diff options
Diffstat (limited to 'arch/x86_64/ia32')
-rw-r--r-- | arch/x86_64/ia32/Makefile | 4 | ||||
-rw-r--r-- | arch/x86_64/ia32/ia32_aout.c | 6 | ||||
-rw-r--r-- | arch/x86_64/ia32/ia32_signal.c | 15 | ||||
-rw-r--r-- | arch/x86_64/ia32/ia32entry.S | 10 | ||||
-rw-r--r-- | arch/x86_64/ia32/ptrace32.c | 8 | ||||
-rw-r--r-- | arch/x86_64/ia32/sys_ia32.c | 5 | ||||
-rw-r--r-- | arch/x86_64/ia32/syscall32.c | 17 | ||||
-rw-r--r-- | arch/x86_64/ia32/syscall32_syscall.S | 17 |
8 files changed, 51 insertions, 31 deletions
diff --git a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile index a12b19da4b5..f76217d8f57 100644 --- a/arch/x86_64/ia32/Makefile +++ b/arch/x86_64/ia32/Makefile @@ -4,14 +4,14 @@ obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \ ia32_signal.o tls32.o \ - ia32_binfmt.o fpu32.o ptrace32.o syscall32.o + ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o sysv-$(CONFIG_SYSVIPC) := ipc32.o obj-$(CONFIG_IA32_EMULATION) += $(sysv-y) obj-$(CONFIG_IA32_AOUT) += ia32_aout.o -$(obj)/syscall32.o: $(src)/syscall32.c \ +$(obj)/syscall32_syscall.o: \ $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so) # Teach kbuild about targets diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c index c12edf5d97f..3e6780fa018 100644 --- a/arch/x86_64/ia32/ia32_aout.c +++ b/arch/x86_64/ia32/ia32_aout.c @@ -42,7 +42,7 @@ extern int ia32_setup_arg_pages(struct linux_binprm *bprm, static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); static int load_aout_library(struct file*); -#if CORE_DUMP +#ifdef CORE_DUMP static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file); /* @@ -103,7 +103,7 @@ static struct linux_binfmt aout_format = { .module = THIS_MODULE, .load_binary = load_aout_binary, .load_shlib = load_aout_library, -#if CORE_DUMP +#ifdef CORE_DUMP .core_dump = aout_core_dump, #endif .min_coredump = PAGE_SIZE @@ -120,7 +120,7 @@ static void set_brk(unsigned long start, unsigned long end) up_write(¤t->mm->mmap_sem); } -#if CORE_DUMP +#ifdef CORE_DUMP /* * These are the only things you should do on a core-file: use only these * macros to write out all the necessary info. diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c index fbd09b5126c..66e2821533d 100644 --- a/arch/x86_64/ia32/ia32_signal.c +++ b/arch/x86_64/ia32/ia32_signal.c @@ -428,8 +428,8 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) return (void __user *)((rsp - frame_size) & -8UL); } -void ia32_setup_frame(int sig, struct k_sigaction *ka, - compat_sigset_t *set, struct pt_regs * regs) +int ia32_setup_frame(int sig, struct k_sigaction *ka, + compat_sigset_t *set, struct pt_regs * regs) { struct sigframe __user *frame; int err = 0; @@ -514,14 +514,15 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka, current->comm, current->pid, frame, regs->rip, frame->pretcode); #endif - return; + return 1; give_sigsegv: force_sigsegv(sig, current); + return 0; } -void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - compat_sigset_t *set, struct pt_regs * regs) +int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, + compat_sigset_t *set, struct pt_regs * regs) { struct rt_sigframe __user *frame; int err = 0; @@ -613,9 +614,9 @@ void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, current->comm, current->pid, frame, regs->rip, frame->pretcode); #endif - return; + return 1; give_sigsegv: force_sigsegv(sig, current); + return 0; } - diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index f3ca0db85b5..c45d6a05b98 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S @@ -589,13 +589,17 @@ ia32_sys_call_table: .quad compat_sys_mq_timedreceive /* 280 */ .quad compat_sys_mq_notify .quad compat_sys_mq_getsetattr - .quad quiet_ni_syscall /* reserved for kexec */ + .quad compat_sys_kexec_load /* reserved for kexec */ .quad compat_sys_waitid - .quad quiet_ni_syscall /* sys_altroot */ + .quad quiet_ni_syscall /* 285: sys_altroot */ .quad sys_add_key .quad sys_request_key .quad sys_keyctl - /* don't forget to change IA32_NR_syscalls */ + .quad sys_ioprio_set + .quad sys_ioprio_get /* 290 */ + .quad sys_inotify_init + .quad sys_inotify_add_watch + .quad sys_inotify_rm_watch ia32_syscall_end: .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 .quad ni_syscall diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c index b98b6d2462f..2a925e2af39 100644 --- a/arch/x86_64/ia32/ptrace32.c +++ b/arch/x86_64/ia32/ptrace32.c @@ -43,11 +43,11 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 val) switch (regno) { case offsetof(struct user32, regs.fs): if (val && (val & 3) != 3) return -EIO; - child->thread.fs = val & 0xffff; + child->thread.fsindex = val & 0xffff; break; case offsetof(struct user32, regs.gs): if (val && (val & 3) != 3) return -EIO; - child->thread.gs = val & 0xffff; + child->thread.gsindex = val & 0xffff; break; case offsetof(struct user32, regs.ds): if (val && (val & 3) != 3) return -EIO; @@ -138,10 +138,10 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val) switch (regno) { case offsetof(struct user32, regs.fs): - *val = child->thread.fs; + *val = child->thread.fsindex; break; case offsetof(struct user32, regs.gs): - *val = child->thread.gs; + *val = child->thread.gsindex; break; case offsetof(struct user32, regs.ds): *val = child->thread.ds; diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c index 68a9ab06ee7..be996d1b691 100644 --- a/arch/x86_64/ia32/sys_ia32.c +++ b/arch/x86_64/ia32/sys_ia32.c @@ -61,6 +61,7 @@ #include <linux/ptrace.h> #include <linux/highuid.h> #include <linux/vmalloc.h> +#include <linux/fsnotify.h> #include <asm/mman.h> #include <asm/types.h> #include <asm/uaccess.h> @@ -984,8 +985,10 @@ asmlinkage long sys32_open(const char __user * filename, int flags, int mode) if (IS_ERR(f)) { put_unused_fd(fd); fd = error; - } else + } else { + fsnotify_open(f->f_dentry); fd_install(fd, f); + } } putname(tmp); } diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c index 01d8db1a1c0..adbc5f8089e 100644 --- a/arch/x86_64/ia32/syscall32.c +++ b/arch/x86_64/ia32/syscall32.c @@ -14,16 +14,6 @@ #include <asm/tlbflush.h> #include <asm/ia32_unistd.h> -/* 32bit VDSOs mapped into user space. */ -asm(".section \".init.data\",\"aw\"\n" - "syscall32_syscall:\n" - ".incbin \"arch/x86_64/ia32/vsyscall-syscall.so\"\n" - "syscall32_syscall_end:\n" - "syscall32_sysenter:\n" - ".incbin \"arch/x86_64/ia32/vsyscall-sysenter.so\"\n" - "syscall32_sysenter_end:\n" - ".previous"); - extern unsigned char syscall32_syscall[], syscall32_syscall_end[]; extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[]; extern int sysctl_vsyscall32; @@ -57,6 +47,7 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) int npages = (VSYSCALL32_END - VSYSCALL32_BASE) >> PAGE_SHIFT; struct vm_area_struct *vma; struct mm_struct *mm = current->mm; + int ret; vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!vma) @@ -78,7 +69,11 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) vma->vm_mm = mm; down_write(&mm->mmap_sem); - insert_vm_struct(mm, vma); + if ((ret = insert_vm_struct(mm, vma))) { + up_write(&mm->mmap_sem); + kmem_cache_free(vm_area_cachep, vma); + return ret; + } mm->total_vm += npages; up_write(&mm->mmap_sem); return 0; diff --git a/arch/x86_64/ia32/syscall32_syscall.S b/arch/x86_64/ia32/syscall32_syscall.S new file mode 100644 index 00000000000..8f8271bdf13 --- /dev/null +++ b/arch/x86_64/ia32/syscall32_syscall.S @@ -0,0 +1,17 @@ +/* 32bit VDSOs mapped into user space. */ + + .section ".init.data","aw" + + .globl syscall32_syscall + .globl syscall32_syscall_end + +syscall32_syscall: + .incbin "arch/x86_64/ia32/vsyscall-syscall.so" +syscall32_syscall_end: + + .globl syscall32_sysenter + .globl syscall32_sysenter_end + +syscall32_sysenter: + .incbin "arch/x86_64/ia32/vsyscall-sysenter.so" +syscall32_sysenter_end: |