diff mbox series

x86/vm86/32: Remove VM86_SCREEN_BITMAP support

Message ID 3d34069ab2d249d866ea1d18a47e4170dbfb5982.1610132102.git.luto@kernel.org (mailing list archive)
State New, archived
Headers show
Series x86/vm86/32: Remove VM86_SCREEN_BITMAP support | expand

Commit Message

Andy Lutomirski Jan. 8, 2021, 6:55 p.m. UTC
The implementation was rather buggy.  It unconditionally marked PTEs
read-only, even for VM_SHARED mappings.  I'm not sure whether this is
actually a problem, but it certainly seems unwise.  More importantly, it
released the mmap lock before flushing the TLB, which could allow a racing
CoW operation to falsely believe that the underlying memory was not
writable.

I can't find any users at all of this mechanism, so just remove it.

Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Linux-MM <linux-mm@kvack.org>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: x86@kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Jann Horn <jannh@google.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Yu Zhao <yuzhao@google.com>
Cc: Peter Xu <peterx@redhat.com>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
 arch/x86/include/uapi/asm/vm86.h |  2 +-
 arch/x86/kernel/vm86_32.c        | 55 ++++++--------------------------
 2 files changed, 10 insertions(+), 47 deletions(-)

Comments

Linus Torvalds Jan. 8, 2021, 7:21 p.m. UTC | #1
On Fri, Jan 8, 2021 at 10:55 AM Andy Lutomirski <luto@kernel.org> wrote:
>
> I can't find any users at all of this mechanism, so just remove it.

Ack, as long as it sits in linux-next for a while.

            Linus
Brian Gerst Jan. 8, 2021, 7:27 p.m. UTC | #2
On Fri, Jan 8, 2021 at 1:59 PM Andy Lutomirski <luto@kernel.org> wrote:
>
> The implementation was rather buggy.  It unconditionally marked PTEs
> read-only, even for VM_SHARED mappings.  I'm not sure whether this is
> actually a problem, but it certainly seems unwise.  More importantly, it
> released the mmap lock before flushing the TLB, which could allow a racing
> CoW operation to falsely believe that the underlying memory was not
> writable.
>
> I can't find any users at all of this mechanism, so just remove it.
>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: Linux-MM <linux-mm@kvack.org>
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Cc: x86@kernel.org
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Matthew Wilcox <willy@infradead.org>
> Cc: Jann Horn <jannh@google.com>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Yu Zhao <yuzhao@google.com>
> Cc: Peter Xu <peterx@redhat.com>
> Signed-off-by: Andy Lutomirski <luto@kernel.org>
> ---
>  arch/x86/include/uapi/asm/vm86.h |  2 +-
>  arch/x86/kernel/vm86_32.c        | 55 ++++++--------------------------
>  2 files changed, 10 insertions(+), 47 deletions(-)
>
> diff --git a/arch/x86/include/uapi/asm/vm86.h b/arch/x86/include/uapi/asm/vm86.h
> index d2ee4e307ef8..50004fb4590d 100644
> --- a/arch/x86/include/uapi/asm/vm86.h
> +++ b/arch/x86/include/uapi/asm/vm86.h
> @@ -106,7 +106,7 @@ struct vm86_struct {
>  /*
>   * flags masks
>   */
> -#define VM86_SCREEN_BITMAP     0x0001
> +#define VM86_SCREEN_BITMAP     0x0001        /* no longer supported */
>
>  struct vm86plus_info_struct {
>         unsigned long force_return_for_pic:1;
> diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
> index 764573de3996..28b9e8d511e1 100644
> --- a/arch/x86/kernel/vm86_32.c
> +++ b/arch/x86/kernel/vm86_32.c
> @@ -160,49 +160,6 @@ void save_v86_state(struct kernel_vm86_regs *regs, int retval)
>         do_exit(SIGSEGV);
>  }
>
> -static void mark_screen_rdonly(struct mm_struct *mm)
> -{
> -       struct vm_area_struct *vma;
> -       spinlock_t *ptl;
> -       pgd_t *pgd;
> -       p4d_t *p4d;
> -       pud_t *pud;
> -       pmd_t *pmd;
> -       pte_t *pte;
> -       int i;
> -
> -       mmap_write_lock(mm);
> -       pgd = pgd_offset(mm, 0xA0000);
> -       if (pgd_none_or_clear_bad(pgd))
> -               goto out;
> -       p4d = p4d_offset(pgd, 0xA0000);
> -       if (p4d_none_or_clear_bad(p4d))
> -               goto out;
> -       pud = pud_offset(p4d, 0xA0000);
> -       if (pud_none_or_clear_bad(pud))
> -               goto out;
> -       pmd = pmd_offset(pud, 0xA0000);
> -
> -       if (pmd_trans_huge(*pmd)) {
> -               vma = find_vma(mm, 0xA0000);
> -               split_huge_pmd(vma, pmd, 0xA0000);
> -       }
> -       if (pmd_none_or_clear_bad(pmd))
> -               goto out;
> -       pte = pte_offset_map_lock(mm, pmd, 0xA0000, &ptl);
> -       for (i = 0; i < 32; i++) {
> -               if (pte_present(*pte))
> -                       set_pte(pte, pte_wrprotect(*pte));
> -               pte++;
> -       }
> -       pte_unmap_unlock(pte, ptl);
> -out:
> -       mmap_write_unlock(mm);
> -       flush_tlb_mm_range(mm, 0xA0000, 0xA0000 + 32*PAGE_SIZE, PAGE_SHIFT, false);
> -}
> -
> -
> -
>  static int do_vm86_irq_handling(int subfunction, int irqnumber);
>  static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus);
>
> @@ -282,6 +239,15 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
>                         offsetof(struct vm86_struct, int_revectored)))
>                 return -EFAULT;
>
> +
> +       /* VM86_SCREEN_BITMAP had numerous bugs and appears to have no users. */
> +       if (v.flags & VM86_SCREEN_BITMAP) {
> +               char comm[TASK_COMM_LEN];
> +
> +               pr_info_once("vm86: '%s' uses VM86_SCREEN_BITMAP, which is no longer supported\n", get_task_comm(comm, current);
> +               return -EINVAL;
> +       }
> +
>         memset(&vm86regs, 0, sizeof(vm86regs));
>
>         vm86regs.pt.bx = v.regs.ebx;
> @@ -370,9 +336,6 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
>         update_task_stack(tsk);
>         preempt_enable();
>
> -       if (vm86->flags & VM86_SCREEN_BITMAP)
> -               mark_screen_rdonly(tsk->mm);
> -
>         memcpy((struct kernel_vm86_regs *)regs, &vm86regs, sizeof(vm86regs));
>         return regs->ax;
>  }

You can also remove screen_bitmap from struct vm86 (the kernel
internal structure), and the check_v8086_mode() function.

--
Brian Gerst
kernel test robot Jan. 8, 2021, 10:16 p.m. UTC | #3
Hi Andy,

I love your patch! Perhaps something to improve:

[auto build test WARNING on tip/master]
[also build test WARNING on linux/master linus/master tip/x86/core v5.11-rc2 next-20210108]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Andy-Lutomirski/x86-vm86-32-Remove-VM86_SCREEN_BITMAP-support/20210109-025703
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 6c44caf1e694c346a5d9de6277079f097fb78359
config: i386-randconfig-s001-20210108 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-208-g46a52ca4-dirty
        # https://github.com/0day-ci/linux/commit/616553cd85241d71033c0cdd03655cd50157c46c
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Andy-Lutomirski/x86-vm86-32-Remove-VM86_SCREEN_BITMAP-support/20210109-025703
        git checkout 616553cd85241d71033c0cdd03655cd50157c46c
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   arch/x86/kernel/vm86_32.c: In function 'do_sys_vm86':
   arch/x86/kernel/vm86_32.c:829: error: unterminated argument list invoking macro "pr_info_once"
     829 | 
         | 
   arch/x86/kernel/vm86_32.c:247:3: error: 'pr_info_once' undeclared (first use in this function)
     247 |   pr_info_once("vm86: '%s' uses VM86_SCREEN_BITMAP, which is no longer supported\n", get_task_comm(comm, current);
         |   ^~~~~~~~~~~~
   arch/x86/kernel/vm86_32.c:247:3: note: each undeclared identifier is reported only once for each function it appears in
   arch/x86/kernel/vm86_32.c:247:15: error: expected ';' at end of input
     247 |   pr_info_once("vm86: '%s' uses VM86_SCREEN_BITMAP, which is no longer supported\n", get_task_comm(comm, current);
         |               ^
         |               ;
   ......
     829 | 
         |                
   arch/x86/kernel/vm86_32.c:247:3: error: expected declaration or statement at end of input
     247 |   pr_info_once("vm86: '%s' uses VM86_SCREEN_BITMAP, which is no longer supported\n", get_task_comm(comm, current);
         |   ^~~~~~~~~~~~
   arch/x86/kernel/vm86_32.c:245:8: warning: unused variable 'comm' [-Wunused-variable]
     245 |   char comm[TASK_COMM_LEN];
         |        ^~~~
   arch/x86/kernel/vm86_32.c:247:3: error: expected declaration or statement at end of input
     247 |   pr_info_once("vm86: '%s' uses VM86_SCREEN_BITMAP, which is no longer supported\n", get_task_comm(comm, current);
         |   ^~~~~~~~~~~~
   arch/x86/kernel/vm86_32.c:200:18: warning: unused variable 'regs' [-Wunused-variable]
     200 |  struct pt_regs *regs = current_pt_regs();
         |                  ^~~~
   arch/x86/kernel/vm86_32.c:199:26: warning: unused variable 'vm86regs' [-Wunused-variable]
     199 |  struct kernel_vm86_regs vm86regs;
         |                          ^~~~~~~~
   arch/x86/kernel/vm86_32.c: At top level:
>> arch/x86/kernel/vm86_32.c:163:12: warning: 'do_vm86_irq_handling' used but never defined
     163 | static int do_vm86_irq_handling(int subfunction, int irqnumber);
         |            ^~~~~~~~~~~~~~~~~~~~
   arch/x86/kernel/vm86_32.c: In function 'do_sys_vm86':
   arch/x86/kernel/vm86_32.c:829: error: control reaches end of non-void function [-Werror=return-type]
     829 | 
         | 
   cc1: some warnings being treated as errors


vim +/do_vm86_irq_handling +163 arch/x86/kernel/vm86_32.c

^1da177e4c3f415 arch/i386/kernel/vm86.c   Linus Torvalds 2005-04-16  162  
^1da177e4c3f415 arch/i386/kernel/vm86.c   Linus Torvalds 2005-04-16 @163  static int do_vm86_irq_handling(int subfunction, int irqnumber);
1342635638cba9b arch/x86/kernel/vm86_32.c Brian Gerst    2015-07-29  164  static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus);
^1da177e4c3f415 arch/i386/kernel/vm86.c   Linus Torvalds 2005-04-16  165  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Andrea Arcangeli Jan. 8, 2021, 11:39 p.m. UTC | #4
On Fri, Jan 08, 2021 at 10:55:05AM -0800, Andy Lutomirski wrote:
> The implementation was rather buggy.  It unconditionally marked PTEs
> released the mmap lock before flushing the TLB, which could allow a racing
> CoW operation to falsely believe that the underlying memory was not
> writable.
> 
> I can't find any users at all of this mechanism, so just remove it.

Reviewed-by: Andrea Arcangeli <aarcange@redhat.com>
Eric W. Biederman Jan. 9, 2021, 8:16 p.m. UTC | #5
Andy Lutomirski <luto@kernel.org> writes:

> The implementation was rather buggy.  It unconditionally marked PTEs
> read-only, even for VM_SHARED mappings.  I'm not sure whether this is
> actually a problem, but it certainly seems unwise.  More importantly, it
> released the mmap lock before flushing the TLB, which could allow a racing
> CoW operation to falsely believe that the underlying memory was not
> writable.
>
> I can't find any users at all of this mechanism, so just remove it.

In another age this was used by dosemu.  Have you looked at dosemu to
see if it still uses this support (on 32bit where dosemu can use vm86)?

It may still be a valid removal target I just wanted to point out what
the original user was.

Eric

> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: Linux-MM <linux-mm@kvack.org>
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Cc: x86@kernel.org
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Matthew Wilcox <willy@infradead.org>
> Cc: Jann Horn <jannh@google.com>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Yu Zhao <yuzhao@google.com>
> Cc: Peter Xu <peterx@redhat.com>
> Signed-off-by: Andy Lutomirski <luto@kernel.org>
> ---
>  arch/x86/include/uapi/asm/vm86.h |  2 +-
>  arch/x86/kernel/vm86_32.c        | 55 ++++++--------------------------
>  2 files changed, 10 insertions(+), 47 deletions(-)
>
> diff --git a/arch/x86/include/uapi/asm/vm86.h b/arch/x86/include/uapi/asm/vm86.h
> index d2ee4e307ef8..50004fb4590d 100644
> --- a/arch/x86/include/uapi/asm/vm86.h
> +++ b/arch/x86/include/uapi/asm/vm86.h
> @@ -106,7 +106,7 @@ struct vm86_struct {
>  /*
>   * flags masks
>   */
> -#define VM86_SCREEN_BITMAP	0x0001
> +#define VM86_SCREEN_BITMAP	0x0001        /* no longer supported */
>  
>  struct vm86plus_info_struct {
>  	unsigned long force_return_for_pic:1;
> diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
> index 764573de3996..28b9e8d511e1 100644
> --- a/arch/x86/kernel/vm86_32.c
> +++ b/arch/x86/kernel/vm86_32.c
> @@ -160,49 +160,6 @@ void save_v86_state(struct kernel_vm86_regs *regs, int retval)
>  	do_exit(SIGSEGV);
>  }
>  
> -static void mark_screen_rdonly(struct mm_struct *mm)
> -{
> -	struct vm_area_struct *vma;
> -	spinlock_t *ptl;
> -	pgd_t *pgd;
> -	p4d_t *p4d;
> -	pud_t *pud;
> -	pmd_t *pmd;
> -	pte_t *pte;
> -	int i;
> -
> -	mmap_write_lock(mm);
> -	pgd = pgd_offset(mm, 0xA0000);
> -	if (pgd_none_or_clear_bad(pgd))
> -		goto out;
> -	p4d = p4d_offset(pgd, 0xA0000);
> -	if (p4d_none_or_clear_bad(p4d))
> -		goto out;
> -	pud = pud_offset(p4d, 0xA0000);
> -	if (pud_none_or_clear_bad(pud))
> -		goto out;
> -	pmd = pmd_offset(pud, 0xA0000);
> -
> -	if (pmd_trans_huge(*pmd)) {
> -		vma = find_vma(mm, 0xA0000);
> -		split_huge_pmd(vma, pmd, 0xA0000);
> -	}
> -	if (pmd_none_or_clear_bad(pmd))
> -		goto out;
> -	pte = pte_offset_map_lock(mm, pmd, 0xA0000, &ptl);
> -	for (i = 0; i < 32; i++) {
> -		if (pte_present(*pte))
> -			set_pte(pte, pte_wrprotect(*pte));
> -		pte++;
> -	}
> -	pte_unmap_unlock(pte, ptl);
> -out:
> -	mmap_write_unlock(mm);
> -	flush_tlb_mm_range(mm, 0xA0000, 0xA0000 + 32*PAGE_SIZE, PAGE_SHIFT, false);
> -}
> -
> -
> -
>  static int do_vm86_irq_handling(int subfunction, int irqnumber);
>  static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus);
>  
> @@ -282,6 +239,15 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
>  			offsetof(struct vm86_struct, int_revectored)))
>  		return -EFAULT;
>  
> +
> +	/* VM86_SCREEN_BITMAP had numerous bugs and appears to have no users. */
> +	if (v.flags & VM86_SCREEN_BITMAP) {
> +		char comm[TASK_COMM_LEN];
> +
> +		pr_info_once("vm86: '%s' uses VM86_SCREEN_BITMAP, which is no longer supported\n", get_task_comm(comm, current);
> +		return -EINVAL;
> +	}
> +
>  	memset(&vm86regs, 0, sizeof(vm86regs));
>  
>  	vm86regs.pt.bx = v.regs.ebx;
> @@ -370,9 +336,6 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
>  	update_task_stack(tsk);
>  	preempt_enable();
>  
> -	if (vm86->flags & VM86_SCREEN_BITMAP)
> -		mark_screen_rdonly(tsk->mm);
> -
>  	memcpy((struct kernel_vm86_regs *)regs, &vm86regs, sizeof(vm86regs));
>  	return regs->ax;
>  }
Andy Lutomirski Jan. 9, 2021, 8:42 p.m. UTC | #6
> On Jan 9, 2021, at 12:17 PM, ebiederm@xmission.com wrote:
> 
> Andy Lutomirski <luto@kernel.org> writes:
> 
>> The implementation was rather buggy.  It unconditionally marked PTEs
>> read-only, even for VM_SHARED mappings.  I'm not sure whether this is
>> actually a problem, but it certainly seems unwise.  More importantly, it
>> released the mmap lock before flushing the TLB, which could allow a racing
>> CoW operation to falsely believe that the underlying memory was not
>> writable.
>> 
>> I can't find any users at all of this mechanism, so just remove it.
> 
> In another age this was used by dosemu.  Have you looked at dosemu to
> see if it still uses this support (on 32bit where dosemu can use vm86)?
> 
> It may still be a valid removal target I just wanted to point out what
> the original user was.

I’m pretty sure that dosemu2 does not use this support.  I think the original dosemu doesn’t either, but I’m also not convinced it has any users at all.

I meant to cc Stas, and I will for v2.

> 
> Eric
> 
>> Cc: Andrea Arcangeli <aarcange@redhat.com>
>> Cc: Linux-MM <linux-mm@kvack.org>
>> Cc: Jason Gunthorpe <jgg@ziepe.ca>
>> Cc: x86@kernel.org
>> Cc: Linus Torvalds <torvalds@linux-foundation.org>
>> Cc: Matthew Wilcox <willy@infradead.org>
>> Cc: Jann Horn <jannh@google.com>
>> Cc: Jan Kara <jack@suse.cz>
>> Cc: Yu Zhao <yuzhao@google.com>
>> Cc: Peter Xu <peterx@redhat.com>
>> Signed-off-by: Andy Lutomirski <luto@kernel.org>
>> ---
>> arch/x86/include/uapi/asm/vm86.h |  2 +-
>> arch/x86/kernel/vm86_32.c        | 55 ++++++--------------------------
>> 2 files changed, 10 insertions(+), 47 deletions(-)
>> 
>> diff --git a/arch/x86/include/uapi/asm/vm86.h b/arch/x86/include/uapi/asm/vm86.h
>> index d2ee4e307ef8..50004fb4590d 100644
>> --- a/arch/x86/include/uapi/asm/vm86.h
>> +++ b/arch/x86/include/uapi/asm/vm86.h
>> @@ -106,7 +106,7 @@ struct vm86_struct {
>> /*
>>  * flags masks
>>  */
>> -#define VM86_SCREEN_BITMAP    0x0001
>> +#define VM86_SCREEN_BITMAP    0x0001        /* no longer supported */
>> 
>> struct vm86plus_info_struct {
>>    unsigned long force_return_for_pic:1;
>> diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
>> index 764573de3996..28b9e8d511e1 100644
>> --- a/arch/x86/kernel/vm86_32.c
>> +++ b/arch/x86/kernel/vm86_32.c
>> @@ -160,49 +160,6 @@ void save_v86_state(struct kernel_vm86_regs *regs, int retval)
>>    do_exit(SIGSEGV);
>> }
>> 
>> -static void mark_screen_rdonly(struct mm_struct *mm)
>> -{
>> -    struct vm_area_struct *vma;
>> -    spinlock_t *ptl;
>> -    pgd_t *pgd;
>> -    p4d_t *p4d;
>> -    pud_t *pud;
>> -    pmd_t *pmd;
>> -    pte_t *pte;
>> -    int i;
>> -
>> -    mmap_write_lock(mm);
>> -    pgd = pgd_offset(mm, 0xA0000);
>> -    if (pgd_none_or_clear_bad(pgd))
>> -        goto out;
>> -    p4d = p4d_offset(pgd, 0xA0000);
>> -    if (p4d_none_or_clear_bad(p4d))
>> -        goto out;
>> -    pud = pud_offset(p4d, 0xA0000);
>> -    if (pud_none_or_clear_bad(pud))
>> -        goto out;
>> -    pmd = pmd_offset(pud, 0xA0000);
>> -
>> -    if (pmd_trans_huge(*pmd)) {
>> -        vma = find_vma(mm, 0xA0000);
>> -        split_huge_pmd(vma, pmd, 0xA0000);
>> -    }
>> -    if (pmd_none_or_clear_bad(pmd))
>> -        goto out;
>> -    pte = pte_offset_map_lock(mm, pmd, 0xA0000, &ptl);
>> -    for (i = 0; i < 32; i++) {
>> -        if (pte_present(*pte))
>> -            set_pte(pte, pte_wrprotect(*pte));
>> -        pte++;
>> -    }
>> -    pte_unmap_unlock(pte, ptl);
>> -out:
>> -    mmap_write_unlock(mm);
>> -    flush_tlb_mm_range(mm, 0xA0000, 0xA0000 + 32*PAGE_SIZE, PAGE_SHIFT, false);
>> -}
>> -
>> -
>> -
>> static int do_vm86_irq_handling(int subfunction, int irqnumber);
>> static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus);
>> 
>> @@ -282,6 +239,15 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
>>            offsetof(struct vm86_struct, int_revectored)))
>>        return -EFAULT;
>> 
>> +
>> +    /* VM86_SCREEN_BITMAP had numerous bugs and appears to have no users. */
>> +    if (v.flags & VM86_SCREEN_BITMAP) {
>> +        char comm[TASK_COMM_LEN];
>> +
>> +        pr_info_once("vm86: '%s' uses VM86_SCREEN_BITMAP, which is no longer supported\n", get_task_comm(comm, current);
>> +        return -EINVAL;
>> +    }
>> +
>>    memset(&vm86regs, 0, sizeof(vm86regs));
>> 
>>    vm86regs.pt.bx = v.regs.ebx;
>> @@ -370,9 +336,6 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
>>    update_task_stack(tsk);
>>    preempt_enable();
>> 
>> -    if (vm86->flags & VM86_SCREEN_BITMAP)
>> -        mark_screen_rdonly(tsk->mm);
>> -
>>    memcpy((struct kernel_vm86_regs *)regs, &vm86regs, sizeof(vm86regs));
>>    return regs->ax;
>> }
diff mbox series

Patch

diff --git a/arch/x86/include/uapi/asm/vm86.h b/arch/x86/include/uapi/asm/vm86.h
index d2ee4e307ef8..50004fb4590d 100644
--- a/arch/x86/include/uapi/asm/vm86.h
+++ b/arch/x86/include/uapi/asm/vm86.h
@@ -106,7 +106,7 @@  struct vm86_struct {
 /*
  * flags masks
  */
-#define VM86_SCREEN_BITMAP	0x0001
+#define VM86_SCREEN_BITMAP	0x0001        /* no longer supported */
 
 struct vm86plus_info_struct {
 	unsigned long force_return_for_pic:1;
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index 764573de3996..28b9e8d511e1 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -160,49 +160,6 @@  void save_v86_state(struct kernel_vm86_regs *regs, int retval)
 	do_exit(SIGSEGV);
 }
 
-static void mark_screen_rdonly(struct mm_struct *mm)
-{
-	struct vm_area_struct *vma;
-	spinlock_t *ptl;
-	pgd_t *pgd;
-	p4d_t *p4d;
-	pud_t *pud;
-	pmd_t *pmd;
-	pte_t *pte;
-	int i;
-
-	mmap_write_lock(mm);
-	pgd = pgd_offset(mm, 0xA0000);
-	if (pgd_none_or_clear_bad(pgd))
-		goto out;
-	p4d = p4d_offset(pgd, 0xA0000);
-	if (p4d_none_or_clear_bad(p4d))
-		goto out;
-	pud = pud_offset(p4d, 0xA0000);
-	if (pud_none_or_clear_bad(pud))
-		goto out;
-	pmd = pmd_offset(pud, 0xA0000);
-
-	if (pmd_trans_huge(*pmd)) {
-		vma = find_vma(mm, 0xA0000);
-		split_huge_pmd(vma, pmd, 0xA0000);
-	}
-	if (pmd_none_or_clear_bad(pmd))
-		goto out;
-	pte = pte_offset_map_lock(mm, pmd, 0xA0000, &ptl);
-	for (i = 0; i < 32; i++) {
-		if (pte_present(*pte))
-			set_pte(pte, pte_wrprotect(*pte));
-		pte++;
-	}
-	pte_unmap_unlock(pte, ptl);
-out:
-	mmap_write_unlock(mm);
-	flush_tlb_mm_range(mm, 0xA0000, 0xA0000 + 32*PAGE_SIZE, PAGE_SHIFT, false);
-}
-
-
-
 static int do_vm86_irq_handling(int subfunction, int irqnumber);
 static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus);
 
@@ -282,6 +239,15 @@  static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
 			offsetof(struct vm86_struct, int_revectored)))
 		return -EFAULT;
 
+
+	/* VM86_SCREEN_BITMAP had numerous bugs and appears to have no users. */
+	if (v.flags & VM86_SCREEN_BITMAP) {
+		char comm[TASK_COMM_LEN];
+
+		pr_info_once("vm86: '%s' uses VM86_SCREEN_BITMAP, which is no longer supported\n", get_task_comm(comm, current);
+		return -EINVAL;
+	}
+
 	memset(&vm86regs, 0, sizeof(vm86regs));
 
 	vm86regs.pt.bx = v.regs.ebx;
@@ -370,9 +336,6 @@  static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
 	update_task_stack(tsk);
 	preempt_enable();
 
-	if (vm86->flags & VM86_SCREEN_BITMAP)
-		mark_screen_rdonly(tsk->mm);
-
 	memcpy((struct kernel_vm86_regs *)regs, &vm86regs, sizeof(vm86regs));
 	return regs->ax;
 }