Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88459d4c authored by Jeremy Fitzhardinge's avatar Jeremy Fitzhardinge Committed by Ingo Molnar
Browse files

xen64: register callbacks in arch-independent way



Use callback_op hypercall to register callbacks in a 32/64-bit
independent way (64-bit doesn't need a code segment, but that detail
is hidden in XEN_CALLBACK).

Signed-off-by: default avatarJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Cc: Stephen Tweedie <sct@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 952d1d70
Loading
Loading
Loading
Loading
+17 −10
Original line number Diff line number Diff line
@@ -91,19 +91,25 @@ static void __init fiddle_vdso(void)
	*mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
}

void xen_enable_sysenter(void)
static __cpuinit int register_callback(unsigned type, const void *func)
{
	int cpu = smp_processor_id();
	extern void xen_sysenter_target(void);
	/* Mask events on entry, even though they get enabled immediately */
	static struct callback_register sysenter = {
		.type = CALLBACKTYPE_sysenter,
		.address = XEN_CALLBACK(__KERNEL_CS, xen_sysenter_target),
	struct callback_register callback = {
		.type = type,
		.address = XEN_CALLBACK(__KERNEL_CS, func),
		.flags = CALLBACKF_mask_events,
	};

	return HYPERVISOR_callback_op(CALLBACKOP_register, &callback);
}

void __cpuinit xen_enable_sysenter(void)
{
	int cpu = smp_processor_id();
	extern void xen_sysenter_target(void);

	if (!boot_cpu_has(X86_FEATURE_SEP) ||
	    HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) != 0) {
	    register_callback(CALLBACKTYPE_sysenter,
			      xen_sysenter_target) != 0) {
		clear_cpu_cap(&cpu_data(cpu), X86_FEATURE_SEP);
		clear_cpu_cap(&boot_cpu_data, X86_FEATURE_SEP);
	}
@@ -120,8 +126,9 @@ void __init xen_arch_setup(void)
	if (!xen_feature(XENFEAT_auto_translated_physmap))
		HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_pae_extended_cr3);

	HYPERVISOR_set_callbacks(__KERNEL_CS, (unsigned long)xen_hypervisor_callback,
				 __KERNEL_CS, (unsigned long)xen_failsafe_callback);
	if (register_callback(CALLBACKTYPE_event, xen_hypervisor_callback) ||
	    register_callback(CALLBACKTYPE_failsafe, xen_failsafe_callback))
		BUG();

	xen_enable_sysenter();

+12 −0
Original line number Diff line number Diff line
@@ -226,6 +226,7 @@ HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
	return _hypercall2(int, stack_switch, ss, esp);
}

#ifdef CONFIG_X86_32
static inline int
HYPERVISOR_set_callbacks(unsigned long event_selector,
			 unsigned long event_address,
@@ -236,6 +237,17 @@ HYPERVISOR_set_callbacks(unsigned long event_selector,
			   event_selector, event_address,
			   failsafe_selector, failsafe_address);
}
#else  /* CONFIG_X86_64 */
static inline int
HYPERVISOR_set_callbacks(unsigned long event_address,
			unsigned long failsafe_address,
			unsigned long syscall_address)
{
	return _hypercall3(int, set_callbacks,
			   event_address, failsafe_address,
			   syscall_address);
}
#endif  /* CONFIG_X86_{32,64} */

static inline int
HYPERVISOR_callback_op(int cmd, void *arg)