aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/paging_tmpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm/paging_tmpl.h')
-rw-r--r--drivers/kvm/paging_tmpl.h15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h
index afcd2a8f45bb..149fa45fd9a5 100644
--- a/drivers/kvm/paging_tmpl.h
+++ b/drivers/kvm/paging_tmpl.h
@@ -71,7 +71,7 @@ struct guest_walker {
71 */ 71 */
72static int FNAME(walk_addr)(struct guest_walker *walker, 72static int FNAME(walk_addr)(struct guest_walker *walker,
73 struct kvm_vcpu *vcpu, gva_t addr, 73 struct kvm_vcpu *vcpu, gva_t addr,
74 int write_fault, int user_fault) 74 int write_fault, int user_fault, int fetch_fault)
75{ 75{
76 hpa_t hpa; 76 hpa_t hpa;
77 struct kvm_memory_slot *slot; 77 struct kvm_memory_slot *slot;
@@ -123,6 +123,11 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
123 if (user_fault && !(*ptep & PT_USER_MASK)) 123 if (user_fault && !(*ptep & PT_USER_MASK))
124 goto access_error; 124 goto access_error;
125 125
126#if PTTYPE == 64
127 if (fetch_fault && is_nx(vcpu) && (*ptep & PT64_NX_MASK))
128 goto access_error;
129#endif
130
126 if (!(*ptep & PT_ACCESSED_MASK)) 131 if (!(*ptep & PT_ACCESSED_MASK))
127 *ptep |= PT_ACCESSED_MASK; /* avoid rmw */ 132 *ptep |= PT_ACCESSED_MASK; /* avoid rmw */
128 133
@@ -169,6 +174,8 @@ err:
169 walker->error_code |= PFERR_WRITE_MASK; 174 walker->error_code |= PFERR_WRITE_MASK;
170 if (user_fault) 175 if (user_fault)
171 walker->error_code |= PFERR_USER_MASK; 176 walker->error_code |= PFERR_USER_MASK;
177 if (fetch_fault)
178 walker->error_code |= PFERR_FETCH_MASK;
172 return 0; 179 return 0;
173} 180}
174 181
@@ -372,6 +379,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
372{ 379{
373 int write_fault = error_code & PFERR_WRITE_MASK; 380 int write_fault = error_code & PFERR_WRITE_MASK;
374 int user_fault = error_code & PFERR_USER_MASK; 381 int user_fault = error_code & PFERR_USER_MASK;
382 int fetch_fault = error_code & PFERR_FETCH_MASK;
375 struct guest_walker walker; 383 struct guest_walker walker;
376 u64 *shadow_pte; 384 u64 *shadow_pte;
377 int fixed; 385 int fixed;
@@ -388,7 +396,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
388 /* 396 /*
389 * Look up the shadow pte for the faulting address. 397 * Look up the shadow pte for the faulting address.
390 */ 398 */
391 r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault); 399 r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault,
400 fetch_fault);
392 401
393 /* 402 /*
394 * The page is not mapped by the guest. Let the guest handle it. 403 * The page is not mapped by the guest. Let the guest handle it.
@@ -437,7 +446,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr)
437 pt_element_t guest_pte; 446 pt_element_t guest_pte;
438 gpa_t gpa; 447 gpa_t gpa;
439 448
440 FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0); 449 FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0);
441 guest_pte = *walker.ptep; 450 guest_pte = *walker.ptep;
442 FNAME(release_walker)(&walker); 451 FNAME(release_walker)(&walker);
443 452