diff options
author | Kevin Hilman <khilman@linaro.org> | 2015-09-14 14:20:38 -0700 |
---|---|---|
committer | Kevin Hilman <khilman@linaro.org> | 2015-09-14 14:20:38 -0700 |
commit | 705e0fe41b54f2dea954ebd692a870a36b04ce76 (patch) | |
tree | dc1c9e774d068ffac89fc9851c921c61cf44677d /arch/x86/xen/enlighten.c | |
parent | 373cea9e2c9c6495a80efdae55cf2114f384a75b (diff) | |
parent | c765e5c15e7d23d2b8b37fafdafc63c0ea75fabf (diff) |
Merge branch 'linux-linaro-lsk-v3.14' into linux-linaro-lsk-v3.14-rtlsk-v3.14-16.03-rtlsk-v3.14-16.02-rtlsk-v3.14-16.01-rtlsk-v3.14-15.12-rtlsk-v3.14-15.11-rtlsk-v3.14-15.10-rtlsk-v3.14-15.09-rtlinux-linaro-lsk-v3.14-rt
* linux-linaro-lsk-v3.14: (66 commits)
Linux 3.14.52
arm64: KVM: Fix host crash when injecting a fault into a 32bit guest
SCSI: Fix NULL pointer dereference in runtime PM
arm64/mm: Remove hack in mmap randomize layout
crypto: caam - fix memory corruption in ahash_final_ctx
regmap: regcache-rbtree: Clean new present bits on present bitmap resize
libfc: Fix fc_fcp_cleanup_each_cmd()
libfc: Fix fc_exch_recv_req() error path
drm/vmwgfx: Fix execbuf locking issues
drm/radeon: add new OLAND pci id
EDAC, ppc4xx: Access mci->csrows array elements properly
localmodconfig: Use Kbuild files too
dm thin metadata: delete btrees when releasing metadata snapshot
perf: Fix PERF_EVENT_IOC_PERIOD migration race
perf: Fix fasync handling on inherited events
xen-blkfront: don't add indirect pages to list when !feature_persistent
mm/hwpoison: fix page refcount of unknown non LRU page
ipc/sem.c: update/correct memory barriers
ipc,sem: fix use after free on IPC_RMID after a task using same semaphore set exits
arm64: el0_dbg does not set link reg for return to user path, breaks debug
...
Diffstat (limited to 'arch/x86/xen/enlighten.c')
-rw-r--r-- | arch/x86/xen/enlighten.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 201d09a7c46b..2302f10b1be6 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -481,6 +481,7 @@ static void set_aliased_prot(void *v, pgprot_t prot) pte_t pte; unsigned long pfn; struct page *page; + unsigned char dummy; ptep = lookup_address((unsigned long)v, &level); BUG_ON(ptep == NULL); @@ -490,6 +491,32 @@ static void set_aliased_prot(void *v, pgprot_t prot) pte = pfn_pte(pfn, prot); + /* + * Careful: update_va_mapping() will fail if the virtual address + * we're poking isn't populated in the page tables. We don't + * need to worry about the direct map (that's always in the page + * tables), but we need to be careful about vmap space. In + * particular, the top level page table can lazily propagate + * entries between processes, so if we've switched mms since we + * vmapped the target in the first place, we might not have the + * top-level page table entry populated. + * + * We disable preemption because we want the same mm active when + * we probe the target and when we issue the hypercall. We'll + * have the same nominal mm, but if we're a kernel thread, lazy + * mm dropping could change our pgd. + * + * Out of an abundance of caution, this uses __get_user() to fault + * in the target address just in case there's some obscure case + * in which the target address isn't readable. + */ + + preempt_disable(); + + pagefault_disable(); /* Avoid warnings due to being atomic. */ + __get_user(dummy, (unsigned char __user __force *)v); + pagefault_enable(); + if (HYPERVISOR_update_va_mapping((unsigned long)v, pte, 0)) BUG(); @@ -501,6 +528,8 @@ static void set_aliased_prot(void *v, pgprot_t prot) BUG(); } else kmap_flush_unused(); + + preempt_enable(); } static void xen_alloc_ldt(struct desc_struct *ldt, unsigned entries) @@ -508,6 +537,17 @@ static void xen_alloc_ldt(struct desc_struct *ldt, unsigned entries) const unsigned entries_per_page = PAGE_SIZE / LDT_ENTRY_SIZE; int i; + /* + * We need to mark the all aliases of the LDT pages RO. We + * don't need to call vm_flush_aliases(), though, since that's + * only responsible for flushing aliases out the TLBs, not the + * page tables, and Xen will flush the TLB for us if needed. + * + * To avoid confusing future readers: none of this is necessary + * to load the LDT. The hypervisor only checks this when the + * LDT is faulted in due to subsequent descriptor access. + */ + for(i = 0; i < entries; i += entries_per_page) set_aliased_prot(ldt + i, PAGE_KERNEL_RO); } |