diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-07-08 18:07:02 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-16 05:03:01 -0400 |
commit | 88459d4c7eb68c4a15609e00e5d100e2a305f040 (patch) | |
tree | 71514d9bffc9854440e848d4f455713d0a4619da /arch/x86/xen/setup.c | |
parent | 952d1d7055c8cbf95b4ad2f90be5ed37db8a48ee (diff) |
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: Jeremy 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: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/xen/setup.c')
-rw-r--r-- | arch/x86/xen/setup.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index f52f3855fb6b..bea3d4f779db 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -91,19 +91,25 @@ static void __init fiddle_vdso(void) | |||
91 | *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT; | 91 | *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT; |
92 | } | 92 | } |
93 | 93 | ||
94 | void xen_enable_sysenter(void) | 94 | static __cpuinit int register_callback(unsigned type, const void *func) |
95 | { | 95 | { |
96 | int cpu = smp_processor_id(); | 96 | struct callback_register callback = { |
97 | extern void xen_sysenter_target(void); | 97 | .type = type, |
98 | /* Mask events on entry, even though they get enabled immediately */ | 98 | .address = XEN_CALLBACK(__KERNEL_CS, func), |
99 | static struct callback_register sysenter = { | ||
100 | .type = CALLBACKTYPE_sysenter, | ||
101 | .address = XEN_CALLBACK(__KERNEL_CS, xen_sysenter_target), | ||
102 | .flags = CALLBACKF_mask_events, | 99 | .flags = CALLBACKF_mask_events, |
103 | }; | 100 | }; |
104 | 101 | ||
102 | return HYPERVISOR_callback_op(CALLBACKOP_register, &callback); | ||
103 | } | ||
104 | |||
105 | void __cpuinit xen_enable_sysenter(void) | ||
106 | { | ||
107 | int cpu = smp_processor_id(); | ||
108 | extern void xen_sysenter_target(void); | ||
109 | |||
105 | if (!boot_cpu_has(X86_FEATURE_SEP) || | 110 | if (!boot_cpu_has(X86_FEATURE_SEP) || |
106 | HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) != 0) { | 111 | register_callback(CALLBACKTYPE_sysenter, |
112 | xen_sysenter_target) != 0) { | ||
107 | clear_cpu_cap(&cpu_data(cpu), X86_FEATURE_SEP); | 113 | clear_cpu_cap(&cpu_data(cpu), X86_FEATURE_SEP); |
108 | clear_cpu_cap(&boot_cpu_data, X86_FEATURE_SEP); | 114 | clear_cpu_cap(&boot_cpu_data, X86_FEATURE_SEP); |
109 | } | 115 | } |
@@ -120,8 +126,9 @@ void __init xen_arch_setup(void) | |||
120 | if (!xen_feature(XENFEAT_auto_translated_physmap)) | 126 | if (!xen_feature(XENFEAT_auto_translated_physmap)) |
121 | HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_pae_extended_cr3); | 127 | HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_pae_extended_cr3); |
122 | 128 | ||
123 | HYPERVISOR_set_callbacks(__KERNEL_CS, (unsigned long)xen_hypervisor_callback, | 129 | if (register_callback(CALLBACKTYPE_event, xen_hypervisor_callback) || |
124 | __KERNEL_CS, (unsigned long)xen_failsafe_callback); | 130 | register_callback(CALLBACKTYPE_failsafe, xen_failsafe_callback)) |
131 | BUG(); | ||
125 | 132 | ||
126 | xen_enable_sysenter(); | 133 | xen_enable_sysenter(); |
127 | 134 | ||