|
[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 |