aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/paging_tmpl.h9
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 9d03ad4dd5ec..1caeb4d22e01 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -246,6 +246,12 @@ walk:
246 gfn_t gfn; 246 gfn_t gfn;
247 u32 ac; 247 u32 ac;
248 248
249 /* check if the kernel is fetching from user page */
250 if (unlikely(pte_access & PT_USER_MASK) &&
251 kvm_read_cr4_bits(vcpu, X86_CR4_SMEP))
252 if (fetch_fault && !user_fault)
253 eperm = true;
254
249 gfn = gpte_to_gfn_lvl(pte, lvl); 255 gfn = gpte_to_gfn_lvl(pte, lvl);
250 gfn += (addr & PT_LVL_OFFSET_MASK(lvl)) >> PAGE_SHIFT; 256 gfn += (addr & PT_LVL_OFFSET_MASK(lvl)) >> PAGE_SHIFT;
251 257
@@ -305,7 +311,8 @@ error:
305 311
306 walker->fault.error_code |= write_fault | user_fault; 312 walker->fault.error_code |= write_fault | user_fault;
307 313
308 if (fetch_fault && mmu->nx) 314 if (fetch_fault && (mmu->nx ||
315 kvm_read_cr4_bits(vcpu, X86_CR4_SMEP)))
309 walker->fault.error_code |= PFERR_FETCH_MASK; 316 walker->fault.error_code |= PFERR_FETCH_MASK;
310 if (rsvd_fault) 317 if (rsvd_fault)
311 walker->fault.error_code |= PFERR_RSVD_MASK; 318 walker->fault.error_code |= PFERR_RSVD_MASK;