mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/arm: Taint Xen on incompatible DCZID values
Use arm64 cpu feature sanitization to TAINT Xen if different DCZID values are found (ftr_dczid is using only STRICT method). In this case actual memory being cleaned by DC ZVA operations would be different depending on the cores which could make a guest zeroing too much or too little memory if it is merged between CPUs. We could, on processors supporting it, trap access to DCZID_EL0 register using HFGRTR_EL2 register but this would not solve the case where a process is being migrated during a copy or if it cached the value of the register. Signed-off-by: Bertrand Marquis <bertrand.marquis@arm.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
This commit is contained in:
1 parent
442d54c445
commit
ef17eb9d3a
3 files changed
+21
-3
No files matched your search
@@ -329,14 +329,11 @@ static const struct arm64_ftr_bits ftr_mvfr2[] = {
|
||||
ARM64_FTR_END,
|
||||
};
|
||||
|
||||
#if 0
|
||||
/* TODO: handle this when sanitizing cache related registers */
|
||||
static const struct arm64_ftr_bits ftr_dczid[] = {
|
||||
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, DCZID_DZP_SHIFT, 1, 1),
|
||||
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, DCZID_BS_SHIFT, 4, 0),
|
||||
ARM64_FTR_END,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct arm64_ftr_bits ftr_id_isar0[] = {
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR0_DIVIDE_SHIFT, 4, 0),
|
||||
@@ -598,6 +595,17 @@ void update_system_features(const struct cpuinfo_arm *new)
|
||||
|
||||
SANITIZE_ID_REG(zfr64, 0, aa64zfr0);
|
||||
|
||||
/*
|
||||
* Comment from Linux:
|
||||
* Userspace may perform DC ZVA instructions. Mismatched block sizes
|
||||
* could result in too much or too little memory being zeroed if a
|
||||
* process is preempted and migrated between CPUs.
|
||||
*
|
||||
* ftr_dczid is using STRICT comparison so we will taint Xen if different
|
||||
* values are found.
|
||||
*/
|
||||
SANITIZE_REG(dczid, 0, dczid);
|
||||
|
||||
if ( cpu_feature64_has_el0_32(&system_cpuinfo) )
|
||||
{
|
||||
SANITIZE_ID_REG(pfr32, 0, pfr0);
|
||||
|
||||
@@ -125,6 +125,8 @@ void identify_cpu(struct cpuinfo_arm *c)
|
||||
|
||||
c->zfr64.bits[0] = READ_SYSREG(ID_AA64ZFR0_EL1);
|
||||
|
||||
c->dczid.bits[0] = READ_SYSREG(DCZID_EL0);
|
||||
|
||||
aarch32_el0 = cpu_feature64_has_el0_32(c);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -259,6 +259,14 @@ struct cpuinfo_arm {
|
||||
register_t bits[1];
|
||||
} zfr64;
|
||||
|
||||
/*
|
||||
* DCZID is only used to check for incoherent values between cores
|
||||
* and taint Xen in this case
|
||||
*/
|
||||
struct {
|
||||
register_t bits[1];
|
||||
} dczid;
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||