Skip to content

Commit 924ebae

Browse files
committed
Merge tag 'kvmarm-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm64 updates for 6.18 - Add support for FF-A 1.2 as the secure memory conduit for pKVM, allowing more registers to be used as part of the message payload. - Change the way pKVM allocates its VM handles, making sure that the privileged hypervisor is never tricked into using uninitialised data. - Speed up MMIO range registration by avoiding unnecessary RCU synchronisation, which results in VMs starting much quicker. - Add the dump of the instruction stream when panic-ing in the EL2 payload, just like the rest of the kernel has always done. This will hopefully help debugging non-VHE setups. - Add 52bit PA support to the stage-1 page-table walker, and make use of it to populate the fault level reported to the guest on failing to translate a stage-1 walk. - Add NV support to the GICv3-on-GICv5 emulation code, ensuring feature parity for guests, irrespective of the host platform. - Fix some really ugly architecture problems when dealing with debug in a nested VM. This has some bad performance impacts, but is at least correct. - Add enough infrastructure to be able to disable EL2 features and give effective values to the EL2 control registers. This then allows a bunch of features to be turned off, which helps cross-host migration. - Large rework of the selftest infrastructure to allow most tests to transparently run at EL2. This is the first step towards enabling NV testing. - Various fixes and improvements all over the map, including one BE fix, just in time for the removal of the feature.
2 parents 8cbb0df + 10fd028 commit 924ebae

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1696
-688
lines changed

arch/arm64/include/asm/kvm_asm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ enum __kvm_host_smccc_func {
8181
__KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff,
8282
__KVM_HOST_SMCCC_FUNC___vgic_v3_save_vmcr_aprs,
8383
__KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
84+
__KVM_HOST_SMCCC_FUNC___pkvm_reserve_vm,
85+
__KVM_HOST_SMCCC_FUNC___pkvm_unreserve_vm,
8486
__KVM_HOST_SMCCC_FUNC___pkvm_init_vm,
8587
__KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu,
8688
__KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,

arch/arm64/include/asm/kvm_emulate.h

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,20 @@ static inline bool vcpu_el2_tge_is_set(const struct kvm_vcpu *vcpu)
220220

221221
static inline bool vcpu_el2_amo_is_set(const struct kvm_vcpu *vcpu)
222222
{
223+
/*
224+
* DDI0487L.b Known Issue D22105
225+
*
226+
* When executing at EL2 and HCR_EL2.{E2H,TGE} = {1, 0} it is
227+
* IMPLEMENTATION DEFINED whether the effective value of HCR_EL2.AMO
228+
* is the value programmed or 1.
229+
*
230+
* Make the implementation choice of treating the effective value as 1 as
231+
* we cannot subsequently catch changes to TGE or AMO that would
232+
* otherwise lead to the SError becoming deliverable.
233+
*/
234+
if (vcpu_is_el2(vcpu) && vcpu_el2_e2h_is_set(vcpu) && !vcpu_el2_tge_is_set(vcpu))
235+
return true;
236+
223237
return ctxt_sys_reg(&vcpu->arch.ctxt, HCR_EL2) & HCR_AMO;
224238
}
225239

@@ -511,21 +525,29 @@ static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu)
511525
if (vcpu_mode_is_32bit(vcpu)) {
512526
*vcpu_cpsr(vcpu) |= PSR_AA32_E_BIT;
513527
} else {
514-
u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1);
528+
enum vcpu_sysreg r;
529+
u64 sctlr;
530+
531+
r = vcpu_has_nv(vcpu) ? SCTLR_EL2 : SCTLR_EL1;
532+
533+
sctlr = vcpu_read_sys_reg(vcpu, r);
515534
sctlr |= SCTLR_ELx_EE;
516-
vcpu_write_sys_reg(vcpu, sctlr, SCTLR_EL1);
535+
vcpu_write_sys_reg(vcpu, sctlr, r);
517536
}
518537
}
519538

520539
static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu)
521540
{
541+
enum vcpu_sysreg r;
542+
u64 bit;
543+
522544
if (vcpu_mode_is_32bit(vcpu))
523545
return !!(*vcpu_cpsr(vcpu) & PSR_AA32_E_BIT);
524546

525-
if (vcpu_mode_priv(vcpu))
526-
return !!(vcpu_read_sys_reg(vcpu, SCTLR_EL1) & SCTLR_ELx_EE);
527-
else
528-
return !!(vcpu_read_sys_reg(vcpu, SCTLR_EL1) & SCTLR_EL1_E0E);
547+
r = is_hyp_ctxt(vcpu) ? SCTLR_EL2 : SCTLR_EL1;
548+
bit = vcpu_mode_priv(vcpu) ? SCTLR_ELx_EE : SCTLR_EL1_E0E;
549+
550+
return vcpu_read_sys_reg(vcpu, r) & bit;
529551
}
530552

531553
static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu,

arch/arm64/include/asm/kvm_host.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ struct kvm_protected_vm {
252252
pkvm_handle_t handle;
253253
struct kvm_hyp_memcache teardown_mc;
254254
struct kvm_hyp_memcache stage2_teardown_mc;
255-
bool enabled;
255+
bool is_protected;
256+
bool is_created;
256257
};
257258

258259
struct kvm_mpidr_data {
@@ -1442,7 +1443,7 @@ struct kvm *kvm_arch_alloc_vm(void);
14421443

14431444
#define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS_RANGE
14441445

1445-
#define kvm_vm_is_protected(kvm) (is_protected_kvm_enabled() && (kvm)->arch.pkvm.enabled)
1446+
#define kvm_vm_is_protected(kvm) (is_protected_kvm_enabled() && (kvm)->arch.pkvm.is_protected)
14461447

14471448
#define vcpu_is_protected(vcpu) kvm_vm_is_protected((vcpu)->kvm)
14481449

arch/arm64/include/asm/kvm_nested.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ extern void check_nested_vcpu_requests(struct kvm_vcpu *vcpu);
8383
extern void kvm_nested_flush_hwstate(struct kvm_vcpu *vcpu);
8484
extern void kvm_nested_sync_hwstate(struct kvm_vcpu *vcpu);
8585

86+
extern void kvm_nested_setup_mdcr_el2(struct kvm_vcpu *vcpu);
87+
8688
struct kvm_s2_trans {
8789
phys_addr_t output;
8890
unsigned long block_size;
@@ -265,15 +267,18 @@ static inline u64 decode_range_tlbi(u64 val, u64 *range, u16 *asid)
265267
return base;
266268
}
267269

268-
static inline unsigned int ps_to_output_size(unsigned int ps)
270+
static inline unsigned int ps_to_output_size(unsigned int ps, bool pa52bit)
269271
{
270272
switch (ps) {
271273
case 0: return 32;
272274
case 1: return 36;
273275
case 2: return 40;
274276
case 3: return 42;
275277
case 4: return 44;
276-
case 5:
278+
case 5: return 48;
279+
case 6: if (pa52bit)
280+
return 52;
281+
fallthrough;
277282
default:
278283
return 48;
279284
}
@@ -285,20 +290,36 @@ enum trans_regime {
285290
TR_EL2,
286291
};
287292

293+
struct s1_walk_info;
294+
295+
struct s1_walk_context {
296+
struct s1_walk_info *wi;
297+
u64 table_ipa;
298+
int level;
299+
};
300+
301+
struct s1_walk_filter {
302+
int (*fn)(struct s1_walk_context *, void *);
303+
void *priv;
304+
};
305+
288306
struct s1_walk_info {
307+
struct s1_walk_filter *filter;
289308
u64 baddr;
290309
enum trans_regime regime;
291310
unsigned int max_oa_bits;
292311
unsigned int pgshift;
293312
unsigned int txsz;
294313
int sl;
314+
u8 sh;
295315
bool as_el0;
296316
bool hpd;
297317
bool e0poe;
298318
bool poe;
299319
bool pan;
300320
bool be;
301321
bool s2;
322+
bool pa52bit;
302323
};
303324

304325
struct s1_walk_result {
@@ -334,6 +355,8 @@ struct s1_walk_result {
334355

335356
int __kvm_translate_va(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
336357
struct s1_walk_result *wr, u64 va);
358+
int __kvm_find_s1_desc_level(struct kvm_vcpu *vcpu, u64 va, u64 ipa,
359+
int *level);
337360

338361
/* VNCR management */
339362
int kvm_vcpu_allocate_vncr_tlb(struct kvm_vcpu *vcpu);

arch/arm64/include/asm/kvm_pkvm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
int pkvm_init_host_vm(struct kvm *kvm);
2020
int pkvm_create_hyp_vm(struct kvm *kvm);
21+
bool pkvm_hyp_vm_is_created(struct kvm *kvm);
2122
void pkvm_destroy_hyp_vm(struct kvm *kvm);
2223
int pkvm_create_hyp_vcpu(struct kvm_vcpu *vcpu);
2324

arch/arm64/include/asm/traps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ int kasan_brk_handler(struct pt_regs *regs, unsigned long esr);
3636
int ubsan_brk_handler(struct pt_regs *regs, unsigned long esr);
3737

3838
int early_brk64(unsigned long addr, unsigned long esr, struct pt_regs *regs);
39+
void dump_kernel_instr(unsigned long kaddr);
3940

4041
/*
4142
* Move regs->pc to next instruction and do necessary setup before it

arch/arm64/include/asm/vncr_mapping.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@
9494
#define VNCR_PMSICR_EL1 0x838
9595
#define VNCR_PMSIRR_EL1 0x840
9696
#define VNCR_PMSLATFR_EL1 0x848
97+
#define VNCR_PMSNEVFR_EL1 0x850
98+
#define VNCR_PMSDSFR_EL1 0x858
9799
#define VNCR_TRFCR_EL1 0x880
98100
#define VNCR_MPAM1_EL1 0x900
99101
#define VNCR_MPAMHCR_EL2 0x930

arch/arm64/kernel/cpufeature.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2539,6 +2539,15 @@ test_has_mpam_hcr(const struct arm64_cpu_capabilities *entry, int scope)
25392539
return idr & MPAMIDR_EL1_HAS_HCR;
25402540
}
25412541

2542+
static bool
2543+
test_has_gicv5_legacy(const struct arm64_cpu_capabilities *entry, int scope)
2544+
{
2545+
if (!this_cpu_has_cap(ARM64_HAS_GICV5_CPUIF))
2546+
return false;
2547+
2548+
return !!(read_sysreg_s(SYS_ICC_IDR0_EL1) & ICC_IDR0_EL1_GCIE_LEGACY);
2549+
}
2550+
25422551
static const struct arm64_cpu_capabilities arm64_features[] = {
25432552
{
25442553
.capability = ARM64_ALWAYS_BOOT,
@@ -3156,6 +3165,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
31563165
.matches = has_cpuid_feature,
31573166
ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, GCIE, IMP)
31583167
},
3168+
{
3169+
.desc = "GICv5 Legacy vCPU interface",
3170+
.type = ARM64_CPUCAP_EARLY_LOCAL_CPU_FEATURE,
3171+
.capability = ARM64_HAS_GICV5_LEGACY,
3172+
.matches = test_has_gicv5_legacy,
3173+
},
31593174
{},
31603175
};
31613176

arch/arm64/kernel/image-vars.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ KVM_NVHE_ALIAS(__hyp_stub_vectors);
105105
KVM_NVHE_ALIAS(vgic_v2_cpuif_trap);
106106
KVM_NVHE_ALIAS(vgic_v3_cpuif_trap);
107107

108+
/* Static key indicating whether GICv3 has GICv2 compatibility */
109+
KVM_NVHE_ALIAS(vgic_v3_has_v2_compat);
110+
108111
/* Static key which is set if CNTVOFF_EL2 is unusable */
109112
KVM_NVHE_ALIAS(broken_cntvoff_key);
110113

arch/arm64/kernel/traps.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,27 +149,26 @@ pstate_check_t * const aarch32_opcode_cond_checks[16] = {
149149

150150
int show_unhandled_signals = 0;
151151

152-
static void dump_kernel_instr(const char *lvl, struct pt_regs *regs)
152+
void dump_kernel_instr(unsigned long kaddr)
153153
{
154-
unsigned long addr = instruction_pointer(regs);
155154
char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
156155
int i;
157156

158-
if (user_mode(regs))
157+
if (!is_ttbr1_addr(kaddr))
159158
return;
160159

161160
for (i = -4; i < 1; i++) {
162161
unsigned int val, bad;
163162

164-
bad = aarch64_insn_read(&((u32 *)addr)[i], &val);
163+
bad = aarch64_insn_read(&((u32 *)kaddr)[i], &val);
165164

166165
if (!bad)
167166
p += sprintf(p, i == 0 ? "(%08x) " : "%08x ", val);
168167
else
169168
p += sprintf(p, i == 0 ? "(????????) " : "???????? ");
170169
}
171170

172-
printk("%sCode: %s\n", lvl, str);
171+
printk(KERN_EMERG "Code: %s\n", str);
173172
}
174173

175174
#define S_SMP " SMP"
@@ -178,6 +177,7 @@ static int __die(const char *str, long err, struct pt_regs *regs)
178177
{
179178
static int die_counter;
180179
int ret;
180+
unsigned long addr = instruction_pointer(regs);
181181

182182
pr_emerg("Internal error: %s: %016lx [#%d] " S_SMP "\n",
183183
str, err, ++die_counter);
@@ -190,7 +190,10 @@ static int __die(const char *str, long err, struct pt_regs *regs)
190190
print_modules();
191191
show_regs(regs);
192192

193-
dump_kernel_instr(KERN_EMERG, regs);
193+
if (user_mode(regs))
194+
return ret;
195+
196+
dump_kernel_instr(addr);
194197

195198
return ret;
196199
}

0 commit comments

Comments
 (0)