View | Details | Raw Unified | Return to bug 276421 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/dev/xen/console/xen_console.c (-3 / +16 lines)
Lines 138-143 struct putchar_arg { Link Here
138
	size_t	n_next;
138
	size_t	n_next;
139
};
139
};
140
140
141
void __weak_symbol
142
xen_emergency_print(const char *str, size_t size)
143
{
144
    HYPERVISOR_console_write(str, size);
145
}
146
141
static void
147
static void
142
putchar(int c, void *arg)
148
putchar(int c, void *arg)
143
{
149
{
Lines 150-161 putchar(int c, void *arg) Link Here
150
		 * We have no buffer, output directly to the
156
		 * We have no buffer, output directly to the
151
		 * console char by char.
157
		 * console char by char.
152
		 */
158
		 */
153
		HYPERVISOR_console_write((char *)&c, 1);
159
		xen_emergency_print((char *)&c, 1);
154
	} else {
160
	} else {
155
		pca->buf[pca->n_next++] = c;
161
		pca->buf[pca->n_next++] = c;
156
		if ((pca->size == pca->n_next) || (c = '\0')) {
162
		if ((pca->size == pca->n_next) || (c = '\0')) {
157
			/* Flush the buffer */
163
			/* Flush the buffer */
158
			HYPERVISOR_console_write(pca->buf, pca->n_next);
164
			xen_emergency_print(pca->buf, pca->n_next);
159
			pca->n_next = 0;
165
			pca->n_next = 0;
160
		}
166
		}
161
	}
167
	}
Lines 185-194 xc_printf(const char *fmt, ...) Link Here
185
191
186
#ifdef PRINTF_BUFR_SIZE
192
#ifdef PRINTF_BUFR_SIZE
187
	if (pca.n_next != 0)
193
	if (pca.n_next != 0)
188
		HYPERVISOR_console_write(buf, pca.n_next);
194
		xen_emergency_print(buf, pca.n_next);
189
#endif
195
#endif
190
}
196
}
191
197
198
#ifdef EARLY_PRINTF
199
void xen_early_putc(int ch)
200
{
201
	xen_emergency_print((char *)&ch, 1);
202
}
203
#endif
204
192
/*---------------------- Helpers for the console lock -----------------------*/
205
/*---------------------- Helpers for the console lock -----------------------*/
193
/*
206
/*
194
 * The lock is not used when the kernel is panicing as it will never recover
207
 * The lock is not used when the kernel is panicing as it will never recover
(-)b/sys/x86/include/xen/xen-os.h (-2 / +3 lines)
Lines 52-59 extern int xen_disable_pv_disks; Link Here
52
/* tunable for disabling PV nics */
52
/* tunable for disabling PV nics */
53
extern int xen_disable_pv_nics;
53
extern int xen_disable_pv_nics;
54
54
55
extern uint32_t xen_cpuid_base;
56
57
/* compatibility for accessing xen_ulong_t with atomics */
55
/* compatibility for accessing xen_ulong_t with atomics */
58
#define	atomic_clear_xen_ulong		atomic_clear_long
56
#define	atomic_clear_xen_ulong		atomic_clear_long
59
#define	atomic_set_xen_ulong		atomic_set_long
57
#define	atomic_set_xen_ulong		atomic_set_long
Lines 96-101 xen_pv_nics_disabled(void) Link Here
96
94
97
bool xen_has_iommu_maps(void);
95
bool xen_has_iommu_maps(void);
98
96
97
/* (Very) early initialization. */
98
void xen_early_init(void);
99
99
#endif /* !__ASSEMBLY__ */
100
#endif /* !__ASSEMBLY__ */
100
101
101
#endif /* _MACHINE_X86_XEN_XEN_OS_H_ */
102
#endif /* _MACHINE_X86_XEN_XEN_OS_H_ */
(-)b/sys/x86/x86/identcpu.c (-4 / +29 lines)
Lines 67-72 Link Here
67
#include <x86/isa/icu.h>
67
#include <x86/isa/icu.h>
68
#include <x86/vmware.h>
68
#include <x86/vmware.h>
69
69
70
#include <xen/xen-os.h>
71
70
#ifdef __i386__
72
#ifdef __i386__
71
#define	IDENTBLUE_CYRIX486	0
73
#define	IDENTBLUE_CYRIX486	0
72
#define	IDENTBLUE_IBMCPU	1
74
#define	IDENTBLUE_IBMCPU	1
Lines 1343-1350 SYSINIT(hook_tsc_freq, SI_SUB_CONFIGURE, SI_ORDER_ANY, hook_tsc_freq, NULL); Link Here
1343
static struct {
1345
static struct {
1344
	const char	*vm_cpuid;
1346
	const char	*vm_cpuid;
1345
	int		vm_guest;
1347
	int		vm_guest;
1348
	void		(*init)(void);
1346
} vm_cpuids[] = {
1349
} vm_cpuids[] = {
1347
	{ "XenVMMXenVMM",	VM_GUEST_XEN },		/* XEN */
1350
	{ "XenVMMXenVMM",	VM_GUEST_XEN,
1351
#ifdef XENHVM
1352
	  &xen_early_init,
1353
#endif
1354
	}, 						/* XEN */
1348
	{ "Microsoft Hv",	VM_GUEST_HV },		/* Microsoft Hyper-V */
1355
	{ "Microsoft Hv",	VM_GUEST_HV },		/* Microsoft Hyper-V */
1349
	{ "VMwareVMware",	VM_GUEST_VMWARE },	/* VMware VM */
1356
	{ "VMwareVMware",	VM_GUEST_VMWARE },	/* VMware VM */
1350
	{ "KVMKVMKVM",		VM_GUEST_KVM },		/* KVM */
1357
	{ "KVMKVMKVM",		VM_GUEST_KVM },		/* KVM */
Lines 1355-1360 static struct { Link Here
1355
static void
1362
static void
1356
identify_hypervisor_cpuid_base(void)
1363
identify_hypervisor_cpuid_base(void)
1357
{
1364
{
1365
	void (*init_fn)(void);
1358
	u_int leaf, regs[4];
1366
	u_int leaf, regs[4];
1359
	int i;
1367
	int i;
1360
1368
Lines 1385-1394 identify_hypervisor_cpuid_base(void) Link Here
1385
			regs[0] = leaf + 1;
1393
			regs[0] = leaf + 1;
1386
1394
1387
		if (regs[0] >= leaf) {
1395
		if (regs[0] >= leaf) {
1396
			enum VM_GUEST prev_vm_guest = vm_guest;
1397
1388
			for (i = 0; i < nitems(vm_cpuids); i++)
1398
			for (i = 0; i < nitems(vm_cpuids); i++)
1389
				if (strncmp((const char *)&regs[1],
1399
				if (strncmp((const char *)&regs[1],
1390
				    vm_cpuids[i].vm_cpuid, 12) == 0) {
1400
				    vm_cpuids[i].vm_cpuid, 12) == 0) {
1391
					vm_guest = vm_cpuids[i].vm_guest;
1401
					vm_guest = vm_cpuids[i].vm_guest;
1402
					init_fn = vm_cpuids[i].init;
1392
					break;
1403
					break;
1393
				}
1404
				}
1394
1405
Lines 1397-1403 identify_hypervisor_cpuid_base(void) Link Here
1397
			 * specific hypervisor, record the base, high value,
1408
			 * specific hypervisor, record the base, high value,
1398
			 * and vendor identifier.
1409
			 * and vendor identifier.
1399
			 */
1410
			 */
1400
			if (vm_guest != VM_GUEST_VM || leaf == 0x40000000) {
1411
			if (vm_guest != prev_vm_guest || leaf == 0x40000000) {
1401
				hv_base = leaf;
1412
				hv_base = leaf;
1402
				hv_high = regs[0];
1413
				hv_high = regs[0];
1403
				((u_int *)&hv_vendor)[0] = regs[1];
1414
				((u_int *)&hv_vendor)[0] = regs[1];
Lines 1409-1419 identify_hypervisor_cpuid_base(void) Link Here
1409
				 * If we found a specific hypervisor, then
1420
				 * If we found a specific hypervisor, then
1410
				 * we are finished.
1421
				 * we are finished.
1411
				 */
1422
				 */
1412
				if (vm_guest != VM_GUEST_VM)
1423
				if (vm_guest != VM_GUEST_VM &&
1413
					return;
1424
				    /*
1425
				     * Xen and other hypervisors can expose the
1426
				     * HyperV signature in addition to the
1427
				     * native one in order to support Viridian
1428
				     * extensions for Windows guests.
1429
				     *
1430
				     * Do the full cpuid scan if HyperV is
1431
				     * detected, as the native hypervisor is
1432
				     * preferred.
1433
				     */
1434
				    vm_guest != VM_GUEST_HV)
1435
					break;
1414
			}
1436
			}
1415
		}
1437
		}
1416
	}
1438
	}
1439
1440
	if (init_fn != NULL)
1441
		init_fn();
1417
}
1442
}
1418
1443
1419
void
1444
void
(-)b/sys/x86/xen/hvm.c (-60 / +86 lines)
Lines 41-48 Link Here
41
41
42
#include <dev/pci/pcivar.h>
42
#include <dev/pci/pcivar.h>
43
43
44
#include <machine/_inttypes.h>
44
#include <machine/cpufunc.h>
45
#include <machine/cpufunc.h>
45
#include <machine/cpu.h>
46
#include <machine/cpu.h>
47
#include <machine/md_var.h>
46
#include <machine/smp.h>
48
#include <machine/smp.h>
47
49
48
#include <x86/apicreg.h>
50
#include <x86/apicreg.h>
Lines 95-100 TUNABLE_INT("hw.xen.disable_pv_nics", &xen_disable_pv_nics); Link Here
95
97
96
/*---------------------- XEN Hypervisor Probe and Setup ----------------------*/
98
/*---------------------- XEN Hypervisor Probe and Setup ----------------------*/
97
99
100
void xen_emergency_print(const char *str, size_t size)
101
{
102
    size_t i;
103
104
    for (i = 0; i < size; i++)
105
	outb(XEN_HVM_DEBUGCONS_IOPORT, str[i]);
106
}
107
98
uint32_t xen_cpuid_base;
108
uint32_t xen_cpuid_base;
99
109
100
static uint32_t
110
static uint32_t
Lines 138-144 hypervisor_version(void) Link Here
138
	uint32_t regs[4];
148
	uint32_t regs[4];
139
	int major, minor;
149
	int major, minor;
140
150
141
	do_cpuid(xen_cpuid_base + 1, regs);
151
	do_cpuid(hv_base + 1, regs);
142
152
143
	major = regs[0] >> 16;
153
	major = regs[0] >> 16;
144
	minor = regs[0] & 0xffff;
154
	minor = regs[0] & 0xffff;
Lines 148-209 hypervisor_version(void) Link Here
148
}
158
}
149
159
150
/*
160
/*
151
 * Allocate and fill in the hypcall page.
161
 * Translate linear to physical address when still running on the bootloader
162
 * created page-tables.
152
 */
163
 */
153
int
164
static vm_paddr_t __nosanitizeaddress __nosanitizememory
154
xen_hvm_init_hypercall_stubs(enum xen_hvm_init_type init_type)
165
early_init_vtop(void *addr)
155
{
166
{
156
	uint32_t regs[4];
167
	return ((uintptr_t)addr - KERNBASE
157
168
#ifdef __amd64__
158
	if (xen_cpuid_base != 0)
169
	    + kernphys - KERNLOAD
159
		/* Already setup. */
170
#endif
160
		goto out;
171
	    );
161
172
}
162
	xen_cpuid_base = xen_hvm_cpuid_base();
163
	if (xen_cpuid_base == 0)
164
		return (ENXIO);
165
173
174
static int
175
map_shared_info(void)
176
{
166
	/*
177
	/*
167
	 * Find the hypercall pages.
178
	 * TODO shared info page should be mapped in an unpopulated (IOW:
179
	 * non-RAM) address.  But finding one at this point in boot is
180
	 * complicated, hence re-use a RAM address for the time being.  This
181
	 * sadly causes super-page shattering in the second stage translation
182
	 * page tables.
168
	 */
183
	 */
169
	do_cpuid(xen_cpuid_base + 2, regs);
184
	static shared_info_t shared_page __attribute__((aligned(PAGE_SIZE)));
170
	if (regs[0] != 1)
185
	static struct xen_add_to_physmap xatp = {
171
		return (EINVAL);
186
	    .domid = DOMID_SELF,
187
	    .idx = 0,
188
	    .space = XENMAPSPACE_shared_info,
189
	};
190
	int rc;
172
191
173
	wrmsr(regs[1], (init_type == XEN_HVM_INIT_EARLY)
192
	if (xatp.gpfn == 0)
174
	    ? (vm_paddr_t)((uintptr_t)&hypercall_page - KERNBASE)
193
	    xatp.gpfn = atop(early_init_vtop(&shared_page));
175
	    : vtophys(&hypercall_page));
176
194
177
out:
195
	rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
178
	hypervisor_version();
196
	if (rc != 0) {
179
	return (0);
197
		printf("cannot map shared info page: %d\n", rc);
198
		HYPERVISOR_shared_info = NULL;
199
	} else if (HYPERVISOR_shared_info == NULL)
200
		HYPERVISOR_shared_info = &shared_page;
201
202
	return (rc);
180
}
203
}
181
204
182
static void
205
/*
183
xen_hvm_init_shared_info_page(void)
206
 * Populate the hypecall and shared pages.
207
 */
208
void
209
xen_early_init(void)
184
{
210
{
185
	struct xen_add_to_physmap xatp;
211
	uint32_t regs[4];
212
	int rc;
186
213
187
	if (xen_pv_domain()) {
214
#ifdef EARLY_PRINTF
188
		/*
215
	early_putc = &xen_early_putc;
189
		 * Already setup in the PV case, shared_info is passed inside
216
#endif
190
		 * of the start_info struct at start of day.
217
191
		 */
218
	if (hv_high < 2) {
219
		xc_printf("Invalid maximum leaves for hv_base\n");
220
		vm_guest = VM_GUEST_VM;
192
		return;
221
		return;
193
	}
222
	}
194
223
195
	if (HYPERVISOR_shared_info == NULL) {
224
	/*
196
		HYPERVISOR_shared_info = malloc(PAGE_SIZE, M_XENHVM, M_NOWAIT);
225
	 * Find the hypercall pages.
197
		if (HYPERVISOR_shared_info == NULL)
226
	 */
198
			panic("Unable to allocate Xen shared info page");
227
	do_cpuid(hv_base + 2, regs);
228
	if (regs[0] != 1) {
229
		xc_printf("Invalid number of hypercall pages %" PRIu32 "\n",
230
		    regs[0]);
231
		vm_guest = VM_GUEST_VM;
232
		return;
199
	}
233
	}
200
234
201
	xatp.domid = DOMID_SELF;
235
	wrmsr(regs[1], early_init_vtop(&hypercall_page));
202
	xatp.idx = 0;
236
203
	xatp.space = XENMAPSPACE_shared_info;
237
	rc = map_shared_info();
204
	xatp.gpfn = vtophys(HYPERVISOR_shared_info) >> PAGE_SHIFT;
238
	if (rc != 0) {
205
	if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
239
		xc_printf("cannot map shared info page: %d\n", rc);
206
		panic("HYPERVISOR_memory_op failed");
240
		vm_guest = VM_GUEST_VM;
241
		return;
242
	}
207
}
243
}
208
244
209
static int
245
static int
Lines 322-353 xen_hvm_disable_emulated_devices(void) Link Here
322
static void
358
static void
323
xen_hvm_init(enum xen_hvm_init_type init_type)
359
xen_hvm_init(enum xen_hvm_init_type init_type)
324
{
360
{
325
	int error;
326
	int i;
361
	int i;
327
362
328
	if (!xen_domain() ||
363
	if (!xen_domain() ||
329
	    init_type == XEN_HVM_INIT_CANCELLED_SUSPEND)
364
	    init_type == XEN_HVM_INIT_CANCELLED_SUSPEND)
330
		return;
365
		return;
331
366
332
	error = xen_hvm_init_hypercall_stubs(init_type);
367
	hypervisor_version();
333
368
334
	switch (init_type) {
369
	switch (init_type) {
335
	case XEN_HVM_INIT_LATE:
370
	case XEN_HVM_INIT_LATE:
336
		if (error != 0)
337
			return;
338
339
		setup_xen_features();
371
		setup_xen_features();
340
#ifdef SMP
372
#ifdef SMP
341
		cpu_ops = xen_hvm_cpu_ops;
373
		cpu_ops = xen_hvm_cpu_ops;
342
#endif
374
#endif
343
		break;
375
		break;
344
	case XEN_HVM_INIT_RESUME:
376
	case XEN_HVM_INIT_RESUME:
345
		if (error != 0)
346
			panic("Unable to init Xen hypercall stubs on resume");
347
348
		/* Clear stale vcpu_info. */
377
		/* Clear stale vcpu_info. */
349
		CPU_FOREACH(i)
378
		CPU_FOREACH(i)
350
			DPCPU_ID_SET(i, vcpu_info, NULL);
379
			DPCPU_ID_SET(i, vcpu_info, NULL);
380
381
		if (map_shared_info() != 0)
382
			panic("cannot map shared info page\n");
383
351
		break;
384
		break;
352
	default:
385
	default:
353
		panic("Unsupported HVM initialization type");
386
		panic("Unsupported HVM initialization type");
Lines 357-369 xen_hvm_init(enum xen_hvm_init_type init_type) Link Here
357
	xen_evtchn_needs_ack = false;
390
	xen_evtchn_needs_ack = false;
358
	xen_hvm_set_callback(NULL);
391
	xen_hvm_set_callback(NULL);
359
392
360
	/*
361
	 * On (PV)HVM domains we need to request the hypervisor to
362
	 * fill the shared info page, for PVH guest the shared_info page
363
	 * is passed inside the start_info struct and is already set, so this
364
	 * functions are no-ops.
365
	 */
366
	xen_hvm_init_shared_info_page();
367
	xen_hvm_disable_emulated_devices();
393
	xen_hvm_disable_emulated_devices();
368
} 
394
} 
369
395
Lines 412-419 xen_hvm_cpu_init(void) Link Here
412
	 * Set vCPU ID. If available fetch the ID from CPUID, if not just use
438
	 * Set vCPU ID. If available fetch the ID from CPUID, if not just use
413
	 * the ACPI ID.
439
	 * the ACPI ID.
414
	 */
440
	 */
415
	KASSERT(xen_cpuid_base != 0, ("Invalid base Xen CPUID leaf"));
441
	KASSERT(hv_base != 0, ("Invalid base Xen CPUID leaf"));
416
	cpuid_count(xen_cpuid_base + 4, 0, regs);
442
	cpuid_count(hv_base + 4, 0, regs);
417
	KASSERT((regs[0] & XEN_HVM_CPUID_VCPU_ID_PRESENT) ||
443
	KASSERT((regs[0] & XEN_HVM_CPUID_VCPU_ID_PRESENT) ||
418
	    !xen_pv_domain(),
444
	    !xen_pv_domain(),
419
	    ("Xen PV domain without vcpu_id in cpuid"));
445
	    ("Xen PV domain without vcpu_id in cpuid"));
Lines 443-450 xen_has_iommu_maps(void) Link Here
443
{
469
{
444
	uint32_t regs[4];
470
	uint32_t regs[4];
445
471
446
	KASSERT(xen_cpuid_base != 0, ("Invalid base Xen CPUID leaf"));
472
	KASSERT(hv_base != 0, ("Invalid base Xen CPUID leaf"));
447
	cpuid_count(xen_cpuid_base + 4, 0, regs);
473
	cpuid_count(hv_base + 4, 0, regs);
448
474
449
	return (regs[0] & XEN_HVM_CPUID_IOMMU_MAPPINGS);
475
	return (regs[0] & XEN_HVM_CPUID_IOMMU_MAPPINGS);
450
}
476
}
(-)b/sys/x86/xen/pv.c (-25 lines)
Lines 159-178 uint64_t Link Here
159
hammer_time_xen(vm_paddr_t start_info_paddr)
159
hammer_time_xen(vm_paddr_t start_info_paddr)
160
{
160
{
161
	struct hvm_modlist_entry *mod;
161
	struct hvm_modlist_entry *mod;
162
	struct xen_add_to_physmap xatp;
163
	uint64_t physfree;
162
	uint64_t physfree;
164
	char *kenv;
163
	char *kenv;
165
	int rc;
166
167
	if (isxen()) {
168
		vm_guest = VM_GUEST_XEN;
169
		rc = xen_hvm_init_hypercall_stubs(XEN_HVM_INIT_EARLY);
170
		if (rc) {
171
			xc_printf("ERROR: failed to initialize hypercall page: %d\n",
172
			    rc);
173
			HYPERVISOR_shutdown(SHUTDOWN_crash);
174
		}
175
	}
176
164
177
	start_info = (struct hvm_start_info *)(start_info_paddr + KERNBASE);
165
	start_info = (struct hvm_start_info *)(start_info_paddr + KERNBASE);
178
	if (start_info->magic != XEN_HVM_START_MAGIC_VALUE) {
166
	if (start_info->magic != XEN_HVM_START_MAGIC_VALUE) {
Lines 211-229 hammer_time_xen(vm_paddr_t start_info_paddr) Link Here
211
			    PAGE_SIZE), physfree);
199
			    PAGE_SIZE), physfree);
212
	}
200
	}
213
201
214
	if (isxen()) {
215
		xatp.domid = DOMID_SELF;
216
		xatp.idx = 0;
217
		xatp.space = XENMAPSPACE_shared_info;
218
		xatp.gpfn = atop(physfree);
219
		if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) {
220
			xc_printf("ERROR: failed to setup shared_info page\n");
221
			HYPERVISOR_shutdown(SHUTDOWN_crash);
222
		}
223
		HYPERVISOR_shared_info = (shared_info_t *)(physfree + KERNBASE);
224
		physfree += PAGE_SIZE;
225
	}
226
227
	/*
202
	/*
228
	 * Init a static kenv using a free page. The contents will be filled
203
	 * Init a static kenv using a free page. The contents will be filled
229
	 * from the parse_preload_data hook.
204
	 * from the parse_preload_data hook.
(-)b/sys/x86/xen/xen_apic.c (-2 / +2 lines)
Lines 343-350 xen_setup_cpus(void) Link Here
343
	 * that's faster than using event channels because it avoids the VM
343
	 * that's faster than using event channels because it avoids the VM
344
	 * exit.
344
	 * exit.
345
	 */
345
	 */
346
	KASSERT(xen_cpuid_base != 0, ("Invalid base Xen CPUID leaf"));
346
	KASSERT(hv_base != 0, ("Invalid base Xen CPUID leaf"));
347
	cpuid_count(xen_cpuid_base + 4, 0, regs);
347
	cpuid_count(hv_base + 4, 0, regs);
348
	if ((x2apic_mode && (regs[0] & XEN_HVM_CPUID_X2APIC_VIRT)) ||
348
	if ((x2apic_mode && (regs[0] & XEN_HVM_CPUID_X2APIC_VIRT)) ||
349
	    (!x2apic_mode && (regs[0] & XEN_HVM_CPUID_APIC_ACCESS_VIRT)))
349
	    (!x2apic_mode && (regs[0] & XEN_HVM_CPUID_APIC_ACCESS_VIRT)))
350
		return;
350
		return;
(-)b/sys/xen/hvm.h (-1 lines)
Lines 96-102 enum xen_hvm_init_type { Link Here
96
	XEN_HVM_INIT_RESUME,
96
	XEN_HVM_INIT_RESUME,
97
};
97
};
98
98
99
int xen_hvm_init_hypercall_stubs(enum xen_hvm_init_type);
100
void xen_hvm_set_callback(device_t);
99
void xen_hvm_set_callback(device_t);
101
void xen_hvm_suspend(void);
100
void xen_hvm_suspend(void);
102
void xen_hvm_resume(bool suspend_cancelled);
101
void xen_hvm_resume(bool suspend_cancelled);
(-)b/sys/xen/xen-os.h (+13 lines)
Lines 151-156 int xenmem_free(device_t dev, int res_id, struct resource *res); Link Here
151
/* Debug/emergency function, prints directly to hypervisor console */
151
/* Debug/emergency function, prints directly to hypervisor console */
152
void xc_printf(const char *, ...) __printflike(1, 2);
152
void xc_printf(const char *, ...) __printflike(1, 2);
153
153
154
/*
155
 * Emergency print function, can be defined per-arch, otherwise defaults to
156
 * HYPERVISOR_console_write.  Should not be called directly, use xc_printf
157
 * instead.
158
 */
159
void xen_emergency_print(const char *str, size_t size);
160
161
/*
162
 * Early printk implementation based on xen_emergency_print.  Only defined if
163
 * EARLY_PRINTF is set.
164
 */
165
void xen_early_putc(int ch);
166
154
#ifndef xen_mb
167
#ifndef xen_mb
155
#define xen_mb() mb()
168
#define xen_mb() mb()
156
#endif
169
#endif

Return to bug 276421