Skip to content

Commit e8d1649

Browse files
shaoqinhMarc Zyngier
authored andcommitted
KVM: arm64: Use kvm_has_feat() to check if FEAT_SSBS is advertised to the guest
Currently KVM use cpus_have_final_cap() to check if FEAT_SSBS is advertised to the guest. But if FEAT_SSBS is writable and isn't advertised to the guest, this is wrong. Update it to use kvm_has_feat() to check if FEAT_SSBS is advertised to the guest, thus the KVM can do the right thing if FEAT_SSBS isn't advertised to the guest. Signed-off-by: Shaoqin Huang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent ffe68b2 commit e8d1649

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

arch/arm64/kvm/hypercalls.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu)
317317
* to the guest, and hide SSBS so that the
318318
* guest stays protected.
319319
*/
320-
if (cpus_have_final_cap(ARM64_SSBS))
320+
if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, SSBS, IMP))
321321
break;
322322
fallthrough;
323323
case SPECTRE_UNAFFECTED:
@@ -428,7 +428,7 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
428428
* Convert the workaround level into an easy-to-compare number, where higher
429429
* values mean better protection.
430430
*/
431-
static int get_kernel_wa_level(u64 regid)
431+
static int get_kernel_wa_level(struct kvm_vcpu *vcpu, u64 regid)
432432
{
433433
switch (regid) {
434434
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
@@ -449,7 +449,7 @@ static int get_kernel_wa_level(u64 regid)
449449
* don't have any FW mitigation if SSBS is there at
450450
* all times.
451451
*/
452-
if (cpus_have_final_cap(ARM64_SSBS))
452+
if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, SSBS, IMP))
453453
return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
454454
fallthrough;
455455
case SPECTRE_UNAFFECTED:
@@ -486,7 +486,7 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
486486
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
487487
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
488488
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
489-
val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
489+
val = get_kernel_wa_level(vcpu, reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
490490
break;
491491
case KVM_REG_ARM_STD_BMAP:
492492
val = READ_ONCE(smccc_feat->std_bmap);
@@ -588,7 +588,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
588588
if (val & ~KVM_REG_FEATURE_LEVEL_MASK)
589589
return -EINVAL;
590590

591-
if (get_kernel_wa_level(reg->id) < val)
591+
if (get_kernel_wa_level(vcpu, reg->id) < val)
592592
return -EINVAL;
593593

594594
return 0;
@@ -624,7 +624,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
624624
* We can deal with NOT_AVAIL on NOT_REQUIRED, but not the
625625
* other way around.
626626
*/
627-
if (get_kernel_wa_level(reg->id) < wa_level)
627+
if (get_kernel_wa_level(vcpu, reg->id) < wa_level)
628628
return -EINVAL;
629629

630630
return 0;

0 commit comments

Comments
 (0)