2021-01-08 18:57:28

by Andy Lutomirski

[permalink] [raw]
Subject: [PATCH] x86/vm86/32: Remove VM86_SCREEN_BITMAP support

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 <[email protected]>
Cc: Linux-MM <[email protected]>
Cc: Jason Gunthorpe <[email protected]>
Cc: [email protected]
Cc: Linus Torvalds <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Jann Horn <[email protected]>
Cc: Jan Kara <[email protected]>
Cc: Yu Zhao <[email protected]>
Cc: Peter Xu <[email protected]>
Signed-off-by: Andy Lutomirski <[email protected]>
---
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;
}
--
2.29.2


2021-01-08 19:25:36

by Linus Torvalds

[permalink] [raw]
Subject: Re: [PATCH] x86/vm86/32: Remove VM86_SCREEN_BITMAP support

On Fri, Jan 8, 2021 at 10:55 AM Andy Lutomirski <[email protected]> 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

2021-01-08 19:32:02

by Brian Gerst

[permalink] [raw]
Subject: Re: [PATCH] x86/vm86/32: Remove VM86_SCREEN_BITMAP support

On Fri, Jan 8, 2021 at 1:59 PM Andy Lutomirski <[email protected]> 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 <[email protected]>
> Cc: Linux-MM <[email protected]>
> Cc: Jason Gunthorpe <[email protected]>
> Cc: [email protected]
> Cc: Linus Torvalds <[email protected]>
> Cc: Matthew Wilcox <[email protected]>
> Cc: Jann Horn <[email protected]>
> Cc: Jan Kara <[email protected]>
> Cc: Yu Zhao <[email protected]>
> Cc: Peter Xu <[email protected]>
> Signed-off-by: Andy Lutomirski <[email protected]>
> ---
> 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

2021-01-08 22:18:49

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] x86/vm86/32: Remove VM86_SCREEN_BITMAP support

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 <[email protected]>

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/[email protected]


Attachments:
(No filename) (4.37 kB)
.config.gz (31.81 kB)
Download all attachments

2021-01-08 23:43:38

by Andrea Arcangeli

[permalink] [raw]
Subject: Re: [PATCH] x86/vm86/32: Remove VM86_SCREEN_BITMAP support

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 <[email protected]>

2021-01-09 20:21:26

by Eric W. Biederman

[permalink] [raw]
Subject: Re: [PATCH] x86/vm86/32: Remove VM86_SCREEN_BITMAP support

Andy Lutomirski <[email protected]> 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 <[email protected]>
> Cc: Linux-MM <[email protected]>
> Cc: Jason Gunthorpe <[email protected]>
> Cc: [email protected]
> Cc: Linus Torvalds <[email protected]>
> Cc: Matthew Wilcox <[email protected]>
> Cc: Jann Horn <[email protected]>
> Cc: Jan Kara <[email protected]>
> Cc: Yu Zhao <[email protected]>
> Cc: Peter Xu <[email protected]>
> Signed-off-by: Andy Lutomirski <[email protected]>
> ---
> 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;
> }

2021-01-09 20:46:22

by Andy Lutomirski

[permalink] [raw]
Subject: Re: [PATCH] x86/vm86/32: Remove VM86_SCREEN_BITMAP support



> On Jan 9, 2021, at 12:17 PM, [email protected] wrote:
>
> Andy Lutomirski <[email protected]> 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 <[email protected]>
>> Cc: Linux-MM <[email protected]>
>> Cc: Jason Gunthorpe <[email protected]>
>> Cc: [email protected]
>> Cc: Linus Torvalds <[email protected]>
>> Cc: Matthew Wilcox <[email protected]>
>> Cc: Jann Horn <[email protected]>
>> Cc: Jan Kara <[email protected]>
>> Cc: Yu Zhao <[email protected]>
>> Cc: Peter Xu <[email protected]>
>> Signed-off-by: Andy Lutomirski <[email protected]>
>> ---
>> 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;
>> }