Skip to content

Commit 0062442

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: "Fixes for ARM and x86, the latter especially for old processors without two-dimensional paging (EPT/NPT)" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: kvm: mmu: fix is_tdp_mmu_check when the TDP MMU is not in use KVM: SVM: Update cr3_lm_rsvd_bits for AMD SEV guests KVM: x86: Introduce cr3_lm_rsvd_bits in kvm_vcpu_arch KVM: x86: clflushopt should be treated as a no-op by emulation KVM: arm64: Handle SCXTNUM_ELx traps KVM: arm64: Unify trap handlers injecting an UNDEF KVM: arm64: Allow setting of ID_AA64PFR0_EL1.CSV2 from userspace
2 parents 326fd6d + c887c9b commit 0062442

File tree

10 files changed

+115
-46
lines changed

10 files changed

+115
-46
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ struct kvm_arch {
118118
*/
119119
unsigned long *pmu_filter;
120120
unsigned int pmuver;
121+
122+
u8 pfr0_csv2;
121123
};
122124

123125
struct kvm_vcpu_fault_info {

arch/arm64/include/asm/sysreg.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,8 @@
372372
#define SYS_CONTEXTIDR_EL1 sys_reg(3, 0, 13, 0, 1)
373373
#define SYS_TPIDR_EL1 sys_reg(3, 0, 13, 0, 4)
374374

375+
#define SYS_SCXTNUM_EL1 sys_reg(3, 0, 13, 0, 7)
376+
375377
#define SYS_CNTKCTL_EL1 sys_reg(3, 0, 14, 1, 0)
376378

377379
#define SYS_CCSIDR_EL1 sys_reg(3, 1, 0, 0, 0)
@@ -404,6 +406,8 @@
404406
#define SYS_TPIDR_EL0 sys_reg(3, 3, 13, 0, 2)
405407
#define SYS_TPIDRRO_EL0 sys_reg(3, 3, 13, 0, 3)
406408

409+
#define SYS_SCXTNUM_EL0 sys_reg(3, 3, 13, 0, 7)
410+
407411
/* Definitions for system register interface to AMU for ARMv8.4 onwards */
408412
#define SYS_AM_EL0(crm, op2) sys_reg(3, 3, 13, (crm), (op2))
409413
#define SYS_AMCR_EL0 SYS_AM_EL0(2, 0)

arch/arm64/kvm/arm.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,20 @@ static int kvm_arm_default_max_vcpus(void)
102102
return vgic_present ? kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS;
103103
}
104104

105+
static void set_default_csv2(struct kvm *kvm)
106+
{
107+
/*
108+
* The default is to expose CSV2 == 1 if the HW isn't affected.
109+
* Although this is a per-CPU feature, we make it global because
110+
* asymmetric systems are just a nuisance.
111+
*
112+
* Userspace can override this as long as it doesn't promise
113+
* the impossible.
114+
*/
115+
if (arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED)
116+
kvm->arch.pfr0_csv2 = 1;
117+
}
118+
105119
/**
106120
* kvm_arch_init_vm - initializes a VM data structure
107121
* @kvm: pointer to the KVM struct
@@ -127,6 +141,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
127141
/* The maximum number of VCPUs is limited by the host's GIC model */
128142
kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
129143

144+
set_default_csv2(kvm);
145+
130146
return ret;
131147
out_free_stage2_pgd:
132148
kvm_free_stage2_pgd(&kvm->arch.mmu);

arch/arm64/kvm/sys_regs.c

Lines changed: 67 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,42 +1038,34 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
10381038
{ SYS_DESC(SYS_PMEVTYPERn_EL0(n)), \
10391039
access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), }
10401040

1041-
static bool access_amu(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
1042-
const struct sys_reg_desc *r)
1041+
static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
1042+
const struct sys_reg_desc *r)
10431043
{
10441044
kvm_inject_undefined(vcpu);
10451045

10461046
return false;
10471047
}
10481048

10491049
/* Macro to expand the AMU counter and type registers*/
1050-
#define AMU_AMEVCNTR0_EL0(n) { SYS_DESC(SYS_AMEVCNTR0_EL0(n)), access_amu }
1051-
#define AMU_AMEVTYPER0_EL0(n) { SYS_DESC(SYS_AMEVTYPER0_EL0(n)), access_amu }
1052-
#define AMU_AMEVCNTR1_EL0(n) { SYS_DESC(SYS_AMEVCNTR1_EL0(n)), access_amu }
1053-
#define AMU_AMEVTYPER1_EL0(n) { SYS_DESC(SYS_AMEVTYPER1_EL0(n)), access_amu }
1054-
1055-
static bool trap_ptrauth(struct kvm_vcpu *vcpu,
1056-
struct sys_reg_params *p,
1057-
const struct sys_reg_desc *rd)
1058-
{
1059-
/*
1060-
* If we land here, that is because we didn't fixup the access on exit
1061-
* by allowing the PtrAuth sysregs. The only way this happens is when
1062-
* the guest does not have PtrAuth support enabled.
1063-
*/
1064-
kvm_inject_undefined(vcpu);
1065-
1066-
return false;
1067-
}
1050+
#define AMU_AMEVCNTR0_EL0(n) { SYS_DESC(SYS_AMEVCNTR0_EL0(n)), undef_access }
1051+
#define AMU_AMEVTYPER0_EL0(n) { SYS_DESC(SYS_AMEVTYPER0_EL0(n)), undef_access }
1052+
#define AMU_AMEVCNTR1_EL0(n) { SYS_DESC(SYS_AMEVCNTR1_EL0(n)), undef_access }
1053+
#define AMU_AMEVTYPER1_EL0(n) { SYS_DESC(SYS_AMEVTYPER1_EL0(n)), undef_access }
10681054

10691055
static unsigned int ptrauth_visibility(const struct kvm_vcpu *vcpu,
10701056
const struct sys_reg_desc *rd)
10711057
{
10721058
return vcpu_has_ptrauth(vcpu) ? 0 : REG_HIDDEN;
10731059
}
10741060

1061+
/*
1062+
* If we land here on a PtrAuth access, that is because we didn't
1063+
* fixup the access on exit by allowing the PtrAuth sysregs. The only
1064+
* way this happens is when the guest does not have PtrAuth support
1065+
* enabled.
1066+
*/
10751067
#define __PTRAUTH_KEY(k) \
1076-
{ SYS_DESC(SYS_## k), trap_ptrauth, reset_unknown, k, \
1068+
{ SYS_DESC(SYS_## k), undef_access, reset_unknown, k, \
10771069
.visibility = ptrauth_visibility}
10781070

10791071
#define PTRAUTH_KEY(k) \
@@ -1128,9 +1120,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
11281120
if (!vcpu_has_sve(vcpu))
11291121
val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
11301122
val &= ~(0xfUL << ID_AA64PFR0_AMU_SHIFT);
1131-
if (!(val & (0xfUL << ID_AA64PFR0_CSV2_SHIFT)) &&
1132-
arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED)
1133-
val |= (1UL << ID_AA64PFR0_CSV2_SHIFT);
1123+
val &= ~(0xfUL << ID_AA64PFR0_CSV2_SHIFT);
1124+
val |= ((u64)vcpu->kvm->arch.pfr0_csv2 << ID_AA64PFR0_CSV2_SHIFT);
11341125
} else if (id == SYS_ID_AA64PFR1_EL1) {
11351126
val &= ~(0xfUL << ID_AA64PFR1_MTE_SHIFT);
11361127
} else if (id == SYS_ID_AA64ISAR1_EL1 && !vcpu_has_ptrauth(vcpu)) {
@@ -1213,6 +1204,40 @@ static unsigned int sve_visibility(const struct kvm_vcpu *vcpu,
12131204
return REG_HIDDEN;
12141205
}
12151206

1207+
static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
1208+
const struct sys_reg_desc *rd,
1209+
const struct kvm_one_reg *reg, void __user *uaddr)
1210+
{
1211+
const u64 id = sys_reg_to_index(rd);
1212+
int err;
1213+
u64 val;
1214+
u8 csv2;
1215+
1216+
err = reg_from_user(&val, uaddr, id);
1217+
if (err)
1218+
return err;
1219+
1220+
/*
1221+
* Allow AA64PFR0_EL1.CSV2 to be set from userspace as long as
1222+
* it doesn't promise more than what is actually provided (the
1223+
* guest could otherwise be covered in ectoplasmic residue).
1224+
*/
1225+
csv2 = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR0_CSV2_SHIFT);
1226+
if (csv2 > 1 ||
1227+
(csv2 && arm64_get_spectre_v2_state() != SPECTRE_UNAFFECTED))
1228+
return -EINVAL;
1229+
1230+
/* We can only differ with CSV2, and anything else is an error */
1231+
val ^= read_id_reg(vcpu, rd, false);
1232+
val &= ~(0xFUL << ID_AA64PFR0_CSV2_SHIFT);
1233+
if (val)
1234+
return -EINVAL;
1235+
1236+
vcpu->kvm->arch.pfr0_csv2 = csv2;
1237+
1238+
return 0;
1239+
}
1240+
12161241
/*
12171242
* cpufeature ID register user accessors
12181243
*
@@ -1341,13 +1366,6 @@ static bool access_ccsidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
13411366
return true;
13421367
}
13431368

1344-
static bool access_mte_regs(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
1345-
const struct sys_reg_desc *r)
1346-
{
1347-
kvm_inject_undefined(vcpu);
1348-
return false;
1349-
}
1350-
13511369
/* sys_reg_desc initialiser for known cpufeature ID registers */
13521370
#define ID_SANITISED(name) { \
13531371
SYS_DESC(SYS_##name), \
@@ -1472,7 +1490,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
14721490

14731491
/* AArch64 ID registers */
14741492
/* CRm=4 */
1475-
ID_SANITISED(ID_AA64PFR0_EL1),
1493+
{ SYS_DESC(SYS_ID_AA64PFR0_EL1), .access = access_id_reg,
1494+
.get_user = get_id_reg, .set_user = set_id_aa64pfr0_el1, },
14761495
ID_SANITISED(ID_AA64PFR1_EL1),
14771496
ID_UNALLOCATED(4,2),
14781497
ID_UNALLOCATED(4,3),
@@ -1515,8 +1534,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
15151534
{ SYS_DESC(SYS_ACTLR_EL1), access_actlr, reset_actlr, ACTLR_EL1 },
15161535
{ SYS_DESC(SYS_CPACR_EL1), NULL, reset_val, CPACR_EL1, 0 },
15171536

1518-
{ SYS_DESC(SYS_RGSR_EL1), access_mte_regs },
1519-
{ SYS_DESC(SYS_GCR_EL1), access_mte_regs },
1537+
{ SYS_DESC(SYS_RGSR_EL1), undef_access },
1538+
{ SYS_DESC(SYS_GCR_EL1), undef_access },
15201539

15211540
{ SYS_DESC(SYS_ZCR_EL1), NULL, reset_val, ZCR_EL1, 0, .visibility = sve_visibility },
15221541
{ SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 },
@@ -1542,8 +1561,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
15421561
{ SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi },
15431562
{ SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi },
15441563

1545-
{ SYS_DESC(SYS_TFSR_EL1), access_mte_regs },
1546-
{ SYS_DESC(SYS_TFSRE0_EL1), access_mte_regs },
1564+
{ SYS_DESC(SYS_TFSR_EL1), undef_access },
1565+
{ SYS_DESC(SYS_TFSRE0_EL1), undef_access },
15471566

15481567
{ SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 },
15491568
{ SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 },
@@ -1579,6 +1598,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
15791598
{ SYS_DESC(SYS_CONTEXTIDR_EL1), access_vm_reg, reset_val, CONTEXTIDR_EL1, 0 },
15801599
{ SYS_DESC(SYS_TPIDR_EL1), NULL, reset_unknown, TPIDR_EL1 },
15811600

1601+
{ SYS_DESC(SYS_SCXTNUM_EL1), undef_access },
1602+
15821603
{ SYS_DESC(SYS_CNTKCTL_EL1), NULL, reset_val, CNTKCTL_EL1, 0},
15831604

15841605
{ SYS_DESC(SYS_CCSIDR_EL1), access_ccsidr },
@@ -1607,14 +1628,16 @@ static const struct sys_reg_desc sys_reg_descs[] = {
16071628
{ SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
16081629
{ SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 },
16091630

1610-
{ SYS_DESC(SYS_AMCR_EL0), access_amu },
1611-
{ SYS_DESC(SYS_AMCFGR_EL0), access_amu },
1612-
{ SYS_DESC(SYS_AMCGCR_EL0), access_amu },
1613-
{ SYS_DESC(SYS_AMUSERENR_EL0), access_amu },
1614-
{ SYS_DESC(SYS_AMCNTENCLR0_EL0), access_amu },
1615-
{ SYS_DESC(SYS_AMCNTENSET0_EL0), access_amu },
1616-
{ SYS_DESC(SYS_AMCNTENCLR1_EL0), access_amu },
1617-
{ SYS_DESC(SYS_AMCNTENSET1_EL0), access_amu },
1631+
{ SYS_DESC(SYS_SCXTNUM_EL0), undef_access },
1632+
1633+
{ SYS_DESC(SYS_AMCR_EL0), undef_access },
1634+
{ SYS_DESC(SYS_AMCFGR_EL0), undef_access },
1635+
{ SYS_DESC(SYS_AMCGCR_EL0), undef_access },
1636+
{ SYS_DESC(SYS_AMUSERENR_EL0), undef_access },
1637+
{ SYS_DESC(SYS_AMCNTENCLR0_EL0), undef_access },
1638+
{ SYS_DESC(SYS_AMCNTENSET0_EL0), undef_access },
1639+
{ SYS_DESC(SYS_AMCNTENCLR1_EL0), undef_access },
1640+
{ SYS_DESC(SYS_AMCNTENSET1_EL0), undef_access },
16181641
AMU_AMEVCNTR0_EL0(0),
16191642
AMU_AMEVCNTR0_EL0(1),
16201643
AMU_AMEVCNTR0_EL0(2),

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,7 @@ struct kvm_vcpu_arch {
639639
int cpuid_nent;
640640
struct kvm_cpuid_entry2 *cpuid_entries;
641641

642+
unsigned long cr3_lm_rsvd_bits;
642643
int maxphyaddr;
643644
int max_tdp_level;
644645

arch/x86/kvm/cpuid.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
178178
vcpu->arch.cr4_guest_rsvd_bits =
179179
__cr4_reserved_bits(guest_cpuid_has, vcpu);
180180

181+
vcpu->arch.cr3_lm_rsvd_bits = rsvd_bits(cpuid_maxphyaddr(vcpu), 63);
182+
181183
/* Invoke the vendor callback only after the above state is updated. */
182184
kvm_x86_ops.vcpu_after_set_cpuid(vcpu);
183185
}

arch/x86/kvm/emulate.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4046,6 +4046,12 @@ static int em_clflush(struct x86_emulate_ctxt *ctxt)
40464046
return X86EMUL_CONTINUE;
40474047
}
40484048

4049+
static int em_clflushopt(struct x86_emulate_ctxt *ctxt)
4050+
{
4051+
/* emulating clflushopt regardless of cpuid */
4052+
return X86EMUL_CONTINUE;
4053+
}
4054+
40494055
static int em_movsxd(struct x86_emulate_ctxt *ctxt)
40504056
{
40514057
ctxt->dst.val = (s32) ctxt->src.val;
@@ -4585,7 +4591,7 @@ static const struct opcode group11[] = {
45854591
};
45864592

45874593
static const struct gprefix pfx_0f_ae_7 = {
4588-
I(SrcMem | ByteOp, em_clflush), N, N, N,
4594+
I(SrcMem | ByteOp, em_clflush), I(SrcMem | ByteOp, em_clflushopt), N, N,
45894595
};
45904596

45914597
static const struct group_dual group15 = { {

arch/x86/kvm/mmu/tdp_mmu.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,14 @@ bool is_tdp_mmu_root(struct kvm *kvm, hpa_t hpa)
4949
{
5050
struct kvm_mmu_page *sp;
5151

52+
if (!kvm->arch.tdp_mmu_enabled)
53+
return false;
54+
if (WARN_ON(!VALID_PAGE(hpa)))
55+
return false;
56+
5257
sp = to_shadow_page(hpa);
58+
if (WARN_ON(!sp))
59+
return false;
5360

5461
return sp->tdp_mmu_page && sp->root_count;
5562
}

arch/x86/kvm/svm/svm.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3741,6 +3741,7 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
37413741
static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
37423742
{
37433743
struct vcpu_svm *svm = to_svm(vcpu);
3744+
struct kvm_cpuid_entry2 *best;
37443745

37453746
vcpu->arch.xsaves_enabled = guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) &&
37463747
boot_cpu_has(X86_FEATURE_XSAVE) &&
@@ -3753,6 +3754,13 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
37533754
/* Check again if INVPCID interception if required */
37543755
svm_check_invpcid(svm);
37553756

3757+
/* For sev guests, the memory encryption bit is not reserved in CR3. */
3758+
if (sev_guest(vcpu->kvm)) {
3759+
best = kvm_find_cpuid_entry(vcpu, 0x8000001F, 0);
3760+
if (best)
3761+
vcpu->arch.cr3_lm_rsvd_bits &= ~(1UL << (best->ebx & 0x3f));
3762+
}
3763+
37563764
if (!kvm_vcpu_apicv_active(vcpu))
37573765
return;
37583766

arch/x86/kvm/x86.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,7 @@ int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
10411041
}
10421042

10431043
if (is_long_mode(vcpu) &&
1044-
(cr3 & rsvd_bits(cpuid_maxphyaddr(vcpu), 63)))
1044+
(cr3 & vcpu->arch.cr3_lm_rsvd_bits))
10451045
return 1;
10461046
else if (is_pae_paging(vcpu) &&
10471047
!load_pdptrs(vcpu, vcpu->arch.walk_mmu, cr3))

0 commit comments

Comments
 (0)