[PATCH v7 19/38] KVM: arm64: Add remaining ID registers to id_reg_desc_table
Reiji Watanabe
reijiw at google.com
Mon Apr 18 23:55:25 PDT 2022
Add hidden or reserved ID registers, and remaining ID registers,
which don't require special handling, to id_reg_desc_table.
Add 'flags' field to id_reg_desc, which is used to indicates hiddden
or reserved registers. Since now id_reg_desc_init() is called even
for hidden/reserved registers, change it to not do anything for them.
Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
arch/arm64/kvm/sys_regs.c | 84 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 82 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 9e090441057a..479208dedd79 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -331,6 +331,11 @@ struct id_reg_desc {
/* Fields that are not validated by arm64_check_features. */
u64 ignore_mask;
+ /* Miscellaneous flags */
+#define ID_DESC_REG_UNALLOC (1UL << 0)
+#define ID_DESC_REG_HIDDEN (1UL << 1)
+ u64 flags;
+
/* An optional initialization function of the id_reg_desc */
void (*init)(struct id_reg_desc *id_reg);
@@ -376,8 +381,13 @@ struct id_reg_desc {
static void id_reg_desc_init(struct id_reg_desc *id_reg)
{
u32 id = reg_to_encoding(&id_reg->reg_desc);
- u64 val = read_sanitised_ftr_reg(id);
+ u64 val;
+
+ if (id_reg->flags & (ID_DESC_REG_HIDDEN | ID_DESC_REG_UNALLOC))
+ /* Nothing to do for a hidden/unalloc ID register */
+ return;
+ val = read_sanitised_ftr_reg(id);
id_reg->vcpu_limit_val = val;
id_reg_desc_init_ftr(id_reg);
@@ -4192,33 +4202,103 @@ static struct id_reg_desc mvfr1_el1_desc = {
.validate = validate_mvfr1_el1,
};
+#define ID_DESC_DEFAULT(name) \
+ [IDREG_IDX(SYS_##name)] = &(struct id_reg_desc) { \
+ .reg_desc = ID_SANITISED(name), \
+ }
+
+#define ID_DESC_HIDDEN(name) \
+ [IDREG_IDX(SYS_##name)] = &(struct id_reg_desc) { \
+ .reg_desc = ID_HIDDEN(name), \
+ .flags = ID_DESC_REG_HIDDEN, \
+ }
+
+#define ID_DESC_UNALLOC(crm, op2) \
+ [(crm - 1) << 3 | op2] = &(struct id_reg_desc) { \
+ .reg_desc = ID_UNALLOCATED(crm, op2), \
+ .flags = ID_DESC_REG_UNALLOC, \
+ }
+
#define ID_DESC(id_reg_name, id_reg_desc) \
[IDREG_IDX(SYS_##id_reg_name)] = (id_reg_desc)
-/* A table for ID registers's information. */
+/*
+ * A table for ID registers's information.
+ * All entries in the table except ID_DESC_HIDDEN and ID_DESC_UNALLOC
+ * must have corresponding entries in arm64_ftr_regs[] in
+ * arch/arm64/kernel/cpufeature.c because read_sanitised_ftr_reg() is
+ * called for each of the ID registers.
+ */
static struct id_reg_desc *id_reg_desc_table[KVM_ARM_ID_REG_MAX_NUM] = {
/* CRm=1 */
+ ID_DESC_DEFAULT(ID_PFR0_EL1),
+ ID_DESC_DEFAULT(ID_PFR1_EL1),
ID_DESC(ID_DFR0_EL1, &id_dfr0_el1_desc),
+ ID_DESC_HIDDEN(ID_AFR0_EL1),
ID_DESC(ID_MMFR0_EL1, &id_mmfr0_el1_desc),
+ ID_DESC_DEFAULT(ID_MMFR1_EL1),
+ ID_DESC_DEFAULT(ID_MMFR2_EL1),
+ ID_DESC_DEFAULT(ID_MMFR3_EL1),
+
+ /* CRm=2 */
+ ID_DESC_DEFAULT(ID_ISAR0_EL1),
+ ID_DESC_DEFAULT(ID_ISAR1_EL1),
+ ID_DESC_DEFAULT(ID_ISAR2_EL1),
+ ID_DESC_DEFAULT(ID_ISAR3_EL1),
+ ID_DESC_DEFAULT(ID_ISAR4_EL1),
+ ID_DESC_DEFAULT(ID_ISAR5_EL1),
+ ID_DESC_DEFAULT(ID_MMFR4_EL1),
+ ID_DESC_DEFAULT(ID_ISAR6_EL1),
/* CRm=3 */
+ ID_DESC_DEFAULT(MVFR0_EL1),
ID_DESC(MVFR1_EL1, &mvfr1_el1_desc),
+ ID_DESC_DEFAULT(MVFR2_EL1),
+ ID_DESC_UNALLOC(3, 3),
+ ID_DESC_DEFAULT(ID_PFR2_EL1),
ID_DESC(ID_DFR1_EL1, &id_dfr1_el1_desc),
+ ID_DESC_DEFAULT(ID_MMFR5_EL1),
+ ID_DESC_UNALLOC(3, 7),
/* CRm=4 */
ID_DESC(ID_AA64PFR0_EL1, &id_aa64pfr0_el1_desc),
ID_DESC(ID_AA64PFR1_EL1, &id_aa64pfr1_el1_desc),
+ ID_DESC_UNALLOC(4, 2),
+ ID_DESC_UNALLOC(4, 3),
+ ID_DESC_DEFAULT(ID_AA64ZFR0_EL1),
+ ID_DESC_UNALLOC(4, 5),
+ ID_DESC_UNALLOC(4, 6),
+ ID_DESC_UNALLOC(4, 7),
/* CRm=5 */
ID_DESC(ID_AA64DFR0_EL1, &id_aa64dfr0_el1_desc),
+ ID_DESC_DEFAULT(ID_AA64DFR1_EL1),
+ ID_DESC_UNALLOC(5, 2),
+ ID_DESC_UNALLOC(5, 3),
+ ID_DESC_HIDDEN(ID_AA64AFR0_EL1),
+ ID_DESC_HIDDEN(ID_AA64AFR1_EL1),
+ ID_DESC_UNALLOC(5, 6),
+ ID_DESC_UNALLOC(5, 7),
/* CRm=6 */
ID_DESC(ID_AA64ISAR0_EL1, &id_aa64isar0_el1_desc),
ID_DESC(ID_AA64ISAR1_EL1, &id_aa64isar1_el1_desc),
ID_DESC(ID_AA64ISAR2_EL1, &id_aa64isar2_el1_desc),
+ ID_DESC_UNALLOC(6, 3),
+ ID_DESC_UNALLOC(6, 4),
+ ID_DESC_UNALLOC(6, 5),
+ ID_DESC_UNALLOC(6, 6),
+ ID_DESC_UNALLOC(6, 7),
/* CRm=7 */
ID_DESC(ID_AA64MMFR0_EL1, &id_aa64mmfr0_el1_desc),
+ ID_DESC_DEFAULT(ID_AA64MMFR1_EL1),
+ ID_DESC_DEFAULT(ID_AA64MMFR2_EL1),
+ ID_DESC_UNALLOC(7, 3),
+ ID_DESC_UNALLOC(7, 4),
+ ID_DESC_UNALLOC(7, 5),
+ ID_DESC_UNALLOC(7, 6),
+ ID_DESC_UNALLOC(7, 7),
};
static inline struct id_reg_desc *get_id_reg_desc(u32 id)
--
2.36.0.rc0.470.gd361397f0d-goog
More information about the linux-arm-kernel
mailing list