[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode
On 15/04/14 14:01, Feng Wu wrote: > Use STAC/CLAC to temporary disable SMAP to allow legal accesses to > user pages in kernel mode > > Signed-off-by: Feng Wu <feng.wu@xxxxxxxxx> > --- > xen/arch/x86/clear_page.S | 3 +++ > xen/arch/x86/domain_build.c | 16 ++++++++++++++++ > xen/arch/x86/usercopy.c | 6 ++++++ > xen/arch/x86/x86_64/compat/entry.S | 2 ++ > xen/arch/x86/x86_64/entry.S | 4 ++++ > xen/include/asm-x86/uaccess.h | 4 ++++ > xen/include/asm-x86/x86_64/system.h | 2 ++ > 7 files changed, 37 insertions(+) > > diff --git a/xen/arch/x86/clear_page.S b/xen/arch/x86/clear_page.S > index 96315ad..2ef4bb0 100644 > --- a/xen/arch/x86/clear_page.S > +++ b/xen/arch/x86/clear_page.S > @@ -1,9 +1,11 @@ > #include <xen/config.h> > #include <asm/page.h> > +#include <asm/asm_defns.h> > > #define ptr_reg %rdi > > ENTRY(clear_page_sse2) > + ASM_STAC > mov $PAGE_SIZE/16, %ecx > xor %eax,%eax > > @@ -15,5 +17,6 @@ ENTRY(clear_page_sse2) > lea 16(ptr_reg), ptr_reg > jnz 0b > > + ASM_CLAC > sfence > ret > diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c > index 84ce392..1ba138b 100644 > --- a/xen/arch/x86/domain_build.c > +++ b/xen/arch/x86/domain_build.c > @@ -789,8 +789,10 @@ int __init construct_dom0( > rc = -1; > goto out; > } > + stac(); > hypercall_page_initialise( > d, (void *)(unsigned long)parms.virt_hypercall); > + clac(); > } > > /* Free temporary buffers. */ > @@ -799,6 +801,7 @@ int __init construct_dom0( > /* Set up start info area. */ > si = (start_info_t *)vstartinfo_start; > clear_page(si); > + stac(); > si->nr_pages = nr_pages; > > si->shared_info = virt_to_maddr(d->shared_info); > @@ -813,6 +816,7 @@ int __init construct_dom0( > snprintf(si->magic, sizeof(si->magic), "xen-3.0-x86_%d%s", > elf_64bit(&elf) ? 64 : 32, parms.pae ? "p" : ""); > > + clac(); > count = d->tot_pages; > l4start = map_domain_page(pagetable_get_pfn(v->arch.guest_table)); > l3tab = NULL; > @@ -956,16 +960,20 @@ int __init construct_dom0( > if ( pfn > REVERSE_START && (vinitrd_start || pfn < initrd_pfn) ) > mfn = alloc_epfn - (pfn - REVERSE_START); > #endif > + stac(); > if ( !is_pv_32on64_domain(d) ) > ((unsigned long *)vphysmap_start)[pfn] = mfn; > else > ((unsigned int *)vphysmap_start)[pfn] = mfn; > + clac(); > set_gpfn_from_mfn(mfn, pfn); > if (!(pfn & 0xfffff)) > process_pending_softirqs(); > } > + stac(); > si->first_p2m_pfn = pfn; > si->nr_p2m_frames = d->tot_pages - count; > + clac(); > page_list_for_each ( page, &d->page_list ) > { > mfn = page_to_mfn(page); > @@ -976,7 +984,9 @@ int __init construct_dom0( > if ( !page->u.inuse.type_info && > !get_page_and_type(page, d, PGT_writable_page) ) > BUG(); > + stac(); > ((unsigned long *)vphysmap_start)[pfn] = mfn; > + clac(); > set_gpfn_from_mfn(mfn, pfn); > ++pfn; > if (!(pfn & 0xfffff)) > @@ -985,7 +995,9 @@ int __init construct_dom0( > } > BUG_ON(pfn != d->tot_pages); > #ifndef NDEBUG > + stac(); > alloc_epfn += PFN_UP(initrd_len) + si->nr_p2m_frames; > + clac(); This could presumably be eliminated by keeping a stack copy of si->nr_p2m_frames ? ~Andrew > #endif > while ( pfn < nr_pages ) > { > @@ -997,10 +1009,12 @@ int __init construct_dom0( > #ifndef NDEBUG > #define pfn (nr_pages - 1 - (pfn - (alloc_epfn - alloc_spfn))) > #endif > + stac(); > if ( !is_pv_32on64_domain(d) ) > ((unsigned long *)vphysmap_start)[pfn] = mfn; > else > ((unsigned int *)vphysmap_start)[pfn] = mfn; > + clac(); > set_gpfn_from_mfn(mfn, pfn); > #undef pfn > page++; pfn++; > @@ -1009,6 +1023,7 @@ int __init construct_dom0( > } > } > > + stac(); > if ( initrd_len != 0 ) > { > si->mod_start = vinitrd_start ?: initrd_pfn; > @@ -1024,6 +1039,7 @@ int __init construct_dom0( > si->console.dom0.info_off = sizeof(struct start_info); > si->console.dom0.info_size = sizeof(struct dom0_vga_console_info); > } > + clac(); > > if ( is_pv_32on64_domain(d) ) > xlat_start_info(si, XLAT_start_info_console_dom0); > diff --git a/xen/arch/x86/usercopy.c b/xen/arch/x86/usercopy.c > index b79202b..5dd77db 100644 > --- a/xen/arch/x86/usercopy.c > +++ b/xen/arch/x86/usercopy.c > @@ -15,6 +15,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void > *from, unsigned n) > unsigned long __d0, __d1, __d2, __n = n; > > asm volatile ( > + ASM_STAC"\n" > " cmp $"STR(2*BYTES_PER_LONG-1)",%0\n" > " jbe 1f\n" > " mov %1,%0\n" > @@ -30,6 +31,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void > *from, unsigned n) > " mov %3,%0\n" > "1: rep movsb\n" /* ...remainder copied as bytes */ > "2:\n" > + ASM_CLAC"\n" > ".section .fixup,\"ax\"\n" > "5: add %3,%0\n" > " jmp 2b\n" > @@ -52,6 +54,7 @@ __copy_from_user_ll(void *to, const void __user *from, > unsigned n) > unsigned long __d0, __d1, __d2, __n = n; > > asm volatile ( > + ASM_STAC"\n" > " cmp $"STR(2*BYTES_PER_LONG-1)",%0\n" > " jbe 1f\n" > " mov %1,%0\n" > @@ -67,6 +70,7 @@ __copy_from_user_ll(void *to, const void __user *from, > unsigned n) > " mov %3,%0\n" > "1: rep; movsb\n" /* ...remainder copied as bytes */ > "2:\n" > + ASM_CLAC"\n" > ".section .fixup,\"ax\"\n" > "5: add %3,%0\n" > " jmp 6f\n" > @@ -114,10 +118,12 @@ copy_to_user(void __user *to, const void *from, > unsigned n) > do { \ > long __d0; \ > __asm__ __volatile__( \ > + ASM_STAC"\n" \ > "0: rep; stosl\n" \ > " movl %2,%0\n" \ > "1: rep; stosb\n" \ > "2:\n" \ > + ASM_CLAC"\n" \ > ".section .fixup,\"ax\"\n" \ > "3: lea 0(%2,%0,4),%0\n" \ > " jmp 2b\n" \ > diff --git a/xen/arch/x86/x86_64/compat/entry.S > b/xen/arch/x86/x86_64/compat/entry.S > index 32b3bcc..b0fabf4 100644 > --- a/xen/arch/x86/x86_64/compat/entry.S > +++ b/xen/arch/x86/x86_64/compat/entry.S > @@ -265,6 +265,7 @@ ENTRY(compat_int80_direct_trap) > /* On return only %rbx and %rdx are guaranteed non-clobbered. */ > compat_create_bounce_frame: > ASSERT_INTERRUPTS_ENABLED > + ASM_STAC > mov %fs,%edi > testb $2,UREGS_cs+8(%rsp) > jz 1f > @@ -336,6 +337,7 @@ __UNLIKELY_END(compat_bounce_null_selector) > movl %eax,UREGS_cs+8(%rsp) > movl TRAPBOUNCE_eip(%rdx),%eax > movl %eax,UREGS_rip+8(%rsp) > + ASM_CLAC > ret > .section .fixup,"ax" > .Lfx13: > diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S > index 3ea4683..63ba795 100644 > --- a/xen/arch/x86/x86_64/entry.S > +++ b/xen/arch/x86/x86_64/entry.S > @@ -377,6 +377,7 @@ __UNLIKELY_END(create_bounce_frame_bad_sp) > movb TRAPBOUNCE_flags(%rdx),%cl > subq $40,%rsi > movq UREGS_ss+8(%rsp),%rax > + ASM_STAC > .Lft2: movq %rax,32(%rsi) # SS > movq UREGS_rsp+8(%rsp),%rax > .Lft3: movq %rax,24(%rsi) # RSP > @@ -434,9 +435,11 @@ UNLIKELY_END(bounce_failsafe) > testq %rax,%rax > UNLIKELY_START(z, create_bounce_frame_bad_bounce_ip) > lea > UNLIKELY_DISPATCH_LABEL(create_bounce_frame_bad_bounce_ip)(%rip), %rdi > + ASM_CLAC > jmp asm_domain_crash_synchronous /* Does not return */ > __UNLIKELY_END(create_bounce_frame_bad_bounce_ip) > movq %rax,UREGS_rip+8(%rsp) > + ASM_CLAC > ret > _ASM_EXTABLE(.Lft2, dom_crash_sync_extable) > _ASM_EXTABLE(.Lft3, dom_crash_sync_extable) > @@ -463,6 +466,7 @@ ENTRY(dom_crash_sync_extable) > leal (%rax,%rax,2),%eax > orb %al,UREGS_cs(%rsp) > xorl %edi,%edi > + ASM_CLAC > jmp asm_domain_crash_synchronous /* Does not return */ > > /* No special register assumptions. */ > diff --git a/xen/include/asm-x86/uaccess.h b/xen/include/asm-x86/uaccess.h > index 88b4ba2..ce1af4a 100644 > --- a/xen/include/asm-x86/uaccess.h > +++ b/xen/include/asm-x86/uaccess.h > @@ -147,8 +147,10 @@ struct __large_struct { unsigned long buf[100]; }; > */ > #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ > __asm__ __volatile__( \ > + ASM_STAC"\n" \ > "1: mov"itype" %"rtype"1,%2\n" \ > "2:\n" \ > + ASM_CLAC"\n" \ > ".section .fixup,\"ax\"\n" \ > "3: mov %3,%0\n" \ > " jmp 2b\n" \ > @@ -159,8 +161,10 @@ struct __large_struct { unsigned long buf[100]; }; > > #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \ > __asm__ __volatile__( \ > + ASM_STAC"\n" \ > "1: mov"itype" %2,%"rtype"1\n" \ > "2:\n" \ > + ASM_CLAC"\n" \ > ".section .fixup,\"ax\"\n" \ > "3: mov %3,%0\n" \ > " xor"itype" %"rtype"1,%"rtype"1\n" \ > diff --git a/xen/include/asm-x86/x86_64/system.h > b/xen/include/asm-x86/x86_64/system.h > index 20f038b..b8394b9 100644 > --- a/xen/include/asm-x86/x86_64/system.h > +++ b/xen/include/asm-x86/x86_64/system.h > @@ -13,8 +13,10 @@ > */ > #define __cmpxchg_user(_p,_o,_n,_isuff,_oppre,_regtype) \ > asm volatile ( \ > + ASM_STAC"\n" \ > "1: lock; cmpxchg"_isuff" %"_oppre"2,%3\n" \ > "2:\n" \ > + ASM_CLAC"\n" \ > ".section .fixup,\"ax\"\n" \ > "3: movl $1,%1\n" \ > " jmp 2b\n" \ _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |