KVM/arm64 fixes for 6.16, take #4

- Gracefully fail initialising pKVM if the interrupt controller isn't
   GICv3
 
 - Also gracefully fail initialising pKVM if the carveout allocation
   fails
 
 - Fix the computing of the minimum MMIO range required for the host on
   stage-2 fault
 
 - Fix the generation of the GICv3 Maintenance Interrupt in nested mode
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEn9UcU+C1Yxj9lZw9I9DQutE9ekMFAmhdY4cACgkQI9DQutE9
 ekOyqw//U0wxGtFhzro2bZPLCGfthRsnVsZQDODPiXhUCc2+92/X4Ek+UmWX4McH
 Pzgik16g3jq6h+PtwtIjkVucj52QdHS5XiVTai12udtsJMkwFSuWbaNDGW96Y2G9
 /msF6FCD82fCz5yYGJMbX69Dthim72O8TTTLMOjBRVvCJzy6NmBRQQTOhfgVNhoI
 p91kqx3V02NTIG+Gd03Xhg5QVzGTFEJ3BtGBJ8tlO+o0DIzHbP+0vHSdRmKcchz6
 u3zOYBAny3p8Qa2B92QrzLvNXq1bOnnB1a52D5ZDBa1vqDeLSRfFne9V6RTxRDeM
 IY1uoWVWHLHkSufzJu6hwteEKStA7FOeihnUAx4I0VllGT7Ce+mFcD/XrNdMYZHS
 L5kSWSkfqz0sbX3a1gPO0YpQCZ648lHJqu84VGIasL3uunHCJ5zmu75+G52GXASQ
 4hZgd0zlCx1ALvn4KhZhtV+YncrXOPfGXY83o+S3jECjeHR56zQ2XBANt8afjW09
 SpJO/UqwFubuLUZECV0tO4bKffIphkeJDYbrLCNdlT+RCSJa0sQ3eWLkZy7YpKr7
 EyzQbT8HfIX5sRxKNk0nTgTG0RPV6i2sI7BiUMQrR3hPs5H9Y4Ie3qL9m+FEAzQf
 XcrZl7b4xWXCFeQ0PJIOUs26hyiFYrNJvZ6ldcMIsk5keLnKWo4=
 =no8X
 -----END PGP SIGNATURE-----

Merge tag 'kvmarm-fixes-6.16-4' of https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD

KVM/arm64 fixes for 6.16, take #4

- Gracefully fail initialising pKVM if the interrupt controller isn't
  GICv3

- Also gracefully fail initialising pKVM if the carveout allocation
  fails

- Fix the computing of the minimum MMIO range required for the host on
  stage-2 fault

- Fix the generation of the GICv3 Maintenance Interrupt in nested mode
This commit is contained in:
Paolo Bonzini 2025-07-08 10:46:40 -04:00
commit 8aed168bf7
3 changed files with 23 additions and 13 deletions

View File

@ -2129,7 +2129,7 @@ static void cpu_hyp_init(void *discard)
static void cpu_hyp_uninit(void *discard)
{
if (__this_cpu_read(kvm_hyp_initialized)) {
if (!is_protected_kvm_enabled() && __this_cpu_read(kvm_hyp_initialized)) {
cpu_hyp_reset();
__this_cpu_write(kvm_hyp_initialized, 0);
}
@ -2345,8 +2345,13 @@ static void __init teardown_hyp_mode(void)
free_hyp_pgds();
for_each_possible_cpu(cpu) {
if (per_cpu(kvm_hyp_initialized, cpu))
continue;
free_pages(per_cpu(kvm_arm_hyp_stack_base, cpu), NVHE_STACK_SHIFT - PAGE_SHIFT);
free_pages(kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu], nvhe_percpu_order());
if (!kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu])
continue;
if (free_sve) {
struct cpu_sve_state *sve_state;
@ -2354,6 +2359,9 @@ static void __init teardown_hyp_mode(void)
sve_state = per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->sve_state;
free_pages((unsigned long) sve_state, pkvm_host_sve_state_order());
}
free_pages(kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu], nvhe_percpu_order());
}
}

View File

@ -479,6 +479,7 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
{
struct kvm_mem_range cur;
kvm_pte_t pte;
u64 granule;
s8 level;
int ret;
@ -496,18 +497,21 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
return -EPERM;
}
do {
u64 granule = kvm_granule_size(level);
for (; level <= KVM_PGTABLE_LAST_LEVEL; level++) {
if (!kvm_level_supports_block_mapping(level))
continue;
granule = kvm_granule_size(level);
cur.start = ALIGN_DOWN(addr, granule);
cur.end = cur.start + granule;
level++;
} while ((level <= KVM_PGTABLE_LAST_LEVEL) &&
!(kvm_level_supports_block_mapping(level) &&
range_included(&cur, range)));
if (!range_included(&cur, range))
continue;
*range = cur;
return 0;
}
*range = cur;
WARN_ON(1);
return 0;
return -EINVAL;
}
int host_stage2_idmap_locked(phys_addr_t addr, u64 size,

View File

@ -401,9 +401,7 @@ void vgic_v3_nested_update_mi(struct kvm_vcpu *vcpu)
{
bool level;
level = __vcpu_sys_reg(vcpu, ICH_HCR_EL2) & ICH_HCR_EL2_En;
if (level)
level &= vgic_v3_get_misr(vcpu);
level = (__vcpu_sys_reg(vcpu, ICH_HCR_EL2) & ICH_HCR_EL2_En) && vgic_v3_get_misr(vcpu);
kvm_vgic_inject_irq(vcpu->kvm, vcpu,
vcpu->kvm->arch.vgic.mi_intid, level, vcpu);
}