Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752112AbbGKGH3 (ORCPT ); Sat, 11 Jul 2015 02:07:29 -0400 Received: from mail-yk0-f175.google.com ([209.85.160.175]:33476 "EHLO mail-yk0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751685AbbGKGH2 (ORCPT ); Sat, 11 Jul 2015 02:07:28 -0400 From: Brian Gerst To: x86@kernel.org, linux-kernel@vger.kernel.org Cc: Ingo Molnar , "H. Peter Anvin" , Denys Vlasenko , Andy Lutomirski , Linus Torvalds Subject: [PATCH 3/5] x86/vm86: Move fields from kernel_vm86_struct Date: Sat, 11 Jul 2015 01:09:18 -0400 Message-Id: <1436591360-16210-4-git-send-email-brgerst@gmail.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1436591360-16210-1-git-send-email-brgerst@gmail.com> References: <1436591360-16210-1-git-send-email-brgerst@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6863 Lines: 190 Move the non-regs fields to the off-stack data. Signed-off-by: Brian Gerst --- arch/x86/include/asm/vm86.h | 17 ++++++++-------- arch/x86/kernel/vm86_32.c | 48 ++++++++++++++++++++++----------------------- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/arch/x86/include/asm/vm86.h b/arch/x86/include/asm/vm86.h index 88f14e3..bc28a40 100644 --- a/arch/x86/include/asm/vm86.h +++ b/arch/x86/include/asm/vm86.h @@ -38,13 +38,7 @@ struct kernel_vm86_struct { * Therefore, pt_regs in fact points to a complete 'kernel_vm86_struct' * in kernelspace, hence we need not reget the data from userspace. */ -#define VM86_TSS_ESP0 flags - unsigned long flags; - unsigned long screen_bitmap; - unsigned long cpu_type; - struct revectored_struct int_revectored; - struct revectored_struct int21_revectored; - struct vm86plus_info_struct vm86plus; +#define VM86_TSS_ESP0 regs32 struct pt_regs *regs32; /* here we save the pointer to the old regs */ /* * The below is not part of the structure, but the stack layout continues @@ -60,12 +54,19 @@ struct kernel_vm86_struct { struct kernel_vm86_info { struct vm86_struct __user *vm86_info; - unsigned long screen_bitmap; unsigned long v86flags; unsigned long v86mask; unsigned long saved_sp0; unsigned int saved_fs; unsigned int saved_gs; + + /* Must match vm86plus_struct after regs */ + unsigned long flags; + unsigned long screen_bitmap; + unsigned long cpu_type; + struct revectored_struct int_revectored; + struct revectored_struct int21_revectored; + struct vm86plus_info_struct vm86plus; }; #ifdef CONFIG_VM86 diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index 8b29c9b..f174602 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -68,7 +68,6 @@ #define KVM86 ((struct kernel_vm86_struct *)regs) -#define VMPI KVM86->vm86plus /* @@ -111,18 +110,16 @@ static int copy_vm86_regs_to_user(struct vm86_regs __user *user, /* convert vm86_regs to kernel_vm86_regs */ static int copy_vm86_regs_from_user(struct kernel_vm86_regs *regs, - const struct vm86_regs __user *user, - unsigned extra) + const struct vm86_regs __user *user) { int ret = 0; /* copy ax-fs inclusive */ ret += copy_from_user(regs, user, offsetof(struct kernel_vm86_regs, pt.orig_ax)); - /* copy orig_ax-__gsh+extra */ + /* copy orig_ax-__gsh */ ret += copy_from_user(®s->pt.orig_ax, &user->orig_eax, sizeof(struct kernel_vm86_regs) - - offsetof(struct kernel_vm86_regs, pt.orig_ax) + - extra); + offsetof(struct kernel_vm86_regs, pt.orig_ax)); return ret; } @@ -261,18 +258,20 @@ static long do_sys_vm86(struct vm86plus_struct __user *v86, bool plus, } if (vm86->saved_sp0) return -EPERM; + if (copy_vm86_regs_from_user(&info->regs, &v86->regs)) + return -EFAULT; if (plus) { - if (copy_vm86_regs_from_user(&info->regs, &v86->regs, - offsetof(struct kernel_vm86_struct, regs32) - - sizeof(info->regs))) + if (copy_from_user(&vm86->flags, &v86->flags, + sizeof(struct vm86plus_struct) - + offsetof(struct vm86plus_struct, flags))) return -EFAULT; - info->vm86plus.is_vm86pus = 1; + vm86->vm86plus.is_vm86pus = 1; } else { - if (copy_vm86_regs_from_user(&info->regs, &v86->regs, - offsetof(struct kernel_vm86_struct, vm86plus) - - sizeof(info->regs))) + if (copy_from_user(&vm86->flags, &v86->flags, + sizeof(struct vm86_struct) - + offsetof(struct vm86_struct, flags))) return -EFAULT; - memset(&info->vm86plus, 0, sizeof(struct vm86plus_info_struct)); + memset(&vm86->vm86plus, 0, sizeof(struct vm86plus_info_struct)); } info->regs32 = current_pt_regs(); vm86->vm86_info = (struct vm86_struct __user *) v86; @@ -297,7 +296,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *v86, bool plus, info->regs.pt.flags |= info->regs32->flags & ~SAFE_MASK; info->regs.pt.flags |= X86_VM_MASK; - switch (info->cpu_type) { + switch (vm86->cpu_type) { case CPU_286: vm86->v86mask = 0; break; @@ -327,8 +326,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *v86, bool plus, load_sp0(tss, &tsk->thread); put_cpu(); - vm86->screen_bitmap = info->screen_bitmap; - if (info->flags & VM86_SCREEN_BITMAP) + if (vm86->flags & VM86_SCREEN_BITMAP) mark_screen_rdonly(tsk->mm); /*call __audit_syscall_exit since we do not exit via the normal paths */ @@ -520,12 +518,13 @@ static void do_int(struct kernel_vm86_regs *regs, int i, { unsigned long __user *intr_ptr; unsigned long segoffs; + struct kernel_vm86_info *vm86 = current->thread.vm86; if (regs->pt.cs == BIOSSEG) goto cannot_handle; - if (is_revectored(i, &KVM86->int_revectored)) + if (is_revectored(i, &vm86->int_revectored)) goto cannot_handle; - if (i == 0x21 && is_revectored(AH(regs), &KVM86->int21_revectored)) + if (i == 0x21 && is_revectored(AH(regs), &vm86->int21_revectored)) goto cannot_handle; intr_ptr = (unsigned long __user *) (i << 2); if (get_user(segoffs, intr_ptr)) @@ -549,7 +548,7 @@ cannot_handle: int handle_vm86_trap(struct kernel_vm86_regs *regs, long error_code, int trapno) { - if (VMPI.is_vm86pus) { + if (current->thread.vm86->vm86plus.is_vm86pus) { if ((trapno == 3) || (trapno == 1)) { KVM86->regs32->ax = VM86_TRAP + (trapno << 8); /* setting this flag forces the code in entry_32.S to @@ -576,12 +575,13 @@ void handle_vm86_fault(struct kernel_vm86_regs *regs, long error_code) unsigned char __user *ssp; unsigned short ip, sp, orig_flags; int data32, pref_done; + struct vm86plus_info_struct *vmpi = ¤t->thread.vm86->vm86plus; #define CHECK_IF_IN_TRAP \ - if (VMPI.vm86dbg_active && VMPI.vm86dbg_TFpendig) \ + if (vmpi->vm86dbg_active && vmpi->vm86dbg_TFpendig) \ newflags |= X86_EFLAGS_TF #define VM86_FAULT_RETURN do { \ - if (VMPI.force_return_for_pic && (VEFLAGS & (X86_EFLAGS_IF | X86_EFLAGS_VIF))) \ + if (vmpi->force_return_for_pic && (VEFLAGS & (X86_EFLAGS_IF | X86_EFLAGS_VIF))) \ return_to_32bit(regs, VM86_PICRETURN); \ if (orig_flags & X86_EFLAGS_TF) \ handle_vm86_trap(regs, 0, 1); \ @@ -651,8 +651,8 @@ void handle_vm86_fault(struct kernel_vm86_regs *regs, long error_code) case 0xcd: { int intno = popb(csp, ip, simulate_sigsegv); IP(regs) = ip; - if (VMPI.vm86dbg_active) { - if ((1 << (intno & 7)) & VMPI.vm86dbg_intxxtab[intno >> 3]) + if (vmpi->vm86dbg_active) { + if ((1 << (intno & 7)) & vmpi->vm86dbg_intxxtab[intno >> 3]) return_to_32bit(regs, VM86_INTx + (intno << 8)); } do_int(regs, intno, ssp, sp); -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/