aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/setup.c
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-07-08 18:07:14 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-16 05:05:52 -0400
commit6fcac6d305e8238939e169f4c52e8ec8a552a31f (patch)
treeb973a215938121d42bc586925d9712f205badea0 /arch/x86/xen/setup.c
parentd6182fbf04164016cb6540db02eef3d6bdc967c3 (diff)
xen64: set up syscall and sysenter entrypoints for 64-bit
We set up entrypoints for syscall and sysenter. sysenter is only used for 32-bit compat processes, whereas syscall can be used in by both 32 and 64-bit processes. 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.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index bea3d4f779db..9d7a14402895 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -86,9 +86,11 @@ static void xen_idle(void)
86 */ 86 */
87static void __init fiddle_vdso(void) 87static void __init fiddle_vdso(void)
88{ 88{
89#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
89 extern const char vdso32_default_start; 90 extern const char vdso32_default_start;
90 u32 *mask = VDSO32_SYMBOL(&vdso32_default_start, NOTE_MASK); 91 u32 *mask = VDSO32_SYMBOL(&vdso32_default_start, NOTE_MASK);
91 *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT; 92 *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
93#endif
92} 94}
93 95
94static __cpuinit int register_callback(unsigned type, const void *func) 96static __cpuinit int register_callback(unsigned type, const void *func)
@@ -106,15 +108,48 @@ void __cpuinit xen_enable_sysenter(void)
106{ 108{
107 int cpu = smp_processor_id(); 109 int cpu = smp_processor_id();
108 extern void xen_sysenter_target(void); 110 extern void xen_sysenter_target(void);
111 int ret;
112
113#ifdef CONFIG_X86_32
114 if (!boot_cpu_has(X86_FEATURE_SEP)) {
115 return;
116 }
117#else
118 if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL &&
119 boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR) {
120 return;
121 }
122#endif
109 123
110 if (!boot_cpu_has(X86_FEATURE_SEP) || 124 ret = register_callback(CALLBACKTYPE_sysenter, xen_sysenter_target);
111 register_callback(CALLBACKTYPE_sysenter, 125 if(ret != 0) {
112 xen_sysenter_target) != 0) {
113 clear_cpu_cap(&cpu_data(cpu), X86_FEATURE_SEP); 126 clear_cpu_cap(&cpu_data(cpu), X86_FEATURE_SEP);
114 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_SEP); 127 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_SEP);
115 } 128 }
116} 129}
117 130
131void __cpuinit xen_enable_syscall(void)
132{
133#ifdef CONFIG_X86_64
134 int cpu = smp_processor_id();
135 int ret;
136 extern void xen_syscall_target(void);
137 extern void xen_syscall32_target(void);
138
139 ret = register_callback(CALLBACKTYPE_syscall, xen_syscall_target);
140 if (ret != 0) {
141 printk("failed to set syscall: %d\n", ret);
142 clear_cpu_cap(&cpu_data(cpu), X86_FEATURE_SYSCALL);
143 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_SYSCALL);
144 } else {
145 ret = register_callback(CALLBACKTYPE_syscall32,
146 xen_syscall32_target);
147 if (ret != 0)
148 printk("failed to set 32-bit syscall: %d\n", ret);
149 }
150#endif /* CONFIG_X86_64 */
151}
152
118void __init xen_arch_setup(void) 153void __init xen_arch_setup(void)
119{ 154{
120 struct physdev_set_iopl set_iopl; 155 struct physdev_set_iopl set_iopl;
@@ -131,6 +166,7 @@ void __init xen_arch_setup(void)
131 BUG(); 166 BUG();
132 167
133 xen_enable_sysenter(); 168 xen_enable_sysenter();
169 xen_enable_syscall();
134 170
135 set_iopl.iopl = 1; 171 set_iopl.iopl = 1;
136 rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl); 172 rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);