Skip to content

Commit 42a0305

Browse files
committed
Merge tag 'kvmarm-fixes-6.17-1' of https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm64 changes for 6.17, take #2 - Correctly handle 'invariant' system registers for protected VMs - Improved handling of VNCR data aborts, including external aborts - Fixes for handling of FEAT_RAS for NV guests, providing a sane fault context during SEA injection and preventing the use of RASv1p1 fault injection hardware - Ensure that page table destruction when a VM is destroyed gives an opportunity to reschedule - Large fix to KVM's infrastructure for managing guest context loaded on the CPU, addressing issues where the output of AT emulation doesn't get reflected to the guest - Fix AT S12 emulation to actually perform stage-2 translation when necessary - Avoid attempting vLPI irqbypass when GICv4 has been explicitly disabled for a VM - Minor KVM + selftest fixes
2 parents 085e899 + ee372e6 commit 42a0305

34 files changed

+560
-349
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 2 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,115 +1160,8 @@ u64 kvm_vcpu_apply_reg_masks(const struct kvm_vcpu *, enum vcpu_sysreg, u64);
11601160
__v; \
11611161
})
11621162

1163-
u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg);
1164-
void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg);
1165-
1166-
static inline bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val)
1167-
{
1168-
/*
1169-
* *** VHE ONLY ***
1170-
*
1171-
* System registers listed in the switch are not saved on every
1172-
* exit from the guest but are only saved on vcpu_put.
1173-
*
1174-
* SYSREGS_ON_CPU *MUST* be checked before using this helper.
1175-
*
1176-
* Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but
1177-
* should never be listed below, because the guest cannot modify its
1178-
* own MPIDR_EL1 and MPIDR_EL1 is accessed for VCPU A from VCPU B's
1179-
* thread when emulating cross-VCPU communication.
1180-
*/
1181-
if (!has_vhe())
1182-
return false;
1183-
1184-
switch (reg) {
1185-
case SCTLR_EL1: *val = read_sysreg_s(SYS_SCTLR_EL12); break;
1186-
case CPACR_EL1: *val = read_sysreg_s(SYS_CPACR_EL12); break;
1187-
case TTBR0_EL1: *val = read_sysreg_s(SYS_TTBR0_EL12); break;
1188-
case TTBR1_EL1: *val = read_sysreg_s(SYS_TTBR1_EL12); break;
1189-
case TCR_EL1: *val = read_sysreg_s(SYS_TCR_EL12); break;
1190-
case TCR2_EL1: *val = read_sysreg_s(SYS_TCR2_EL12); break;
1191-
case PIR_EL1: *val = read_sysreg_s(SYS_PIR_EL12); break;
1192-
case PIRE0_EL1: *val = read_sysreg_s(SYS_PIRE0_EL12); break;
1193-
case POR_EL1: *val = read_sysreg_s(SYS_POR_EL12); break;
1194-
case ESR_EL1: *val = read_sysreg_s(SYS_ESR_EL12); break;
1195-
case AFSR0_EL1: *val = read_sysreg_s(SYS_AFSR0_EL12); break;
1196-
case AFSR1_EL1: *val = read_sysreg_s(SYS_AFSR1_EL12); break;
1197-
case FAR_EL1: *val = read_sysreg_s(SYS_FAR_EL12); break;
1198-
case MAIR_EL1: *val = read_sysreg_s(SYS_MAIR_EL12); break;
1199-
case VBAR_EL1: *val = read_sysreg_s(SYS_VBAR_EL12); break;
1200-
case CONTEXTIDR_EL1: *val = read_sysreg_s(SYS_CONTEXTIDR_EL12);break;
1201-
case TPIDR_EL0: *val = read_sysreg_s(SYS_TPIDR_EL0); break;
1202-
case TPIDRRO_EL0: *val = read_sysreg_s(SYS_TPIDRRO_EL0); break;
1203-
case TPIDR_EL1: *val = read_sysreg_s(SYS_TPIDR_EL1); break;
1204-
case AMAIR_EL1: *val = read_sysreg_s(SYS_AMAIR_EL12); break;
1205-
case CNTKCTL_EL1: *val = read_sysreg_s(SYS_CNTKCTL_EL12); break;
1206-
case ELR_EL1: *val = read_sysreg_s(SYS_ELR_EL12); break;
1207-
case SPSR_EL1: *val = read_sysreg_s(SYS_SPSR_EL12); break;
1208-
case PAR_EL1: *val = read_sysreg_par(); break;
1209-
case DACR32_EL2: *val = read_sysreg_s(SYS_DACR32_EL2); break;
1210-
case IFSR32_EL2: *val = read_sysreg_s(SYS_IFSR32_EL2); break;
1211-
case DBGVCR32_EL2: *val = read_sysreg_s(SYS_DBGVCR32_EL2); break;
1212-
case ZCR_EL1: *val = read_sysreg_s(SYS_ZCR_EL12); break;
1213-
case SCTLR2_EL1: *val = read_sysreg_s(SYS_SCTLR2_EL12); break;
1214-
default: return false;
1215-
}
1216-
1217-
return true;
1218-
}
1219-
1220-
static inline bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg)
1221-
{
1222-
/*
1223-
* *** VHE ONLY ***
1224-
*
1225-
* System registers listed in the switch are not restored on every
1226-
* entry to the guest but are only restored on vcpu_load.
1227-
*
1228-
* SYSREGS_ON_CPU *MUST* be checked before using this helper.
1229-
*
1230-
* Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but
1231-
* should never be listed below, because the MPIDR should only be set
1232-
* once, before running the VCPU, and never changed later.
1233-
*/
1234-
if (!has_vhe())
1235-
return false;
1236-
1237-
switch (reg) {
1238-
case SCTLR_EL1: write_sysreg_s(val, SYS_SCTLR_EL12); break;
1239-
case CPACR_EL1: write_sysreg_s(val, SYS_CPACR_EL12); break;
1240-
case TTBR0_EL1: write_sysreg_s(val, SYS_TTBR0_EL12); break;
1241-
case TTBR1_EL1: write_sysreg_s(val, SYS_TTBR1_EL12); break;
1242-
case TCR_EL1: write_sysreg_s(val, SYS_TCR_EL12); break;
1243-
case TCR2_EL1: write_sysreg_s(val, SYS_TCR2_EL12); break;
1244-
case PIR_EL1: write_sysreg_s(val, SYS_PIR_EL12); break;
1245-
case PIRE0_EL1: write_sysreg_s(val, SYS_PIRE0_EL12); break;
1246-
case POR_EL1: write_sysreg_s(val, SYS_POR_EL12); break;
1247-
case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); break;
1248-
case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); break;
1249-
case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); break;
1250-
case FAR_EL1: write_sysreg_s(val, SYS_FAR_EL12); break;
1251-
case MAIR_EL1: write_sysreg_s(val, SYS_MAIR_EL12); break;
1252-
case VBAR_EL1: write_sysreg_s(val, SYS_VBAR_EL12); break;
1253-
case CONTEXTIDR_EL1: write_sysreg_s(val, SYS_CONTEXTIDR_EL12);break;
1254-
case TPIDR_EL0: write_sysreg_s(val, SYS_TPIDR_EL0); break;
1255-
case TPIDRRO_EL0: write_sysreg_s(val, SYS_TPIDRRO_EL0); break;
1256-
case TPIDR_EL1: write_sysreg_s(val, SYS_TPIDR_EL1); break;
1257-
case AMAIR_EL1: write_sysreg_s(val, SYS_AMAIR_EL12); break;
1258-
case CNTKCTL_EL1: write_sysreg_s(val, SYS_CNTKCTL_EL12); break;
1259-
case ELR_EL1: write_sysreg_s(val, SYS_ELR_EL12); break;
1260-
case SPSR_EL1: write_sysreg_s(val, SYS_SPSR_EL12); break;
1261-
case PAR_EL1: write_sysreg_s(val, SYS_PAR_EL1); break;
1262-
case DACR32_EL2: write_sysreg_s(val, SYS_DACR32_EL2); break;
1263-
case IFSR32_EL2: write_sysreg_s(val, SYS_IFSR32_EL2); break;
1264-
case DBGVCR32_EL2: write_sysreg_s(val, SYS_DBGVCR32_EL2); break;
1265-
case ZCR_EL1: write_sysreg_s(val, SYS_ZCR_EL12); break;
1266-
case SCTLR2_EL1: write_sysreg_s(val, SYS_SCTLR2_EL12); break;
1267-
default: return false;
1268-
}
1269-
1270-
return true;
1271-
}
1163+
u64 vcpu_read_sys_reg(const struct kvm_vcpu *, enum vcpu_sysreg);
1164+
void vcpu_write_sys_reg(struct kvm_vcpu *, u64, enum vcpu_sysreg);
12721165

12731166
struct kvm_vm_stat {
12741167
struct kvm_vm_stat_generic generic;

arch/arm64/include/asm/kvm_mmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu);
180180
int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
181181
phys_addr_t pa, unsigned long size, bool writable);
182182

183+
int kvm_handle_guest_sea(struct kvm_vcpu *vcpu);
183184
int kvm_handle_guest_abort(struct kvm_vcpu *vcpu);
184185

185186
phys_addr_t kvm_mmu_get_httbr(void);

arch/arm64/include/asm/kvm_pgtable.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,11 @@ static inline kvm_pte_t *kvm_dereference_pteref(struct kvm_pgtable_walker *walke
355355
return pteref;
356356
}
357357

358+
static inline kvm_pte_t *kvm_dereference_pteref_raw(kvm_pteref_t pteref)
359+
{
360+
return pteref;
361+
}
362+
358363
static inline int kvm_pgtable_walk_begin(struct kvm_pgtable_walker *walker)
359364
{
360365
/*
@@ -384,6 +389,11 @@ static inline kvm_pte_t *kvm_dereference_pteref(struct kvm_pgtable_walker *walke
384389
return rcu_dereference_check(pteref, !(walker->flags & KVM_PGTABLE_WALK_SHARED));
385390
}
386391

392+
static inline kvm_pte_t *kvm_dereference_pteref_raw(kvm_pteref_t pteref)
393+
{
394+
return rcu_dereference_raw(pteref);
395+
}
396+
387397
static inline int kvm_pgtable_walk_begin(struct kvm_pgtable_walker *walker)
388398
{
389399
if (walker->flags & KVM_PGTABLE_WALK_SHARED)
@@ -551,6 +561,26 @@ static inline int kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2
551561
*/
552562
void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt);
553563

564+
/**
565+
* kvm_pgtable_stage2_destroy_range() - Destroy the unlinked range of addresses.
566+
* @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*().
567+
* @addr: Intermediate physical address at which to place the mapping.
568+
* @size: Size of the mapping.
569+
*
570+
* The page-table is assumed to be unreachable by any hardware walkers prior
571+
* to freeing and therefore no TLB invalidation is performed.
572+
*/
573+
void kvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt,
574+
u64 addr, u64 size);
575+
576+
/**
577+
* kvm_pgtable_stage2_destroy_pgd() - Destroy the PGD of guest stage-2 page-table.
578+
* @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*().
579+
*
580+
* It is assumed that the rest of the page-table is freed before this operation.
581+
*/
582+
void kvm_pgtable_stage2_destroy_pgd(struct kvm_pgtable *pgt);
583+
554584
/**
555585
* kvm_pgtable_stage2_free_unlinked() - Free an unlinked stage-2 paging structure.
556586
* @mm_ops: Memory management callbacks.

arch/arm64/include/asm/kvm_pkvm.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,9 @@ struct pkvm_mapping {
179179

180180
int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
181181
struct kvm_pgtable_mm_ops *mm_ops);
182-
void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt);
182+
void pkvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt,
183+
u64 addr, u64 size);
184+
void pkvm_pgtable_stage2_destroy_pgd(struct kvm_pgtable *pgt);
183185
int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
184186
enum kvm_pgtable_prot prot, void *mc,
185187
enum kvm_pgtable_walk_flags flags);

arch/arm64/include/asm/kvm_ras.h

Lines changed: 0 additions & 25 deletions
This file was deleted.

arch/arm64/include/asm/sysreg.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,9 +1142,6 @@
11421142

11431143
#define ARM64_FEATURE_FIELD_BITS 4
11441144

1145-
/* Defined for compatibility only, do not add new users. */
1146-
#define ARM64_FEATURE_MASK(x) (x##_MASK)
1147-
11481145
#ifdef __ASSEMBLY__
11491146

11501147
.macro mrs_s, rt, sreg

arch/arm64/kernel/cpufeature.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2269,6 +2269,24 @@ static void cpu_clear_disr(const struct arm64_cpu_capabilities *__unused)
22692269
/* Firmware may have left a deferred SError in this register. */
22702270
write_sysreg_s(0, SYS_DISR_EL1);
22712271
}
2272+
static bool has_rasv1p1(const struct arm64_cpu_capabilities *__unused, int scope)
2273+
{
2274+
const struct arm64_cpu_capabilities rasv1p1_caps[] = {
2275+
{
2276+
ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, RAS, V1P1)
2277+
},
2278+
{
2279+
ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, RAS, IMP)
2280+
},
2281+
{
2282+
ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, RAS_frac, RASv1p1)
2283+
},
2284+
};
2285+
2286+
return (has_cpuid_feature(&rasv1p1_caps[0], scope) ||
2287+
(has_cpuid_feature(&rasv1p1_caps[1], scope) &&
2288+
has_cpuid_feature(&rasv1p1_caps[2], scope)));
2289+
}
22722290
#endif /* CONFIG_ARM64_RAS_EXTN */
22732291

22742292
#ifdef CONFIG_ARM64_PTR_AUTH
@@ -2687,6 +2705,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
26872705
.cpu_enable = cpu_clear_disr,
26882706
ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, RAS, IMP)
26892707
},
2708+
{
2709+
.desc = "RASv1p1 Extension Support",
2710+
.capability = ARM64_HAS_RASV1P1_EXTN,
2711+
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
2712+
.matches = has_rasv1p1,
2713+
},
26902714
#endif /* CONFIG_ARM64_RAS_EXTN */
26912715
#ifdef CONFIG_ARM64_AMU_EXTN
26922716
{

arch/arm64/kvm/arm.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2408,12 +2408,12 @@ static u64 get_hyp_id_aa64pfr0_el1(void)
24082408
*/
24092409
u64 val = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
24102410

2411-
val &= ~(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) |
2412-
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3));
2411+
val &= ~(ID_AA64PFR0_EL1_CSV2 |
2412+
ID_AA64PFR0_EL1_CSV3);
24132413

2414-
val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2),
2414+
val |= FIELD_PREP(ID_AA64PFR0_EL1_CSV2,
24152415
arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED);
2416-
val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3),
2416+
val |= FIELD_PREP(ID_AA64PFR0_EL1_CSV3,
24172417
arm64_get_meltdown_state() == SPECTRE_UNAFFECTED);
24182418

24192419
return val;

arch/arm64/kvm/at.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,10 +1420,10 @@ void __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr)
14201420
return;
14211421

14221422
/*
1423-
* If we only have a single stage of translation (E2H=0 or
1424-
* TGE=1), exit early. Same thing if {VM,DC}=={0,0}.
1423+
* If we only have a single stage of translation (EL2&0), exit
1424+
* early. Same thing if {VM,DC}=={0,0}.
14251425
*/
1426-
if (!vcpu_el2_e2h_is_set(vcpu) || vcpu_el2_tge_is_set(vcpu) ||
1426+
if (compute_translation_regime(vcpu, op) == TR_EL20 ||
14271427
!(vcpu_read_sys_reg(vcpu, HCR_EL2) & (HCR_VM | HCR_DC)))
14281428
return;
14291429

arch/arm64/kvm/emulate-nested.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2833,7 +2833,7 @@ int kvm_inject_nested_sea(struct kvm_vcpu *vcpu, bool iabt, u64 addr)
28332833
iabt ? ESR_ELx_EC_IABT_LOW : ESR_ELx_EC_DABT_LOW);
28342834
esr |= ESR_ELx_FSC_EXTABT | ESR_ELx_IL;
28352835

2836-
vcpu_write_sys_reg(vcpu, FAR_EL2, addr);
2836+
vcpu_write_sys_reg(vcpu, addr, FAR_EL2);
28372837

28382838
if (__vcpu_sys_reg(vcpu, SCTLR2_EL2) & SCTLR2_EL1_EASE)
28392839
return kvm_inject_nested(vcpu, esr, except_type_serror);

0 commit comments

Comments
 (0)