24
24
#include <linux/init.h>
25
25
#include <linux/types.h>
26
26
27
+ #include <asm/io.h>
27
28
#include <asm/xen/hypervisor.h>
28
29
29
30
#include <xen/xen.h>
31
+ #include <xen/interface/xen.h>
32
+ #include <xen/hvm.h>
30
33
#include <xen/page.h>
31
34
#include <xen/events.h>
32
35
#include <xen/interface/io/console.h>
@@ -42,9 +45,13 @@ static int xencons_irq;
42
45
/* ------------------------------------------------------------------ */
43
46
44
47
static unsigned long console_pfn = ~0ul ;
48
+ static unsigned int console_evtchn = ~0ul ;
49
+ static struct xencons_interface * xencons_if = NULL ;
45
50
46
51
static inline struct xencons_interface * xencons_interface (void )
47
52
{
53
+ if (xencons_if != NULL )
54
+ return xencons_if ;
48
55
if (console_pfn == ~0ul )
49
56
return mfn_to_virt (xen_start_info -> console .domU .mfn );
50
57
else
@@ -54,7 +61,10 @@ static inline struct xencons_interface *xencons_interface(void)
54
61
static inline void notify_daemon (void )
55
62
{
56
63
/* Use evtchn: this is called early, before irq is set up. */
57
- notify_remote_via_evtchn (xen_start_info -> console .domU .evtchn );
64
+ if (console_evtchn == ~0ul )
65
+ notify_remote_via_evtchn (xen_start_info -> console .domU .evtchn );
66
+ else
67
+ notify_remote_via_evtchn (console_evtchn );
58
68
}
59
69
60
70
static int __write_console (const char * data , int len )
@@ -157,44 +167,77 @@ static struct hv_ops dom0_hvc_ops = {
157
167
.notifier_hangup = notifier_hangup_irq ,
158
168
};
159
169
170
+ static int xen_hvm_console_init (void )
171
+ {
172
+ int r ;
173
+ uint64_t v = 0 ;
174
+ unsigned long mfn ;
175
+
176
+ if (!xen_hvm_domain ())
177
+ return - ENODEV ;
178
+
179
+ if (xencons_if != NULL )
180
+ return - EBUSY ;
181
+
182
+ r = hvm_get_parameter (HVM_PARAM_CONSOLE_EVTCHN , & v );
183
+ if (r < 0 )
184
+ return - ENODEV ;
185
+ console_evtchn = v ;
186
+ hvm_get_parameter (HVM_PARAM_CONSOLE_PFN , & v );
187
+ if (r < 0 )
188
+ return - ENODEV ;
189
+ mfn = v ;
190
+ xencons_if = ioremap (mfn << PAGE_SHIFT , PAGE_SIZE );
191
+ if (xencons_if == NULL )
192
+ return - ENODEV ;
193
+
194
+ return 0 ;
195
+ }
196
+
160
197
static int __init xen_hvc_init (void )
161
198
{
162
199
struct hvc_struct * hp ;
163
200
struct hv_ops * ops ;
201
+ int r ;
164
202
165
- if (!xen_pv_domain ())
203
+ if (!xen_domain ())
166
204
return - ENODEV ;
167
205
168
206
if (xen_initial_domain ()) {
169
207
ops = & dom0_hvc_ops ;
170
208
xencons_irq = bind_virq_to_irq (VIRQ_CONSOLE , 0 );
171
209
} else {
172
- if (!xen_start_info -> console .domU .evtchn )
173
- return - ENODEV ;
174
-
175
210
ops = & domU_hvc_ops ;
176
- xencons_irq = bind_evtchn_to_irq (xen_start_info -> console .domU .evtchn );
211
+ if (xen_pv_domain ()) {
212
+ if (!xen_start_info -> console .domU .evtchn )
213
+ return - ENODEV ;
214
+ console_pfn = mfn_to_pfn (xen_start_info -> console .domU .mfn );
215
+ console_evtchn = xen_start_info -> console .domU .evtchn ;
216
+ } else {
217
+ r = xen_hvm_console_init ();
218
+ if (r < 0 )
219
+ return r ;
220
+ }
221
+ xencons_irq = bind_evtchn_to_irq (console_evtchn );
222
+ if (xencons_irq < 0 )
223
+ xencons_irq = 0 ; /* NO_IRQ */
224
+ else
225
+ irq_set_noprobe (xencons_irq );
177
226
}
178
- if (xencons_irq < 0 )
179
- xencons_irq = 0 ; /* NO_IRQ */
180
- else
181
- irq_set_noprobe (xencons_irq );
182
227
183
228
hp = hvc_alloc (HVC_COOKIE , xencons_irq , ops , 256 );
184
229
if (IS_ERR (hp ))
185
230
return PTR_ERR (hp );
186
231
187
232
hvc = hp ;
188
233
189
- console_pfn = mfn_to_pfn (xen_start_info -> console .domU .mfn );
190
-
191
234
return 0 ;
192
235
}
193
236
194
237
void xen_console_resume (void )
195
238
{
196
239
if (xencons_irq )
197
- rebind_evtchn_irq (xen_start_info -> console . domU . evtchn , xencons_irq );
240
+ rebind_evtchn_irq (console_evtchn , xencons_irq );
198
241
}
199
242
200
243
static void __exit xen_hvc_fini (void )
@@ -205,16 +248,22 @@ static void __exit xen_hvc_fini(void)
205
248
206
249
static int xen_cons_init (void )
207
250
{
208
- struct hv_ops * ops ;
251
+ const struct hv_ops * ops ;
209
252
210
- if (!xen_pv_domain ())
253
+ if (!xen_domain ())
211
254
return 0 ;
212
255
213
256
if (xen_initial_domain ())
214
257
ops = & dom0_hvc_ops ;
215
- else
258
+ else {
216
259
ops = & domU_hvc_ops ;
217
260
261
+ if (xen_pv_domain ())
262
+ console_evtchn = xen_start_info -> console .domU .evtchn ;
263
+ else
264
+ xen_hvm_console_init ();
265
+ }
266
+
218
267
hvc_instantiate (HVC_COOKIE , 0 , ops );
219
268
return 0 ;
220
269
}
@@ -230,6 +279,9 @@ static void xenboot_write_console(struct console *console, const char *string,
230
279
unsigned int linelen , off = 0 ;
231
280
const char * pos ;
232
281
282
+ if (!xen_pv_domain ())
283
+ return ;
284
+
233
285
dom0_write_console (0 , string , len );
234
286
235
287
if (xen_initial_domain ())
0 commit comments