[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode
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(); #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" \ -- 1.8.3.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |