Skip to content

Commit 74c1807

Browse files
committed
KVM: x86: block KVM_CAP_SYNC_REGS if guest state is protected
KVM_CAP_SYNC_REGS does not make sense for VMs with protected guest state, since the register values cannot actually be written. Return 0 when using the VM-level KVM_CHECK_EXTENSION ioctl, and accordingly return -EINVAL from KVM_RUN if the valid/dirty fields are nonzero. However, on exit from KVM_RUN userspace could have placed a nonzero value into kvm_run->kvm_valid_regs, so check guest_state_protected again and skip store_regs() in that case. Cc: stable@vger.kernel.org Fixes: 517987e ("KVM: x86: add fields to struct kvm_arch for CoCo features") Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-ID: <20250306202923.646075-1-pbonzini@redhat.com> Reviewed-by: Pankaj Gupta <pankaj.gupta@amd.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent adafea1 commit 74c1807

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

arch/x86/kvm/x86.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4580,6 +4580,11 @@ static bool kvm_is_vm_type_supported(unsigned long type)
45804580
return type < 32 && (kvm_caps.supported_vm_types & BIT(type));
45814581
}
45824582

4583+
static inline u32 kvm_sync_valid_fields(struct kvm *kvm)
4584+
{
4585+
return kvm && kvm->arch.has_protected_state ? 0 : KVM_SYNC_X86_VALID_FIELDS;
4586+
}
4587+
45834588
int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
45844589
{
45854590
int r = 0;
@@ -4688,7 +4693,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
46884693
break;
46894694
#endif
46904695
case KVM_CAP_SYNC_REGS:
4691-
r = KVM_SYNC_X86_VALID_FIELDS;
4696+
r = kvm_sync_valid_fields(kvm);
46924697
break;
46934698
case KVM_CAP_ADJUST_CLOCK:
46944699
r = KVM_CLOCK_VALID_FLAGS;
@@ -11481,6 +11486,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
1148111486
{
1148211487
struct kvm_queued_exception *ex = &vcpu->arch.exception;
1148311488
struct kvm_run *kvm_run = vcpu->run;
11489+
u32 sync_valid_fields;
1148411490
int r;
1148511491

1148611492
r = kvm_mmu_post_init_vm(vcpu->kvm);
@@ -11526,8 +11532,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
1152611532
goto out;
1152711533
}
1152811534

11529-
if ((kvm_run->kvm_valid_regs & ~KVM_SYNC_X86_VALID_FIELDS) ||
11530-
(kvm_run->kvm_dirty_regs & ~KVM_SYNC_X86_VALID_FIELDS)) {
11535+
sync_valid_fields = kvm_sync_valid_fields(vcpu->kvm);
11536+
if ((kvm_run->kvm_valid_regs & ~sync_valid_fields) ||
11537+
(kvm_run->kvm_dirty_regs & ~sync_valid_fields)) {
1153111538
r = -EINVAL;
1153211539
goto out;
1153311540
}
@@ -11585,7 +11592,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
1158511592

1158611593
out:
1158711594
kvm_put_guest_fpu(vcpu);
11588-
if (kvm_run->kvm_valid_regs)
11595+
if (kvm_run->kvm_valid_regs && likely(!vcpu->arch.guest_state_protected))
1158911596
store_regs(vcpu);
1159011597
post_kvm_run_save(vcpu);
1159111598
kvm_vcpu_srcu_read_unlock(vcpu);

0 commit comments

Comments
 (0)