UPSTREAM: KVM: arm64: Allow SMCCC_ARCH_WORKAROUND_3 to be discovered and migrated
commit a5905d6af492ee6a4a2205f0d550b3f931b03d03 upstream. KVM allows the guest to discover whether the ARCH_WORKAROUND SMCCC are implemented, and to preserve that state during migration through its firmware register interface. Add the necessary boiler plate for SMCCC_ARCH_WORKAROUND_3. Bug: 215557547 Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I9e0964b54727930bbda4f089c91075447b046c91
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
0f76dfc55d
commit
98b16e808f
@@ -270,6 +270,11 @@ struct kvm_vcpu_events {
|
|||||||
#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED 3
|
#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED 3
|
||||||
#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED (1U << 4)
|
#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED (1U << 4)
|
||||||
|
|
||||||
|
#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3 KVM_REG_ARM_FW_REG(3)
|
||||||
|
#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL 0
|
||||||
|
#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL 1
|
||||||
|
#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED 2
|
||||||
|
|
||||||
/* SVE registers */
|
/* SVE registers */
|
||||||
#define KVM_REG_ARM64_SVE (0x15 << KVM_REG_ARM_COPROC_SHIFT)
|
#define KVM_REG_ARM64_SVE (0x15 << KVM_REG_ARM_COPROC_SHIFT)
|
||||||
|
|
||||||
|
@@ -58,6 +58,18 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ARM_SMCCC_ARCH_WORKAROUND_3:
|
||||||
|
switch (arm64_get_spectre_bhb_state()) {
|
||||||
|
case SPECTRE_VULNERABLE:
|
||||||
|
break;
|
||||||
|
case SPECTRE_MITIGATED:
|
||||||
|
val = SMCCC_RET_SUCCESS;
|
||||||
|
break;
|
||||||
|
case SPECTRE_UNAFFECTED:
|
||||||
|
val = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ARM_SMCCC_HV_PV_TIME_FEATURES:
|
case ARM_SMCCC_HV_PV_TIME_FEATURES:
|
||||||
val = SMCCC_RET_SUCCESS;
|
val = SMCCC_RET_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
@@ -397,7 +397,7 @@ int kvm_psci_call(struct kvm_vcpu *vcpu)
|
|||||||
|
|
||||||
int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
|
int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
return 3; /* PSCI version and two workaround registers */
|
return 4; /* PSCI version and three workaround registers */
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
|
int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
|
||||||
@@ -411,6 +411,9 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
|
|||||||
if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, uindices++))
|
if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, uindices++))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3, uindices++))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,6 +453,17 @@ static int get_kernel_wa_level(u64 regid)
|
|||||||
case SPECTRE_VULNERABLE:
|
case SPECTRE_VULNERABLE:
|
||||||
return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
|
return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
|
||||||
|
switch (arm64_get_spectre_bhb_state()) {
|
||||||
|
case SPECTRE_VULNERABLE:
|
||||||
|
return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;
|
||||||
|
case SPECTRE_MITIGATED:
|
||||||
|
return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL;
|
||||||
|
case SPECTRE_UNAFFECTED:
|
||||||
|
return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED;
|
||||||
|
}
|
||||||
|
return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -466,6 +480,7 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
|
|||||||
break;
|
break;
|
||||||
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
|
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
|
||||||
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
|
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
|
||||||
|
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
|
||||||
val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
|
val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -511,6 +526,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
|
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
|
||||||
|
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
|
||||||
if (val & ~KVM_REG_FEATURE_LEVEL_MASK)
|
if (val & ~KVM_REG_FEATURE_LEVEL_MASK)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user