Skip to content

Commit e816252

Browse files
Fuad Tabbaoupton
authored andcommitted
KVM: arm64: Advertise ID_AA64PFR0_EL1.CSV2/3 to protected VMs
The existing pKVM code attempts to advertise CSV2/3 using values initialized to 0, but never set. To advertise CSV2/3 to protected guests, pass the CSV2/3 values to hyp when initializing hyp's view of guests' ID_AA64PFR0_EL1. Similar to non-protected KVM, these are system-wide, rather than per cpu, for simplicity. Fixes: 6c30bfb ("KVM: arm64: Add handlers for protected VM System Registers") Signed-off-by: Fuad Tabba <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent f9ea835 commit e816252

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

arch/arm64/kvm/arm.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1889,9 +1889,33 @@ static int __init do_pkvm_init(u32 hyp_va_bits)
18891889
return ret;
18901890
}
18911891

1892+
static u64 get_hyp_id_aa64pfr0_el1(void)
1893+
{
1894+
/*
1895+
* Track whether the system isn't affected by spectre/meltdown in the
1896+
* hypervisor's view of id_aa64pfr0_el1, used for protected VMs.
1897+
* Although this is per-CPU, we make it global for simplicity, e.g., not
1898+
* to have to worry about vcpu migration.
1899+
*
1900+
* Unlike for non-protected VMs, userspace cannot override this for
1901+
* protected VMs.
1902+
*/
1903+
u64 val = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
1904+
1905+
val &= ~(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) |
1906+
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3));
1907+
1908+
val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2),
1909+
arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED);
1910+
val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3),
1911+
arm64_get_meltdown_state() == SPECTRE_UNAFFECTED);
1912+
1913+
return val;
1914+
}
1915+
18921916
static void kvm_hyp_init_symbols(void)
18931917
{
1894-
kvm_nvhe_sym(id_aa64pfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
1918+
kvm_nvhe_sym(id_aa64pfr0_el1_sys_val) = get_hyp_id_aa64pfr0_el1();
18951919
kvm_nvhe_sym(id_aa64pfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
18961920
kvm_nvhe_sym(id_aa64isar0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR0_EL1);
18971921
kvm_nvhe_sym(id_aa64isar1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR1_EL1);

arch/arm64/kvm/hyp/include/nvhe/fixed_config.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,14 @@
3333
* Allow for protected VMs:
3434
* - Floating-point and Advanced SIMD
3535
* - Data Independent Timing
36+
* - Spectre/Meltdown Mitigation
3637
*/
3738
#define PVM_ID_AA64PFR0_ALLOW (\
3839
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP) | \
3940
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD) | \
40-
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_DIT) \
41+
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_DIT) | \
42+
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) | \
43+
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3) \
4144
)
4245

4346
/*

arch/arm64/kvm/hyp/nvhe/sys_regs.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,12 @@ static u64 get_restricted_features_unsigned(u64 sys_reg_val,
8585

8686
static u64 get_pvm_id_aa64pfr0(const struct kvm_vcpu *vcpu)
8787
{
88-
const struct kvm *kvm = (const struct kvm *)kern_hyp_va(vcpu->kvm);
8988
u64 set_mask = 0;
9089
u64 allow_mask = PVM_ID_AA64PFR0_ALLOW;
9190

9291
set_mask |= get_restricted_features_unsigned(id_aa64pfr0_el1_sys_val,
9392
PVM_ID_AA64PFR0_RESTRICT_UNSIGNED);
9493

95-
/* Spectre and Meltdown mitigation in KVM */
96-
set_mask |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2),
97-
(u64)kvm->arch.pfr0_csv2);
98-
set_mask |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3),
99-
(u64)kvm->arch.pfr0_csv3);
100-
10194
return (id_aa64pfr0_el1_sys_val & allow_mask) | set_mask;
10295
}
10396

0 commit comments

Comments
 (0)