diff options
-rw-r--r-- | arch/x86/ia32/syscall32.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/arch/x86/ia32/syscall32.c b/arch/x86/ia32/syscall32.c index 15013bac181c..d751d96c2ef2 100644 --- a/arch/x86/ia32/syscall32.c +++ b/arch/x86/ia32/syscall32.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /* Copyright 2002,2003 Andi Kleen, SuSE Labs */ | 1 | /* |
2 | 2 | * Copyright 2002,2003 Andi Kleen, SuSE Labs | |
3 | /* vsyscall handling for 32bit processes. Map a stub page into it | 3 | * |
4 | on demand because 32bit cannot reach the kernel's fixmaps */ | 4 | * vsyscall handling for 32bit processes. Map a stub page into it on |
5 | 5 | * demand because 32bit cannot reach the kernel's fixmaps | |
6 | */ | ||
6 | #include <linux/mm.h> | 7 | #include <linux/mm.h> |
7 | #include <linux/string.h> | 8 | #include <linux/string.h> |
8 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
@@ -50,31 +51,33 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) | |||
50 | } | 51 | } |
51 | 52 | ||
52 | static int __init init_syscall32(void) | 53 | static int __init init_syscall32(void) |
53 | { | 54 | { |
54 | char *syscall32_page = (void *)get_zeroed_page(GFP_KERNEL); | 55 | char *syscall32_page = (void *)get_zeroed_page(GFP_KERNEL); |
55 | if (!syscall32_page) | 56 | |
56 | panic("Cannot allocate syscall32 page"); | 57 | if (!syscall32_page) |
58 | panic("Cannot allocate syscall32 page"); | ||
57 | syscall32_pages[0] = virt_to_page(syscall32_page); | 59 | syscall32_pages[0] = virt_to_page(syscall32_page); |
58 | if (use_sysenter > 0) { | 60 | if (use_sysenter > 0) { |
59 | memcpy(syscall32_page, syscall32_sysenter, | 61 | memcpy(syscall32_page, syscall32_sysenter, |
60 | syscall32_sysenter_end - syscall32_sysenter); | 62 | syscall32_sysenter_end - syscall32_sysenter); |
61 | } else { | 63 | } else { |
62 | memcpy(syscall32_page, syscall32_syscall, | 64 | memcpy(syscall32_page, syscall32_syscall, |
63 | syscall32_syscall_end - syscall32_syscall); | 65 | syscall32_syscall_end - syscall32_syscall); |
64 | } | 66 | } |
65 | return 0; | 67 | return 0; |
66 | } | 68 | } |
67 | 69 | __initcall(init_syscall32); | |
68 | __initcall(init_syscall32); | ||
69 | 70 | ||
70 | /* May not be __init: called during resume */ | 71 | /* May not be __init: called during resume */ |
71 | void syscall32_cpu_init(void) | 72 | void syscall32_cpu_init(void) |
72 | { | 73 | { |
73 | if (use_sysenter < 0) | 74 | if (use_sysenter < 0) |
74 | use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL); | 75 | use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL); |
75 | 76 | ||
76 | /* Load these always in case some future AMD CPU supports | 77 | /* |
77 | SYSENTER from compat mode too. */ | 78 | * Load these always in case some future AMD CPU supports |
79 | * SYSENTER from compat mode too. | ||
80 | */ | ||
78 | checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); | 81 | checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); |
79 | checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL); | 82 | checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL); |
80 | checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target); | 83 | checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target); |