diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/vdso.c | 6 | ||||
-rw-r--r-- | arch/s390/kernel/vdso.c | 6 | ||||
-rw-r--r-- | arch/sh/kernel/vsyscall/vsyscall.c | 6 | ||||
-rw-r--r-- | arch/x86/ia32/ia32_aout.c | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/mmu.h | 6 | ||||
-rw-r--r-- | arch/x86/kernel/process_64.c | 8 | ||||
-rw-r--r-- | arch/x86/mm/init_64.c | 16 | ||||
-rw-r--r-- | arch/x86/vdso/vdso32-setup.c | 15 |
8 files changed, 40 insertions, 24 deletions
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index fd8728729abc..142ab1008c3b 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c | |||
@@ -820,17 +820,17 @@ static int __init vdso_init(void) | |||
820 | } | 820 | } |
821 | arch_initcall(vdso_init); | 821 | arch_initcall(vdso_init); |
822 | 822 | ||
823 | int in_gate_area_no_task(unsigned long addr) | 823 | int in_gate_area_no_mm(unsigned long addr) |
824 | { | 824 | { |
825 | return 0; | 825 | return 0; |
826 | } | 826 | } |
827 | 827 | ||
828 | int in_gate_area(struct task_struct *task, unsigned long addr) | 828 | int in_gate_area(struct mm_struct *mm, unsigned long addr) |
829 | { | 829 | { |
830 | return 0; | 830 | return 0; |
831 | } | 831 | } |
832 | 832 | ||
833 | struct vm_area_struct *get_gate_vma(struct task_struct *tsk) | 833 | struct vm_area_struct *get_gate_vma(struct mm_struct *mm) |
834 | { | 834 | { |
835 | return NULL; | 835 | return NULL; |
836 | } | 836 | } |
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index f438d74dedbd..d73630b4fe1d 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
@@ -337,17 +337,17 @@ static int __init vdso_init(void) | |||
337 | } | 337 | } |
338 | arch_initcall(vdso_init); | 338 | arch_initcall(vdso_init); |
339 | 339 | ||
340 | int in_gate_area_no_task(unsigned long addr) | 340 | int in_gate_area_no_mm(unsigned long addr) |
341 | { | 341 | { |
342 | return 0; | 342 | return 0; |
343 | } | 343 | } |
344 | 344 | ||
345 | int in_gate_area(struct task_struct *task, unsigned long addr) | 345 | int in_gate_area(struct mm_struct *mm, unsigned long addr) |
346 | { | 346 | { |
347 | return 0; | 347 | return 0; |
348 | } | 348 | } |
349 | 349 | ||
350 | struct vm_area_struct *get_gate_vma(struct task_struct *tsk) | 350 | struct vm_area_struct *get_gate_vma(struct mm_struct *mm) |
351 | { | 351 | { |
352 | return NULL; | 352 | return NULL; |
353 | } | 353 | } |
diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c index 242117cbad67..1d6d51a1ce79 100644 --- a/arch/sh/kernel/vsyscall/vsyscall.c +++ b/arch/sh/kernel/vsyscall/vsyscall.c | |||
@@ -94,17 +94,17 @@ const char *arch_vma_name(struct vm_area_struct *vma) | |||
94 | return NULL; | 94 | return NULL; |
95 | } | 95 | } |
96 | 96 | ||
97 | struct vm_area_struct *get_gate_vma(struct task_struct *task) | 97 | struct vm_area_struct *get_gate_vma(struct mm_struct *mm) |
98 | { | 98 | { |
99 | return NULL; | 99 | return NULL; |
100 | } | 100 | } |
101 | 101 | ||
102 | int in_gate_area(struct task_struct *task, unsigned long address) | 102 | int in_gate_area(struct mm_struct *mm, unsigned long address) |
103 | { | 103 | { |
104 | return 0; | 104 | return 0; |
105 | } | 105 | } |
106 | 106 | ||
107 | int in_gate_area_no_task(unsigned long address) | 107 | int in_gate_area_no_mm(unsigned long address) |
108 | { | 108 | { |
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index 2d93bdbc9ac0..fd843877e841 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c | |||
@@ -298,6 +298,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
298 | /* OK, This is the point of no return */ | 298 | /* OK, This is the point of no return */ |
299 | set_personality(PER_LINUX); | 299 | set_personality(PER_LINUX); |
300 | set_thread_flag(TIF_IA32); | 300 | set_thread_flag(TIF_IA32); |
301 | current->mm->context.ia32_compat = 1; | ||
301 | 302 | ||
302 | setup_new_exec(bprm); | 303 | setup_new_exec(bprm); |
303 | 304 | ||
diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h index 80a1dee5bea5..aeff3e89b222 100644 --- a/arch/x86/include/asm/mmu.h +++ b/arch/x86/include/asm/mmu.h | |||
@@ -13,6 +13,12 @@ typedef struct { | |||
13 | int size; | 13 | int size; |
14 | struct mutex lock; | 14 | struct mutex lock; |
15 | void *vdso; | 15 | void *vdso; |
16 | |||
17 | #ifdef CONFIG_X86_64 | ||
18 | /* True if mm supports a task running in 32 bit compatibility mode. */ | ||
19 | unsigned short ia32_compat; | ||
20 | #endif | ||
21 | |||
16 | } mm_context_t; | 22 | } mm_context_t; |
17 | 23 | ||
18 | #ifdef CONFIG_SMP | 24 | #ifdef CONFIG_SMP |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index bd387e8f73b4..6c9dd922ac0d 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -501,6 +501,10 @@ void set_personality_64bit(void) | |||
501 | /* Make sure to be in 64bit mode */ | 501 | /* Make sure to be in 64bit mode */ |
502 | clear_thread_flag(TIF_IA32); | 502 | clear_thread_flag(TIF_IA32); |
503 | 503 | ||
504 | /* Ensure the corresponding mm is not marked. */ | ||
505 | if (current->mm) | ||
506 | current->mm->context.ia32_compat = 0; | ||
507 | |||
504 | /* TBD: overwrites user setup. Should have two bits. | 508 | /* TBD: overwrites user setup. Should have two bits. |
505 | But 64bit processes have always behaved this way, | 509 | But 64bit processes have always behaved this way, |
506 | so it's not too bad. The main problem is just that | 510 | so it's not too bad. The main problem is just that |
@@ -516,6 +520,10 @@ void set_personality_ia32(void) | |||
516 | set_thread_flag(TIF_IA32); | 520 | set_thread_flag(TIF_IA32); |
517 | current->personality |= force_personality32; | 521 | current->personality |= force_personality32; |
518 | 522 | ||
523 | /* Mark the associated mm as containing 32-bit tasks. */ | ||
524 | if (current->mm) | ||
525 | current->mm->context.ia32_compat = 1; | ||
526 | |||
519 | /* Prepare the first "return" to user space */ | 527 | /* Prepare the first "return" to user space */ |
520 | current_thread_info()->status |= TS_COMPAT; | 528 | current_thread_info()->status |= TS_COMPAT; |
521 | } | 529 | } |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 2362b646178e..794233587287 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -862,18 +862,18 @@ static struct vm_area_struct gate_vma = { | |||
862 | .vm_flags = VM_READ | VM_EXEC | 862 | .vm_flags = VM_READ | VM_EXEC |
863 | }; | 863 | }; |
864 | 864 | ||
865 | struct vm_area_struct *get_gate_vma(struct task_struct *tsk) | 865 | struct vm_area_struct *get_gate_vma(struct mm_struct *mm) |
866 | { | 866 | { |
867 | #ifdef CONFIG_IA32_EMULATION | 867 | #ifdef CONFIG_IA32_EMULATION |
868 | if (test_tsk_thread_flag(tsk, TIF_IA32)) | 868 | if (!mm || mm->context.ia32_compat) |
869 | return NULL; | 869 | return NULL; |
870 | #endif | 870 | #endif |
871 | return &gate_vma; | 871 | return &gate_vma; |
872 | } | 872 | } |
873 | 873 | ||
874 | int in_gate_area(struct task_struct *task, unsigned long addr) | 874 | int in_gate_area(struct mm_struct *mm, unsigned long addr) |
875 | { | 875 | { |
876 | struct vm_area_struct *vma = get_gate_vma(task); | 876 | struct vm_area_struct *vma = get_gate_vma(mm); |
877 | 877 | ||
878 | if (!vma) | 878 | if (!vma) |
879 | return 0; | 879 | return 0; |
@@ -882,11 +882,11 @@ int in_gate_area(struct task_struct *task, unsigned long addr) | |||
882 | } | 882 | } |
883 | 883 | ||
884 | /* | 884 | /* |
885 | * Use this when you have no reliable task/vma, typically from interrupt | 885 | * Use this when you have no reliable mm, typically from interrupt |
886 | * context. It is less reliable than using the task's vma and may give | 886 | * context. It is less reliable than using a task's mm and may give |
887 | * false positives: | 887 | * false positives. |
888 | */ | 888 | */ |
889 | int in_gate_area_no_task(unsigned long addr) | 889 | int in_gate_area_no_mm(unsigned long addr) |
890 | { | 890 | { |
891 | return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END); | 891 | return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END); |
892 | } | 892 | } |
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c index 36df991985b2..468d591dde31 100644 --- a/arch/x86/vdso/vdso32-setup.c +++ b/arch/x86/vdso/vdso32-setup.c | |||
@@ -417,24 +417,25 @@ const char *arch_vma_name(struct vm_area_struct *vma) | |||
417 | return NULL; | 417 | return NULL; |
418 | } | 418 | } |
419 | 419 | ||
420 | struct vm_area_struct *get_gate_vma(struct task_struct *tsk) | 420 | struct vm_area_struct *get_gate_vma(struct mm_struct *mm) |
421 | { | 421 | { |
422 | struct mm_struct *mm = tsk->mm; | 422 | /* |
423 | 423 | * Check to see if the corresponding task was created in compat vdso | |
424 | /* Check to see if this task was created in compat vdso mode */ | 424 | * mode. |
425 | */ | ||
425 | if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE) | 426 | if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE) |
426 | return &gate_vma; | 427 | return &gate_vma; |
427 | return NULL; | 428 | return NULL; |
428 | } | 429 | } |
429 | 430 | ||
430 | int in_gate_area(struct task_struct *task, unsigned long addr) | 431 | int in_gate_area(struct mm_struct *mm, unsigned long addr) |
431 | { | 432 | { |
432 | const struct vm_area_struct *vma = get_gate_vma(task); | 433 | const struct vm_area_struct *vma = get_gate_vma(mm); |
433 | 434 | ||
434 | return vma && addr >= vma->vm_start && addr < vma->vm_end; | 435 | return vma && addr >= vma->vm_start && addr < vma->vm_end; |
435 | } | 436 | } |
436 | 437 | ||
437 | int in_gate_area_no_task(unsigned long addr) | 438 | int in_gate_area_no_mm(unsigned long addr) |
438 | { | 439 | { |
439 | return 0; | 440 | return 0; |
440 | } | 441 | } |