[PATCH v4 08/22] KVM: arm64: ITS: Implement vgic_mmio_uaccess_write_its_iidr

Eric Auger eric.auger at redhat.com
Mon Mar 27 02:30:58 PDT 2017


The GITS_IIDR revision field is used to encode the version of the
table layout (ABI). So we need to restore it to check the table
layout to be restored is compatible with the destination vITS.

The user selected revision is stored in the user_revision field.
It will be compared against the REV num at table restoration time.

Signed-off-by: Eric Auger <eric.auger at redhat.com>

---

v4: creation
---
 include/kvm/arm_vgic.h       |  2 ++
 virt/kvm/arm/vgic/vgic-its.c | 24 +++++++++++++++++++++---
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index b72dd2a..41b71ca 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -162,6 +162,8 @@ struct vgic_its {
 	u32			creadr;
 	u32			cwriter;
 
+	u32			user_revision;
+
 	/* Protects the device and collection lists */
 	struct mutex		its_lock;
 	struct list_head	device_list;
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index a5f3abe..169b486 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -33,6 +33,9 @@
 #include "vgic.h"
 #include "vgic-mmio.h"
 
+/* ITS Table Layout ABI Revision */
+#define REV 0x1
+
 /*
  * Creates a new (reference to a) struct vgic_irq for a given LPI.
  * If this LPI is already mapped on another ITS, we increase its refcount
@@ -384,7 +387,19 @@ static unsigned long vgic_mmio_read_its_iidr(struct kvm *kvm,
 					     struct vgic_its *its,
 					     gpa_t addr, unsigned int len)
 {
-	return (PRODUCT_ID_KVM << 24) | (IMPLEMENTER_ARM << 0);
+	return (PRODUCT_ID_KVM << 24) | (REV << 12) | IMPLEMENTER_ARM;
+}
+
+static void vgic_mmio_uaccess_write_its_iidr(struct kvm *kvm,
+					     struct vgic_its *its,
+					     gpa_t addr, unsigned int len,
+					     unsigned long val)
+{
+	u64 tmp = 0;
+
+	tmp = update_64bit_reg(tmp, addr & 3, len, val);
+	tmp = (tmp & GENMASK(15, 12)) >> 12;
+	its->user_revision = tmp;
 }
 
 static unsigned long vgic_mmio_read_its_idregs(struct kvm *kvm,
@@ -1359,8 +1374,9 @@ static struct vgic_register_region its_registers[] = {
 	REGISTER_ITS_DESC(GITS_CTLR,
 		vgic_mmio_read_its_ctlr, vgic_mmio_write_its_ctlr, 4,
 		VGIC_ACCESS_32bit),
-	REGISTER_ITS_DESC(GITS_IIDR,
-		vgic_mmio_read_its_iidr, its_mmio_write_wi, 4,
+	REGISTER_ITS_DESC_UACCESS(GITS_IIDR,
+		vgic_mmio_read_its_iidr, its_mmio_write_wi,
+		vgic_mmio_uaccess_write_its_iidr, 4,
 		VGIC_ACCESS_32bit),
 	REGISTER_ITS_DESC(GITS_TYPER,
 		vgic_mmio_read_its_typer, its_mmio_write_wi, 8,
@@ -1458,6 +1474,8 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
 		((u64)GITS_BASER_TYPE_COLLECTION << GITS_BASER_TYPE_SHIFT);
 	dev->kvm->arch.vgic.propbaser = INITIAL_PROPBASER_VALUE;
 
+	its->user_revision = 0;
+
 	dev->private = its;
 
 	return 0;
-- 
2.5.5




More information about the linux-arm-kernel mailing list