xen/arm: Expose SVE feature to the guest

When a guest is allowed to use SVE, expose the SVE features through
the identification registers.

Signed-off-by: Luca Fancellu <luca.fancellu@arm.com>
Acked-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
This commit is contained in:
Luca Fancellu authored and Julien Grall committed 2023-06-07 11:21:41 +01:00
1 parent 8043e80de9
commit c5ff38cdd8
1 file changed
+39 -2
+39 -2
View File
@@ -18,6 +18,8 @@
#include <xen/sched.h>
#include <asm/arm64/cpufeature.h>
#include <asm/arm64/sve.h>
#include <asm/current.h>
#include <asm/regs.h>
#include <asm/traps.h>
@@ -295,7 +297,28 @@ void do_sysreg(struct cpu_user_regs *regs,
GENERATE_TID3_INFO(MVFR0_EL1, mvfr, 0)
GENERATE_TID3_INFO(MVFR1_EL1, mvfr, 1)
GENERATE_TID3_INFO(MVFR2_EL1, mvfr, 2)
GENERATE_TID3_INFO(ID_AA64PFR0_EL1, pfr64, 0)
case HSR_SYSREG_ID_AA64PFR0_EL1:
{
register_t guest_reg_value = guest_cpuinfo.pfr64.bits[0];
if ( is_sve_domain(v->domain) )
{
/* 4 is the SVE field width in id_aa64pfr0_el1 */
uint64_t mask = GENMASK(ID_AA64PFR0_SVE_SHIFT + 4 - 1,
ID_AA64PFR0_SVE_SHIFT);
/* sysval is the sve field on the system */
uint64_t sysval = cpuid_feature_extract_unsigned_field_width(
system_cpuinfo.pfr64.bits[0],
ID_AA64PFR0_SVE_SHIFT, 4);
guest_reg_value &= ~mask;
guest_reg_value |= (sysval << ID_AA64PFR0_SVE_SHIFT) & mask;
}
return handle_ro_read_val(regs, regidx, hsr.sysreg.read, hsr, 1,
guest_reg_value);
}
GENERATE_TID3_INFO(ID_AA64PFR1_EL1, pfr64, 1)
GENERATE_TID3_INFO(ID_AA64DFR0_EL1, dbg64, 0)
GENERATE_TID3_INFO(ID_AA64DFR1_EL1, dbg64, 1)
@@ -306,7 +329,21 @@ void do_sysreg(struct cpu_user_regs *regs,
GENERATE_TID3_INFO(ID_AA64MMFR2_EL1, mm64, 2)
GENERATE_TID3_INFO(ID_AA64AFR0_EL1, aux64, 0)
GENERATE_TID3_INFO(ID_AA64AFR1_EL1, aux64, 1)
GENERATE_TID3_INFO(ID_AA64ZFR0_EL1, zfr64, 0)
case HSR_SYSREG_ID_AA64ZFR0_EL1:
{
/*
* When the guest has the SVE feature enabled, the whole id_aa64zfr0_el1
* needs to be exposed.
*/
register_t guest_reg_value = guest_cpuinfo.zfr64.bits[0];
if ( is_sve_domain(v->domain) )
guest_reg_value = system_cpuinfo.zfr64.bits[0];
return handle_ro_read_val(regs, regidx, hsr.sysreg.read, hsr, 1,
guest_reg_value);
}
/*
* Those cases are catching all Reserved registers trapped by TID3 which
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.