Re: [PATCH 07/13] KVM: arm64: implement basic ITS register handlers
On Fri, May 29, 2015 at 10:53:23AM +0100, Andre Przywara wrote: > Add emulation for some basic MMIO registers used in the ITS emulation. > This includes: > - GITS_{CTLR,TYPER,IIDR} > - ID registers > - GITS_{CBASER,CREAD,CWRITER} > those implement the ITS command buffer handling > > Signed-off-by: Andre Przywara > --- > include/kvm/arm_vgic.h | 3 + > include/linux/irqchip/arm-gic-v3.h | 8 ++ > virt/kvm/arm/its-emul.c| 172 > + > virt/kvm/arm/its-emul.h| 1 + > virt/kvm/arm/vgic-v3-emul.c| 2 + > 5 files changed, 186 insertions(+) > > diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h > index d76c2d9..3b8e3a1 100644 > --- a/include/kvm/arm_vgic.h > +++ b/include/kvm/arm_vgic.h > @@ -159,6 +159,9 @@ struct vgic_io_device { > struct vgic_its { > boolenabled; > spinlock_t lock; > + u64 cbaser; > + int creadr; > + int cwriter; > }; > > struct vgic_dist { > diff --git a/include/linux/irqchip/arm-gic-v3.h > b/include/linux/irqchip/arm-gic-v3.h > index df4e527..0b450c7 100644 > --- a/include/linux/irqchip/arm-gic-v3.h > +++ b/include/linux/irqchip/arm-gic-v3.h > @@ -179,15 +179,23 @@ > #define GITS_BASER 0x0100 > #define GITS_IDREGS_BASE 0xffd0 > #define GITS_PIDR2 GICR_PIDR2 > +#define GITS_PIDR4 0xffd0 > +#define GITS_CIDR0 0xfff0 > +#define GITS_CIDR1 0xfff4 > +#define GITS_CIDR2 0xfff8 > +#define GITS_CIDR3 0xfffc > > #define GITS_TRANSLATER 0x10040 > > #define GITS_CTLR_ENABLE (1U << 0) > #define GITS_CTLR_QUIESCENT (1U << 31) > > +#define GITS_TYPER_PLPIS (1UL << 0) > +#define GITS_TYPER_IDBITS_SHIFT 8 > #define GITS_TYPER_DEVBITS_SHIFT 13 > #define GITS_TYPER_DEVBITS(r)r) >> > GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1) > #define GITS_TYPER_PTA (1UL << 19) > +#define GITS_TYPER_HWCOLLCNT_SHIFT 24 > > #define GITS_CBASER_VALID(1UL << 63) > #define GITS_CBASER_nCnB (0UL << 59) > diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c > index 7b283ce..82bc34a 100644 > --- a/virt/kvm/arm/its-emul.c > +++ b/virt/kvm/arm/its-emul.c > @@ -32,10 +32,62 @@ > #include "vgic.h" > #include "its-emul.h" > > +#define BASER_BASE_ADDRESS(x) ((x) & 0xf000ULL) > + > +/* distributor lock is hold by the VGIC MMIO handler */ > static bool handle_mmio_misc_gits(struct kvm_vcpu *vcpu, > struct kvm_exit_mmio *mmio, > phys_addr_t offset) > { > + struct vgic_its *its = &vcpu->kvm->arch.vgic.its; > + u32 reg; > + bool was_enabled; > + > + switch (offset & ~3) { > + case 0x00: /* GITS_CTLR */ > + /* We never defer any command execution. */ > + reg = GITS_CTLR_QUIESCENT; > + if (its->enabled) > + reg |= GITS_CTLR_ENABLE; > + was_enabled = its->enabled; > + vgic_reg_access(mmio, ®, offset & 3, > + ACCESS_READ_VALUE | ACCESS_WRITE_VALUE); > + its->enabled = !!(reg & GITS_CTLR_ENABLE); > + return !was_enabled && its->enabled; > + case 0x04: /* GITS_IIDR */ > + reg = (PRODUCT_ID_KVM << 24) | (IMPLEMENTER_ARM << 0); > + vgic_reg_access(mmio, ®, offset & 3, > + ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED); > + break; > + case 0x08: /* GITS_TYPER */ > + /* > + * We use linear CPU numbers for redistributor addressing, > + * so GITS_TYPER.PTA is 0. > + * To avoid memory waste on the guest side, we keep the > + * number of IDBits and DevBits low for the time being. > + * This could later be made configurable by userland. > + * Since we have all collections in linked list, we claim > + * that we can hold all of the collection tables in our > + * own memory and that the ITT entry size is 1 byte (the > + * smallest possible one). > + */ > + reg = GITS_TYPER_PLPIS; > + reg |= 0xff << GITS_TYPER_HWCOLLCNT_SHIFT; > + reg |= 0x0f << GITS_TYPER_DEVBITS_SHIFT; > + reg |= 0x0f << GITS_TYPER_IDBITS_SHIFT; > + vgic_reg_access(mmio, ®, offset & 3, > + ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED); > + break; > + case 0x0c: > + /* The upper 32bits of TYPER are all 0 for the time being. > + * Should we need more than 256 collections, we can enable
Re: [PATCH 07/13] KVM: arm64: implement basic ITS register handlers
Reviewed-by: Eric Auger On 05/29/2015 11:53 AM, Andre Przywara wrote: > Add emulation for some basic MMIO registers used in the ITS emulation. > This includes: > - GITS_{CTLR,TYPER,IIDR} > - ID registers > - GITS_{CBASER,CREAD,CWRITER} CREADR > those implement the ITS command buffer handling > > Signed-off-by: Andre Przywara > --- > include/kvm/arm_vgic.h | 3 + > include/linux/irqchip/arm-gic-v3.h | 8 ++ > virt/kvm/arm/its-emul.c| 172 > + > virt/kvm/arm/its-emul.h| 1 + > virt/kvm/arm/vgic-v3-emul.c| 2 + > 5 files changed, 186 insertions(+) > > diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h > index d76c2d9..3b8e3a1 100644 > --- a/include/kvm/arm_vgic.h > +++ b/include/kvm/arm_vgic.h > @@ -159,6 +159,9 @@ struct vgic_io_device { > struct vgic_its { > boolenabled; > spinlock_t lock; > + u64 cbaser; > + int creadr; > + int cwriter; > }; > > struct vgic_dist { > diff --git a/include/linux/irqchip/arm-gic-v3.h > b/include/linux/irqchip/arm-gic-v3.h > index df4e527..0b450c7 100644 > --- a/include/linux/irqchip/arm-gic-v3.h > +++ b/include/linux/irqchip/arm-gic-v3.h > @@ -179,15 +179,23 @@ > #define GITS_BASER 0x0100 > #define GITS_IDREGS_BASE 0xffd0 > #define GITS_PIDR2 GICR_PIDR2 > +#define GITS_PIDR4 0xffd0 > +#define GITS_CIDR0 0xfff0 > +#define GITS_CIDR1 0xfff4 > +#define GITS_CIDR2 0xfff8 > +#define GITS_CIDR3 0xfffc > > #define GITS_TRANSLATER 0x10040 > > #define GITS_CTLR_ENABLE (1U << 0) > #define GITS_CTLR_QUIESCENT (1U << 31) > > +#define GITS_TYPER_PLPIS (1UL << 0) > +#define GITS_TYPER_IDBITS_SHIFT 8 > #define GITS_TYPER_DEVBITS_SHIFT 13 > #define GITS_TYPER_DEVBITS(r)r) >> > GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1) > #define GITS_TYPER_PTA (1UL << 19) > +#define GITS_TYPER_HWCOLLCNT_SHIFT 24 > > #define GITS_CBASER_VALID(1UL << 63) > #define GITS_CBASER_nCnB (0UL << 59) > diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c > index 7b283ce..82bc34a 100644 > --- a/virt/kvm/arm/its-emul.c > +++ b/virt/kvm/arm/its-emul.c > @@ -32,10 +32,62 @@ > #include "vgic.h" > #include "its-emul.h" > > +#define BASER_BASE_ADDRESS(x) ((x) & 0xf000ULL) > + > +/* distributor lock is hold by the VGIC MMIO handler */ > static bool handle_mmio_misc_gits(struct kvm_vcpu *vcpu, > struct kvm_exit_mmio *mmio, > phys_addr_t offset) > { > + struct vgic_its *its = &vcpu->kvm->arch.vgic.its; > + u32 reg; > + bool was_enabled; > + > + switch (offset & ~3) { > + case 0x00: /* GITS_CTLR */ > + /* We never defer any command execution. */ > + reg = GITS_CTLR_QUIESCENT; > + if (its->enabled) > + reg |= GITS_CTLR_ENABLE; > + was_enabled = its->enabled; > + vgic_reg_access(mmio, ®, offset & 3, > + ACCESS_READ_VALUE | ACCESS_WRITE_VALUE); > + its->enabled = !!(reg & GITS_CTLR_ENABLE); > + return !was_enabled && its->enabled; > + case 0x04: /* GITS_IIDR */ > + reg = (PRODUCT_ID_KVM << 24) | (IMPLEMENTER_ARM << 0); > + vgic_reg_access(mmio, ®, offset & 3, > + ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED); > + break; > + case 0x08: /* GITS_TYPER */ > + /* > + * We use linear CPU numbers for redistributor addressing, > + * so GITS_TYPER.PTA is 0. > + * To avoid memory waste on the guest side, we keep the > + * number of IDBits and DevBits low for the time being. > + * This could later be made configurable by userland. > + * Since we have all collections in linked list, we claim > + * that we can hold all of the collection tables in our > + * own memory and that the ITT entry size is 1 byte (the > + * smallest possible one). > + */ > + reg = GITS_TYPER_PLPIS; > + reg |= 0xff << GITS_TYPER_HWCOLLCNT_SHIFT; > + reg |= 0x0f << GITS_TYPER_DEVBITS_SHIFT; > + reg |= 0x0f << GITS_TYPER_IDBITS_SHIFT; > + vgic_reg_access(mmio, ®, offset & 3, > + ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED); > + break; > + case 0x0c: > + /* The upper 32bits of TYPER are all 0 for the time being. > + * Should we need more than 256 collections,
[PATCH 07/13] KVM: arm64: implement basic ITS register handlers
Add emulation for some basic MMIO registers used in the ITS emulation. This includes: - GITS_{CTLR,TYPER,IIDR} - ID registers - GITS_{CBASER,CREAD,CWRITER} those implement the ITS command buffer handling Signed-off-by: Andre Przywara --- include/kvm/arm_vgic.h | 3 + include/linux/irqchip/arm-gic-v3.h | 8 ++ virt/kvm/arm/its-emul.c| 172 + virt/kvm/arm/its-emul.h| 1 + virt/kvm/arm/vgic-v3-emul.c| 2 + 5 files changed, 186 insertions(+) diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index d76c2d9..3b8e3a1 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -159,6 +159,9 @@ struct vgic_io_device { struct vgic_its { boolenabled; spinlock_t lock; + u64 cbaser; + int creadr; + int cwriter; }; struct vgic_dist { diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index df4e527..0b450c7 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -179,15 +179,23 @@ #define GITS_BASER 0x0100 #define GITS_IDREGS_BASE 0xffd0 #define GITS_PIDR2 GICR_PIDR2 +#define GITS_PIDR4 0xffd0 +#define GITS_CIDR0 0xfff0 +#define GITS_CIDR1 0xfff4 +#define GITS_CIDR2 0xfff8 +#define GITS_CIDR3 0xfffc #define GITS_TRANSLATER0x10040 #define GITS_CTLR_ENABLE (1U << 0) #define GITS_CTLR_QUIESCENT(1U << 31) +#define GITS_TYPER_PLPIS (1UL << 0) +#define GITS_TYPER_IDBITS_SHIFT8 #define GITS_TYPER_DEVBITS_SHIFT 13 #define GITS_TYPER_DEVBITS(r) r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1) #define GITS_TYPER_PTA (1UL << 19) +#define GITS_TYPER_HWCOLLCNT_SHIFT 24 #define GITS_CBASER_VALID (1UL << 63) #define GITS_CBASER_nCnB (0UL << 59) diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c index 7b283ce..82bc34a 100644 --- a/virt/kvm/arm/its-emul.c +++ b/virt/kvm/arm/its-emul.c @@ -32,10 +32,62 @@ #include "vgic.h" #include "its-emul.h" +#define BASER_BASE_ADDRESS(x) ((x) & 0xf000ULL) + +/* distributor lock is hold by the VGIC MMIO handler */ static bool handle_mmio_misc_gits(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio, phys_addr_t offset) { + struct vgic_its *its = &vcpu->kvm->arch.vgic.its; + u32 reg; + bool was_enabled; + + switch (offset & ~3) { + case 0x00: /* GITS_CTLR */ + /* We never defer any command execution. */ + reg = GITS_CTLR_QUIESCENT; + if (its->enabled) + reg |= GITS_CTLR_ENABLE; + was_enabled = its->enabled; + vgic_reg_access(mmio, ®, offset & 3, + ACCESS_READ_VALUE | ACCESS_WRITE_VALUE); + its->enabled = !!(reg & GITS_CTLR_ENABLE); + return !was_enabled && its->enabled; + case 0x04: /* GITS_IIDR */ + reg = (PRODUCT_ID_KVM << 24) | (IMPLEMENTER_ARM << 0); + vgic_reg_access(mmio, ®, offset & 3, + ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED); + break; + case 0x08: /* GITS_TYPER */ + /* +* We use linear CPU numbers for redistributor addressing, +* so GITS_TYPER.PTA is 0. +* To avoid memory waste on the guest side, we keep the +* number of IDBits and DevBits low for the time being. +* This could later be made configurable by userland. +* Since we have all collections in linked list, we claim +* that we can hold all of the collection tables in our +* own memory and that the ITT entry size is 1 byte (the +* smallest possible one). +*/ + reg = GITS_TYPER_PLPIS; + reg |= 0xff << GITS_TYPER_HWCOLLCNT_SHIFT; + reg |= 0x0f << GITS_TYPER_DEVBITS_SHIFT; + reg |= 0x0f << GITS_TYPER_IDBITS_SHIFT; + vgic_reg_access(mmio, ®, offset & 3, + ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED); + break; + case 0x0c: + /* The upper 32bits of TYPER are all 0 for the time being. +* Should we need more than 256 collections, we can enable +* some bits in here. +*/ + vgic_reg_access(mmio, NULL, offset & 3, + ACCESS_READ_RAZ | ACCESS_WRITE_IGNORE