diff options
Diffstat (limited to 'drivers/kvm/paging_tmpl.h')
-rw-r--r-- | drivers/kvm/paging_tmpl.h | 15 |
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 | */ |
72 | static int FNAME(walk_addr)(struct guest_walker *walker, | 72 | static 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 | ||