> On Jan 9, 2021, at 12:17 PM, ebiederm@xxxxxxxxxxxx wrote: > > Andy Lutomirski <luto@xxxxxxxxxx> 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@xxxxxxxxxx> >> Cc: Linux-MM <linux-mm@xxxxxxxxx> >> Cc: Jason Gunthorpe <jgg@xxxxxxxx> >> Cc: x86@xxxxxxxxxx >> Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> >> Cc: Matthew Wilcox <willy@xxxxxxxxxxxxx> >> Cc: Jann Horn <jannh@xxxxxxxxxx> >> Cc: Jan Kara <jack@xxxxxxx> >> Cc: Yu Zhao <yuzhao@xxxxxxxxxx> >> Cc: Peter Xu <peterx@xxxxxxxxxx> >> Signed-off-by: Andy Lutomirski <luto@xxxxxxxxxx> >> --- >> 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; >> }