[PATCH 05/31] KVM: apply nGPA->GPA translation to KVM_HC_CLOCK_PAIRING
From: Paolo Bonzini
Date: Fri Sep 18 2026 - 10:43:10 EST
KVM_HC_CLOCK_PAIRING writes to a guest physical addresses. Treat it
as an L2 address when running nested, which is consistent with the
Hyper-V TLB flush hypercalls for example.
This is technically backwards incompatible, but it should be extremely
unlikely to happen in the wild and thus we can treat it as a bugfix, I think.
Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
arch/x86/kvm/x86.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4b3681796c75..0fbe2d4e685f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7195,8 +7195,8 @@ static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr,
{
struct kvm_clock_pairing clock_pairing;
struct timespec64 ts;
+ size_t offset = 0;
u64 cycle;
- int ret;
if (clock_type != KVM_CLOCK_PAIRING_WALLCLOCK)
return -KVM_EOPNOTSUPP;
@@ -7217,12 +7217,20 @@ static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr,
clock_pairing.flags = 0;
memset(&clock_pairing.pad, 0, sizeof(clock_pairing.pad));
- ret = 0;
- if (kvm_write_guest(vcpu->kvm, paddr, &clock_pairing,
- sizeof(struct kvm_clock_pairing)))
- ret = -KVM_EFAULT;
+ while (offset < sizeof(clock_pairing)) {
+ gpa_t gpa = kvm_translate_gpa(vcpu, &vcpu->arch.gva_walk, paddr + offset,
+ PFERR_WRITE_MASK | PFERR_GUEST_FINAL_MASK, NULL, 0);
+ size_t len = min_t(size_t, sizeof(clock_pairing) - offset,
+ PAGE_SIZE - offset_in_page(gpa));
- return ret;
+ if (gpa == INVALID_GPA)
+ return -KVM_EFAULT;
+ if (kvm_write_guest(vcpu->kvm, gpa, (u8 *)&clock_pairing + offset, len))
+ return -KVM_EFAULT;
+
+ offset += len;
+ }
+ return 0;
}
#endif
--
2.52.0