mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 13:44:15 +08:00
Merge remote-tracking branch 'origin/kvm-arm64/csv3' into kvmarm-master/queue
Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
commit
f86e54653e
@ -121,6 +121,7 @@ struct kvm_arch {
|
||||
unsigned int pmuver;
|
||||
|
||||
u8 pfr0_csv2;
|
||||
u8 pfr0_csv3;
|
||||
};
|
||||
|
||||
struct kvm_vcpu_fault_info {
|
||||
|
@ -91,5 +91,7 @@ bool has_spectre_v4(const struct arm64_cpu_capabilities *cap, int scope);
|
||||
void spectre_v4_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
|
||||
void spectre_v4_enable_task_mitigation(struct task_struct *tsk);
|
||||
|
||||
enum mitigation_state arm64_get_meltdown_state(void);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ASM_SPECTRE_H */
|
||||
|
@ -2846,14 +2846,28 @@ static int __init enable_mrs_emulation(void)
|
||||
|
||||
core_initcall(enable_mrs_emulation);
|
||||
|
||||
enum mitigation_state arm64_get_meltdown_state(void)
|
||||
{
|
||||
if (__meltdown_safe)
|
||||
return SPECTRE_UNAFFECTED;
|
||||
|
||||
if (arm64_kernel_unmapped_at_el0())
|
||||
return SPECTRE_MITIGATED;
|
||||
|
||||
return SPECTRE_VULNERABLE;
|
||||
}
|
||||
|
||||
ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (__meltdown_safe)
|
||||
switch (arm64_get_meltdown_state()) {
|
||||
case SPECTRE_UNAFFECTED:
|
||||
return sprintf(buf, "Not affected\n");
|
||||
|
||||
if (arm64_kernel_unmapped_at_el0())
|
||||
case SPECTRE_MITIGATED:
|
||||
return sprintf(buf, "Mitigation: PTI\n");
|
||||
|
||||
return sprintf(buf, "Vulnerable\n");
|
||||
default:
|
||||
return sprintf(buf, "Vulnerable\n");
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ static int kvm_arm_default_max_vcpus(void)
|
||||
return vgic_present ? kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS;
|
||||
}
|
||||
|
||||
static void set_default_csv2(struct kvm *kvm)
|
||||
static void set_default_spectre(struct kvm *kvm)
|
||||
{
|
||||
/*
|
||||
* The default is to expose CSV2 == 1 if the HW isn't affected.
|
||||
@ -113,6 +113,8 @@ static void set_default_csv2(struct kvm *kvm)
|
||||
*/
|
||||
if (arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED)
|
||||
kvm->arch.pfr0_csv2 = 1;
|
||||
if (arm64_get_meltdown_state() == SPECTRE_UNAFFECTED)
|
||||
kvm->arch.pfr0_csv3 = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,7 +142,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
||||
/* The maximum number of VCPUs is limited by the host's GIC model */
|
||||
kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
|
||||
|
||||
set_default_csv2(kvm);
|
||||
set_default_spectre(kvm);
|
||||
|
||||
return ret;
|
||||
out_free_stage2_pgd:
|
||||
|
@ -1026,6 +1026,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
|
||||
val &= ~(0xfUL << ID_AA64PFR0_AMU_SHIFT);
|
||||
val &= ~(0xfUL << ID_AA64PFR0_CSV2_SHIFT);
|
||||
val |= ((u64)vcpu->kvm->arch.pfr0_csv2 << ID_AA64PFR0_CSV2_SHIFT);
|
||||
val &= ~(0xfUL << ID_AA64PFR0_CSV3_SHIFT);
|
||||
val |= ((u64)vcpu->kvm->arch.pfr0_csv3 << ID_AA64PFR0_CSV3_SHIFT);
|
||||
} else if (id == SYS_ID_AA64PFR1_EL1) {
|
||||
val &= ~(0xfUL << ID_AA64PFR1_MTE_SHIFT);
|
||||
} else if (id == SYS_ID_AA64ISAR1_EL1 && !vcpu_has_ptrauth(vcpu)) {
|
||||
@ -1118,9 +1120,9 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
|
||||
const struct kvm_one_reg *reg, void __user *uaddr)
|
||||
{
|
||||
const u64 id = sys_reg_to_index(rd);
|
||||
u8 csv2, csv3;
|
||||
int err;
|
||||
u64 val;
|
||||
u8 csv2;
|
||||
|
||||
err = reg_from_user(&val, uaddr, id);
|
||||
if (err)
|
||||
@ -1136,13 +1138,21 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
|
||||
(csv2 && arm64_get_spectre_v2_state() != SPECTRE_UNAFFECTED))
|
||||
return -EINVAL;
|
||||
|
||||
/* We can only differ with CSV2, and anything else is an error */
|
||||
/* Same thing for CSV3 */
|
||||
csv3 = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR0_CSV3_SHIFT);
|
||||
if (csv3 > 1 ||
|
||||
(csv3 && arm64_get_meltdown_state() != SPECTRE_UNAFFECTED))
|
||||
return -EINVAL;
|
||||
|
||||
/* We can only differ with CSV[23], and anything else is an error */
|
||||
val ^= read_id_reg(vcpu, rd, false);
|
||||
val &= ~(0xFUL << ID_AA64PFR0_CSV2_SHIFT);
|
||||
val &= ~((0xFUL << ID_AA64PFR0_CSV2_SHIFT) |
|
||||
(0xFUL << ID_AA64PFR0_CSV3_SHIFT));
|
||||
if (val)
|
||||
return -EINVAL;
|
||||
|
||||
vcpu->kvm->arch.pfr0_csv2 = csv2;
|
||||
vcpu->kvm->arch.pfr0_csv3 = csv3 ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user