mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2026-01-27 12:47:24 +01:00
Merge branch kvm-arm64/gic-v5-nv into kvmarm-master/next
* kvm-arm64/gic-v5-nv: : . : Add NV support to GICv5 in GICv3 emulation mode, ensuring that the v3 : guest support is identical to that of a pure v3 platform. : : Patches courtesy of Sascha Bischoff (20250828105925.3865158-1-sascha.bischoff@arm.com) : . irqchip/gic-v5: Drop has_gcie_v3_compat from gic_kvm_info KVM: arm64: Use ARM64_HAS_GICV5_LEGACY for GICv5 probing arm64: cpucaps: Add GICv5 Legacy vCPU interface (GCIE_LEGACY) capability KVM: arm64: Enable nested for GICv5 host with FEAT_GCIE_LEGACY KVM: arm64: Don't access ICC_SRE_EL2 if GICv3 doesn't support v2 compatibility Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
commit
d9476fd356
|
|
@ -2539,6 +2539,15 @@ test_has_mpam_hcr(const struct arm64_cpu_capabilities *entry, int scope)
|
|||
return idr & MPAMIDR_EL1_HAS_HCR;
|
||||
}
|
||||
|
||||
static bool
|
||||
test_has_gicv5_legacy(const struct arm64_cpu_capabilities *entry, int scope)
|
||||
{
|
||||
if (!this_cpu_has_cap(ARM64_HAS_GICV5_CPUIF))
|
||||
return false;
|
||||
|
||||
return !!(read_sysreg_s(SYS_ICC_IDR0_EL1) & ICC_IDR0_EL1_GCIE_LEGACY);
|
||||
}
|
||||
|
||||
static const struct arm64_cpu_capabilities arm64_features[] = {
|
||||
{
|
||||
.capability = ARM64_ALWAYS_BOOT,
|
||||
|
|
@ -3156,6 +3165,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
|
|||
.matches = has_cpuid_feature,
|
||||
ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, GCIE, IMP)
|
||||
},
|
||||
{
|
||||
.desc = "GICv5 Legacy vCPU interface",
|
||||
.type = ARM64_CPUCAP_EARLY_LOCAL_CPU_FEATURE,
|
||||
.capability = ARM64_HAS_GICV5_LEGACY,
|
||||
.matches = test_has_gicv5_legacy,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,9 @@ KVM_NVHE_ALIAS(__hyp_stub_vectors);
|
|||
KVM_NVHE_ALIAS(vgic_v2_cpuif_trap);
|
||||
KVM_NVHE_ALIAS(vgic_v3_cpuif_trap);
|
||||
|
||||
/* Static key indicating whether GICv3 has GICv2 compatibility */
|
||||
KVM_NVHE_ALIAS(vgic_v3_has_v2_compat);
|
||||
|
||||
/* Static key which is set if CNTVOFF_EL2 is unusable */
|
||||
KVM_NVHE_ALIAS(broken_cntvoff_key);
|
||||
|
||||
|
|
|
|||
|
|
@ -2321,8 +2321,9 @@ static int __init init_subsystems(void)
|
|||
}
|
||||
|
||||
if (kvm_mode == KVM_MODE_NV &&
|
||||
!(vgic_present && kvm_vgic_global_state.type == VGIC_V3)) {
|
||||
kvm_err("NV support requires GICv3, giving up\n");
|
||||
!(vgic_present && (kvm_vgic_global_state.type == VGIC_V3 ||
|
||||
kvm_vgic_global_state.has_gcie_v3_compat))) {
|
||||
kvm_err("NV support requires GICv3 or GICv5 with legacy support, giving up\n");
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -295,12 +295,8 @@ void __vgic_v3_activate_traps(struct vgic_v3_cpu_if *cpu_if)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GICv5 BET0 FEAT_GCIE_LEGACY doesn't include ICC_SRE_EL2. This is due
|
||||
* to be relaxed in a future spec release, at which point this in
|
||||
* condition can be dropped.
|
||||
*/
|
||||
if (!cpus_have_final_cap(ARM64_HAS_GICV5_CPUIF)) {
|
||||
/* Only disable SRE if the host implements the GICv2 interface */
|
||||
if (static_branch_unlikely(&vgic_v3_has_v2_compat)) {
|
||||
/*
|
||||
* Prevent the guest from touching the ICC_SRE_EL1 system
|
||||
* register. Note that this may not have any effect, as
|
||||
|
|
@ -329,19 +325,16 @@ void __vgic_v3_deactivate_traps(struct vgic_v3_cpu_if *cpu_if)
|
|||
cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can be dropped in the future when GICv5 spec is relaxed. See comment
|
||||
* above.
|
||||
*/
|
||||
if (!cpus_have_final_cap(ARM64_HAS_GICV5_CPUIF)) {
|
||||
/* Only restore SRE if the host implements the GICv2 interface */
|
||||
if (static_branch_unlikely(&vgic_v3_has_v2_compat)) {
|
||||
val = read_gicreg(ICC_SRE_EL2);
|
||||
write_gicreg(val | ICC_SRE_EL2_ENABLE, ICC_SRE_EL2);
|
||||
}
|
||||
|
||||
if (!cpu_if->vgic_sre) {
|
||||
/* Make sure ENABLE is set at EL2 before setting SRE at EL1 */
|
||||
isb();
|
||||
write_gicreg(1, ICC_SRE_EL1);
|
||||
if (!cpu_if->vgic_sre) {
|
||||
/* Make sure ENABLE is set at EL2 before setting SRE at EL1 */
|
||||
isb();
|
||||
write_gicreg(1, ICC_SRE_EL1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -588,6 +588,7 @@ int vgic_v3_map_resources(struct kvm *kvm)
|
|||
}
|
||||
|
||||
DEFINE_STATIC_KEY_FALSE(vgic_v3_cpuif_trap);
|
||||
DEFINE_STATIC_KEY_FALSE(vgic_v3_has_v2_compat);
|
||||
|
||||
static int __init early_group0_trap_cfg(char *buf)
|
||||
{
|
||||
|
|
@ -697,6 +698,13 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
|
|||
if (kvm_vgic_global_state.vcpu_base == 0)
|
||||
kvm_info("disabling GICv2 emulation\n");
|
||||
|
||||
/*
|
||||
* Flip the static branch if the HW supports v2, even if we're
|
||||
* not using it (such as in protected mode).
|
||||
*/
|
||||
if (has_v2)
|
||||
static_branch_enable(&vgic_v3_has_v2_compat);
|
||||
|
||||
if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_30115)) {
|
||||
group0_trap = true;
|
||||
group1_trap = true;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ int vgic_v5_probe(const struct gic_kvm_info *info)
|
|||
u64 ich_vtr_el2;
|
||||
int ret;
|
||||
|
||||
if (!info->has_gcie_v3_compat)
|
||||
if (!cpus_have_final_cap(ARM64_HAS_GICV5_LEGACY))
|
||||
return -ENODEV;
|
||||
|
||||
kvm_vgic_global_state.type = VGIC_V5;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ HAS_GENERIC_AUTH_ARCH_QARMA5
|
|||
HAS_GENERIC_AUTH_IMP_DEF
|
||||
HAS_GICV3_CPUIF
|
||||
HAS_GICV5_CPUIF
|
||||
HAS_GICV5_LEGACY
|
||||
HAS_GIC_PRIO_MASKING
|
||||
HAS_GIC_PRIO_RELAXED_SYNC
|
||||
HAS_HCR_NV1
|
||||
|
|
|
|||
|
|
@ -1062,16 +1062,9 @@ static void gicv5_set_cpuif_idbits(void)
|
|||
#ifdef CONFIG_KVM
|
||||
static struct gic_kvm_info gic_v5_kvm_info __initdata;
|
||||
|
||||
static bool __init gicv5_cpuif_has_gcie_legacy(void)
|
||||
{
|
||||
u64 idr0 = read_sysreg_s(SYS_ICC_IDR0_EL1);
|
||||
return !!FIELD_GET(ICC_IDR0_EL1_GCIE_LEGACY, idr0);
|
||||
}
|
||||
|
||||
static void __init gic_of_setup_kvm_info(struct device_node *node)
|
||||
{
|
||||
gic_v5_kvm_info.type = GIC_V5;
|
||||
gic_v5_kvm_info.has_gcie_v3_compat = gicv5_cpuif_has_gcie_legacy();
|
||||
|
||||
/* GIC Virtual CPU interface maintenance interrupt */
|
||||
gic_v5_kvm_info.no_maint_irq_mask = false;
|
||||
|
|
|
|||
|
|
@ -375,6 +375,7 @@ struct vgic_cpu {
|
|||
|
||||
extern struct static_key_false vgic_v2_cpuif_trap;
|
||||
extern struct static_key_false vgic_v3_cpuif_trap;
|
||||
extern struct static_key_false vgic_v3_has_v2_compat;
|
||||
|
||||
int kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev_addr);
|
||||
void kvm_vgic_early_init(struct kvm *kvm);
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ struct gic_kvm_info {
|
|||
bool has_v4_1;
|
||||
/* Deactivation impared, subpar stuff */
|
||||
bool no_hw_deactivation;
|
||||
/* v3 compat support (GICv5 hosts, only) */
|
||||
bool has_gcie_v3_compat;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_KVM
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user