target/arm: Provide cpu property for controling FEAT_LPA2
There is a Linux kernel bug present until v5.12 that prevents booting with FEAT_LPA2 enabled. As a workaround for TCG, allow the feature to be disabled from -cpu max. Since this kernel bug is present in the Fedora 31 image that we test in avocado, disable lpa2 on the command-line. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
99eb313ddb
commit
69b2265d5f
@ -1392,6 +1392,12 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
|
|||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arm_cpu_lpa2_finalize(cpu, &local_err);
|
||||||
|
if (local_err != NULL) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kvm_enabled()) {
|
if (kvm_enabled()) {
|
||||||
|
@ -204,10 +204,12 @@ typedef struct {
|
|||||||
# define ARM_MAX_VQ 16
|
# define ARM_MAX_VQ 16
|
||||||
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
|
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
|
||||||
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
|
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
|
||||||
|
void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp);
|
||||||
#else
|
#else
|
||||||
# define ARM_MAX_VQ 1
|
# define ARM_MAX_VQ 1
|
||||||
static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { }
|
static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { }
|
||||||
static inline void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) { }
|
static inline void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) { }
|
||||||
|
static inline void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct ARMVectorReg {
|
typedef struct ARMVectorReg {
|
||||||
@ -975,10 +977,11 @@ struct ARMCPU {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Intermediate values used during property parsing.
|
* Intermediate values used during property parsing.
|
||||||
* Once finalized, the values should be read from ID_AA64ISAR1.
|
* Once finalized, the values should be read from ID_AA64*.
|
||||||
*/
|
*/
|
||||||
bool prop_pauth;
|
bool prop_pauth;
|
||||||
bool prop_pauth_impdef;
|
bool prop_pauth_impdef;
|
||||||
|
bool prop_lpa2;
|
||||||
|
|
||||||
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
|
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
|
||||||
uint32_t dcz_blocksize;
|
uint32_t dcz_blocksize;
|
||||||
|
@ -688,6 +688,29 @@ void aarch64_add_pauth_properties(Object *obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Property arm_cpu_lpa2_property =
|
||||||
|
DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
|
||||||
|
|
||||||
|
void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp)
|
||||||
|
{
|
||||||
|
uint64_t t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We only install the property for tcg -cpu max; this is the
|
||||||
|
* only situation in which the cpu field can be true.
|
||||||
|
*/
|
||||||
|
if (!cpu->prop_lpa2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = cpu->isar.id_aa64mmfr0;
|
||||||
|
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 2); /* 16k pages w/ LPA2 */
|
||||||
|
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4, 1); /* 4k pages w/ LPA2 */
|
||||||
|
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 3); /* 16k stage2 w/ LPA2 */
|
||||||
|
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 3); /* 4k stage2 w/ LPA2 */
|
||||||
|
cpu->isar.id_aa64mmfr0 = t;
|
||||||
|
}
|
||||||
|
|
||||||
static void aarch64_host_initfn(Object *obj)
|
static void aarch64_host_initfn(Object *obj)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_KVM)
|
#if defined(CONFIG_KVM)
|
||||||
@ -897,6 +920,7 @@ static void aarch64_max_initfn(Object *obj)
|
|||||||
aarch64_add_sve_properties(obj);
|
aarch64_add_sve_properties(obj);
|
||||||
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
|
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
|
||||||
cpu_max_set_sve_max_vq, NULL, NULL);
|
cpu_max_set_sve_max_vq, NULL, NULL);
|
||||||
|
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aarch64_a64fx_initfn(Object *obj)
|
static void aarch64_a64fx_initfn(Object *obj)
|
||||||
|
@ -79,6 +79,7 @@ class BootLinuxAarch64(LinuxTest):
|
|||||||
"""
|
"""
|
||||||
self.require_accelerator("tcg")
|
self.require_accelerator("tcg")
|
||||||
self.vm.add_args("-accel", "tcg")
|
self.vm.add_args("-accel", "tcg")
|
||||||
|
self.vm.add_args("-cpu", "max,lpa2=off")
|
||||||
self.vm.add_args("-machine", "virt,gic-version=2")
|
self.vm.add_args("-machine", "virt,gic-version=2")
|
||||||
self.add_common_args()
|
self.add_common_args()
|
||||||
self.launch_and_wait(set_up_ssh_connection=False)
|
self.launch_and_wait(set_up_ssh_connection=False)
|
||||||
@ -91,6 +92,7 @@ class BootLinuxAarch64(LinuxTest):
|
|||||||
"""
|
"""
|
||||||
self.require_accelerator("tcg")
|
self.require_accelerator("tcg")
|
||||||
self.vm.add_args("-accel", "tcg")
|
self.vm.add_args("-accel", "tcg")
|
||||||
|
self.vm.add_args("-cpu", "max,lpa2=off")
|
||||||
self.vm.add_args("-machine", "virt,gic-version=3")
|
self.vm.add_args("-machine", "virt,gic-version=3")
|
||||||
self.add_common_args()
|
self.add_common_args()
|
||||||
self.launch_and_wait(set_up_ssh_connection=False)
|
self.launch_and_wait(set_up_ssh_connection=False)
|
||||||
|
Loading…
Reference in New Issue
Block a user