Skip to content

Commit 2dbebf7

Browse files
Sean Christophersonbonzini
authored andcommitted
KVM: nVMX: Plumb L2 GPA through to PML emulation
Explicitly pass the L2 GPA to kvm_arch_write_log_dirty(), which for all intents and purposes is vmx_write_pml_buffer(), instead of having the latter pull the GPA from vmcs.GUEST_PHYSICAL_ADDRESS. If the dirty bit update is the result of KVM emulation (rare for L2), then the GPA in the VMCS may be stale and/or hold a completely unrelated GPA. Fixes: c5f983f ("nVMX: Implement emulated Page Modification Logging") Cc: [email protected] Signed-off-by: Sean Christopherson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 312d16c commit 2dbebf7

File tree

5 files changed

+11
-10
lines changed

5 files changed

+11
-10
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1220,7 +1220,7 @@ struct kvm_x86_ops {
12201220
void (*enable_log_dirty_pt_masked)(struct kvm *kvm,
12211221
struct kvm_memory_slot *slot,
12221222
gfn_t offset, unsigned long mask);
1223-
int (*write_log_dirty)(struct kvm_vcpu *vcpu);
1223+
int (*write_log_dirty)(struct kvm_vcpu *vcpu, gpa_t l2_gpa);
12241224

12251225
/* pmu operations of sub-arch */
12261226
const struct kvm_pmu_ops *pmu_ops;

arch/x86/kvm/mmu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ void kvm_mmu_gfn_disallow_lpage(struct kvm_memory_slot *slot, gfn_t gfn);
222222
void kvm_mmu_gfn_allow_lpage(struct kvm_memory_slot *slot, gfn_t gfn);
223223
bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm,
224224
struct kvm_memory_slot *slot, u64 gfn);
225-
int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu);
225+
int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu, gpa_t l2_gpa);
226226

227227
int kvm_mmu_post_init_vm(struct kvm *kvm);
228228
void kvm_mmu_pre_destroy_vm(struct kvm *kvm);

arch/x86/kvm/mmu/mmu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,10 +1745,10 @@ void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm,
17451745
* Emulate arch specific page modification logging for the
17461746
* nested hypervisor
17471747
*/
1748-
int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu)
1748+
int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu, gpa_t l2_gpa)
17491749
{
17501750
if (kvm_x86_ops.write_log_dirty)
1751-
return kvm_x86_ops.write_log_dirty(vcpu);
1751+
return kvm_x86_ops.write_log_dirty(vcpu, l2_gpa);
17521752

17531753
return 0;
17541754
}

arch/x86/kvm/mmu/paging_tmpl.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ static inline unsigned FNAME(gpte_access)(u64 gpte)
235235
static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu,
236236
struct kvm_mmu *mmu,
237237
struct guest_walker *walker,
238-
int write_fault)
238+
gpa_t addr, int write_fault)
239239
{
240240
unsigned level, index;
241241
pt_element_t pte, orig_pte;
@@ -260,7 +260,7 @@ static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu,
260260
!(pte & PT_GUEST_DIRTY_MASK)) {
261261
trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte));
262262
#if PTTYPE == PTTYPE_EPT
263-
if (kvm_arch_write_log_dirty(vcpu))
263+
if (kvm_arch_write_log_dirty(vcpu, addr))
264264
return -EINVAL;
265265
#endif
266266
pte |= PT_GUEST_DIRTY_MASK;
@@ -454,7 +454,8 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
454454
(PT_GUEST_DIRTY_SHIFT - PT_GUEST_ACCESSED_SHIFT);
455455

456456
if (unlikely(!accessed_dirty)) {
457-
ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, write_fault);
457+
ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker,
458+
addr, write_fault);
458459
if (unlikely(ret < 0))
459460
goto error;
460461
else if (ret)

arch/x86/kvm/vmx/vmx.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7500,11 +7500,11 @@ static void vmx_flush_log_dirty(struct kvm *kvm)
75007500
kvm_flush_pml_buffers(kvm);
75017501
}
75027502

7503-
static int vmx_write_pml_buffer(struct kvm_vcpu *vcpu)
7503+
static int vmx_write_pml_buffer(struct kvm_vcpu *vcpu, gpa_t gpa)
75047504
{
75057505
struct vmcs12 *vmcs12;
75067506
struct vcpu_vmx *vmx = to_vmx(vcpu);
7507-
gpa_t gpa, dst;
7507+
gpa_t dst;
75087508

75097509
if (is_guest_mode(vcpu)) {
75107510
WARN_ON_ONCE(vmx->nested.pml_full);
@@ -7523,7 +7523,7 @@ static int vmx_write_pml_buffer(struct kvm_vcpu *vcpu)
75237523
return 1;
75247524
}
75257525

7526-
gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS) & ~0xFFFull;
7526+
gpa &= ~0xFFFull;
75277527
dst = vmcs12->pml_address + sizeof(u64) * vmcs12->guest_pml_index;
75287528

75297529
if (kvm_write_guest_page(vcpu->kvm, gpa_to_gfn(dst), &gpa,

0 commit comments

Comments
 (0)