[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-arm] [PATCH RFC 2/7] ARM64: KVM: Add reset handlers for all ID reg
From: |
Shannon Zhao |
Subject: |
[Qemu-arm] [PATCH RFC 2/7] ARM64: KVM: Add reset handlers for all ID registers |
Date: |
Mon, 16 Jan 2017 17:33:29 +0800 |
From: Shannon Zhao <address@hidden>
Move invariant_sys_regs before emulate_sys_reg so that it can be used
later.
Signed-off-by: Shannon Zhao <address@hidden>
---
arch/arm64/kvm/sys_regs.c | 193 ++++++++++++++++++++++++++++------------------
1 file changed, 116 insertions(+), 77 deletions(-)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 87e7e66..bf71eb4 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1432,6 +1432,122 @@ static const struct sys_reg_desc cp15_64_regs[] = {
{ Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR1 },
};
+/*
+ * These are the invariant sys_reg registers: we let the guest see the
+ * host versions of these, so they're part of the guest state.
+ *
+ * A future CPU may provide a mechanism to present different values to
+ * the guest, or a future kvm may trap them.
+ */
+
+#define FUNCTION_INVARIANT(reg)
\
+ static void get_##reg(struct kvm_vcpu *v, \
+ const struct sys_reg_desc *r) \
+ { \
+ ((struct sys_reg_desc *)r)->val = read_sysreg(reg); \
+ }
+
+FUNCTION_INVARIANT(midr_el1)
+FUNCTION_INVARIANT(ctr_el0)
+FUNCTION_INVARIANT(revidr_el1)
+FUNCTION_INVARIANT(id_pfr0_el1)
+FUNCTION_INVARIANT(id_pfr1_el1)
+FUNCTION_INVARIANT(id_dfr0_el1)
+FUNCTION_INVARIANT(id_afr0_el1)
+FUNCTION_INVARIANT(id_mmfr0_el1)
+FUNCTION_INVARIANT(id_mmfr1_el1)
+FUNCTION_INVARIANT(id_mmfr2_el1)
+FUNCTION_INVARIANT(id_mmfr3_el1)
+FUNCTION_INVARIANT(id_isar0_el1)
+FUNCTION_INVARIANT(id_isar1_el1)
+FUNCTION_INVARIANT(id_isar2_el1)
+FUNCTION_INVARIANT(id_isar3_el1)
+FUNCTION_INVARIANT(id_isar4_el1)
+FUNCTION_INVARIANT(id_isar5_el1)
+FUNCTION_INVARIANT(mvfr0_el1)
+FUNCTION_INVARIANT(mvfr1_el1)
+FUNCTION_INVARIANT(mvfr2_el1)
+FUNCTION_INVARIANT(id_aa64pfr0_el1)
+FUNCTION_INVARIANT(id_aa64pfr1_el1)
+FUNCTION_INVARIANT(id_aa64dfr0_el1)
+FUNCTION_INVARIANT(id_aa64dfr1_el1)
+FUNCTION_INVARIANT(id_aa64afr0_el1)
+FUNCTION_INVARIANT(id_aa64afr1_el1)
+FUNCTION_INVARIANT(id_aa64isar0_el1)
+FUNCTION_INVARIANT(id_aa64isar1_el1)
+FUNCTION_INVARIANT(id_aa64mmfr0_el1)
+FUNCTION_INVARIANT(id_aa64mmfr1_el1)
+FUNCTION_INVARIANT(clidr_el1)
+FUNCTION_INVARIANT(aidr_el1)
+
+/* ->val is filled in by kvm_sys_reg_table_init() */
+static struct sys_reg_desc invariant_sys_regs[] = {
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0000), Op2(0b000),
+ NULL, get_midr_el1, MIDR_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0000), Op2(0b110),
+ NULL, get_revidr_el1, REVIDR_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b000),
+ NULL, get_id_pfr0_el1, ID_PFR0_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b001),
+ NULL, get_id_pfr1_el1, ID_PFR1_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b010),
+ NULL, get_id_dfr0_el1, ID_DFR0_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b011),
+ NULL, get_id_afr0_el1, ID_AFR0_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b100),
+ NULL, get_id_mmfr0_el1, ID_MMFR0_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b101),
+ NULL, get_id_mmfr1_el1, ID_MMFR1_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b110),
+ NULL, get_id_mmfr2_el1, ID_MMFR2_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b111),
+ NULL, get_id_mmfr3_el1, ID_MMFR3_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b000),
+ NULL, get_id_isar0_el1, ID_ISAR0_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b001),
+ NULL, get_id_isar1_el1, ID_ISAR1_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b010),
+ NULL, get_id_isar2_el1, ID_ISAR2_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b011),
+ NULL, get_id_isar3_el1, ID_ISAR3_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b100),
+ NULL, get_id_isar4_el1, ID_ISAR4_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b101),
+ NULL, get_id_isar5_el1, ID_ISAR5_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0011), Op2(0b000),
+ NULL, get_mvfr0_el1, MVFR0_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0011), Op2(0b001),
+ NULL, get_mvfr1_el1, MVFR1_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0011), Op2(0b010),
+ NULL, get_mvfr2_el1, MVFR2_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0100), Op2(0b000),
+ NULL, get_id_aa64pfr0_el1, ID_AA64PFR0_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0100), Op2(0b001),
+ NULL, get_id_aa64pfr1_el1, ID_AA64PFR1_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0101), Op2(0b000),
+ NULL, get_id_aa64dfr0_el1, ID_AA64DFR0_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0101), Op2(0b001),
+ NULL, get_id_aa64dfr1_el1, ID_AA64DFR1_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0101), Op2(0b100),
+ NULL, get_id_aa64afr0_el1, ID_AA64AFR0_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0101), Op2(0b101),
+ NULL, get_id_aa64afr1_el1, ID_AA64AFR1_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0110), Op2(0b000),
+ NULL, get_id_aa64isar0_el1, ID_AA64ISAR0_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0110), Op2(0b001),
+ NULL, get_id_aa64isar1_el1, ID_AA64ISAR1_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0111), Op2(0b000),
+ NULL, get_id_aa64mmfr0_el1, ID_AA64MMFR0_EL1 },
+ { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0111), Op2(0b001),
+ NULL, get_id_aa64mmfr1_el1, ID_AA64MMFR1_EL1 },
+ { Op0(0b11), Op1(0b001), CRn(0b0000), CRm(0b0000), Op2(0b001),
+ NULL, get_clidr_el1, CLIDR_EL1 },
+ { Op0(0b11), Op1(0b001), CRn(0b0000), CRm(0b0000), Op2(0b111),
+ NULL, get_aidr_el1, AIDR_EL1 },
+ { Op0(0b11), Op1(0b011), CRn(0b0000), CRm(0b0000), Op2(0b001),
+ NULL, get_ctr_el0, CTR_EL0 },
+};
+
/* Target specific emulation tables */
static struct kvm_sys_reg_target_table *target_tables[KVM_ARM_NUM_TARGETS];
@@ -1822,83 +1938,6 @@ static const struct sys_reg_desc
*index_to_sys_reg_desc(struct kvm_vcpu *vcpu,
return r;
}
-/*
- * These are the invariant sys_reg registers: we let the guest see the
- * host versions of these, so they're part of the guest state.
- *
- * A future CPU may provide a mechanism to present different values to
- * the guest, or a future kvm may trap them.
- */
-
-#define FUNCTION_INVARIANT(reg)
\
- static void get_##reg(struct kvm_vcpu *v, \
- const struct sys_reg_desc *r) \
- { \
- ((struct sys_reg_desc *)r)->val = read_sysreg(reg); \
- }
-
-FUNCTION_INVARIANT(midr_el1)
-FUNCTION_INVARIANT(ctr_el0)
-FUNCTION_INVARIANT(revidr_el1)
-FUNCTION_INVARIANT(id_pfr0_el1)
-FUNCTION_INVARIANT(id_pfr1_el1)
-FUNCTION_INVARIANT(id_dfr0_el1)
-FUNCTION_INVARIANT(id_afr0_el1)
-FUNCTION_INVARIANT(id_mmfr0_el1)
-FUNCTION_INVARIANT(id_mmfr1_el1)
-FUNCTION_INVARIANT(id_mmfr2_el1)
-FUNCTION_INVARIANT(id_mmfr3_el1)
-FUNCTION_INVARIANT(id_isar0_el1)
-FUNCTION_INVARIANT(id_isar1_el1)
-FUNCTION_INVARIANT(id_isar2_el1)
-FUNCTION_INVARIANT(id_isar3_el1)
-FUNCTION_INVARIANT(id_isar4_el1)
-FUNCTION_INVARIANT(id_isar5_el1)
-FUNCTION_INVARIANT(clidr_el1)
-FUNCTION_INVARIANT(aidr_el1)
-
-/* ->val is filled in by kvm_sys_reg_table_init() */
-static struct sys_reg_desc invariant_sys_regs[] = {
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0000), Op2(0b000),
- NULL, get_midr_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0000), Op2(0b110),
- NULL, get_revidr_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b000),
- NULL, get_id_pfr0_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b001),
- NULL, get_id_pfr1_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b010),
- NULL, get_id_dfr0_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b011),
- NULL, get_id_afr0_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b100),
- NULL, get_id_mmfr0_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b101),
- NULL, get_id_mmfr1_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b110),
- NULL, get_id_mmfr2_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b111),
- NULL, get_id_mmfr3_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b000),
- NULL, get_id_isar0_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b001),
- NULL, get_id_isar1_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b010),
- NULL, get_id_isar2_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b011),
- NULL, get_id_isar3_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b100),
- NULL, get_id_isar4_el1 },
- { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b101),
- NULL, get_id_isar5_el1 },
- { Op0(0b11), Op1(0b001), CRn(0b0000), CRm(0b0000), Op2(0b001),
- NULL, get_clidr_el1 },
- { Op0(0b11), Op1(0b001), CRn(0b0000), CRm(0b0000), Op2(0b111),
- NULL, get_aidr_el1 },
- { Op0(0b11), Op1(0b011), CRn(0b0000), CRm(0b0000), Op2(0b001),
- NULL, get_ctr_el0 },
-};
-
static int reg_from_user(u64 *val, const void __user *uaddr, u64 id)
{
if (copy_from_user(val, uaddr, KVM_REG_SIZE(id)) != 0)
--
2.0.4
- [Qemu-arm] [PATCH RFC 0/7] ARM64: KVM: Cross type vCPU support, Shannon Zhao, 2017/01/16
- [Qemu-arm] [PATCH RFC 7/7] ARM64: KVM: Add user set handler for id_aa64mmfr0_el1, Shannon Zhao, 2017/01/16
- [Qemu-arm] [PATCH RFC 4/7] ARM64: KVM: emulate accessing ID registers, Shannon Zhao, 2017/01/16
- [Qemu-arm] [PATCH RFC 5/7] ARM64: KVM: Support cross type vCPU, Shannon Zhao, 2017/01/16
- [Qemu-arm] [PATCH RFC 2/7] ARM64: KVM: Add reset handlers for all ID registers,
Shannon Zhao <=
- [Qemu-arm] [PATCH RFC 6/7] ARM64: KVM: Support heterogeneous system, Shannon Zhao, 2017/01/16
- [Qemu-arm] [PATCH RFC 1/7] ARM64: KVM: Add the definition of ID registers, Shannon Zhao, 2017/01/16
- [Qemu-arm] [PATCH RFC 3/7] ARM64: KVM: Reset ID registers when creating the VCPUs, Shannon Zhao, 2017/01/16