Message ID | 20160928182457.12433-23-andre.przywara@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, 28 Sep 2016, Andre Przywara wrote: > For each hardware ITS create and initialize a virtual ITS for Dom0. > We use the same memory mapped address to keep the doorbell working. > > Signed-off-by: Andre Przywara <andre.przywara@arm.com> > --- > xen/arch/arm/vgic-its.c | 22 ++++++++++++++++++++++ > xen/arch/arm/vgic-v3.c | 12 ++++++++++++ > xen/include/asm-arm/domain.h | 1 + > xen/include/asm-arm/gic-its.h | 13 +++++++++++++ > 4 files changed, 48 insertions(+) > > diff --git a/xen/arch/arm/vgic-its.c b/xen/arch/arm/vgic-its.c > index 1e429b7..5c605b5 100644 > --- a/xen/arch/arm/vgic-its.c > +++ b/xen/arch/arm/vgic-its.c > @@ -829,6 +829,28 @@ static const struct mmio_handler_ops vgic_its_mmio_handler = { > .write = vgic_v3_its_mmio_write, > }; > > +int vgic_v3_its_init_virtual(struct domain *d, struct host_its *hw_its, > + paddr_t guest_addr) > +{ > + struct virt_its *its; > + > + its = xzalloc(struct virt_its); > + if ( ! its ) > + return -ENOMEM; > + > + its->d = d; > + its->hw_its = hw_its; > + its->baser0 = 0x7917000000000400; > + its->baser1 = 0x3c01000000000400; > + its->cbaser = 0x380e000000000400; Please #define these values. > + spin_lock_init(&its->vcmd_lock); > + spin_lock_init(&its->its_lock); > + > + register_mmio_handler(d, &vgic_its_mmio_handler, guest_addr, SZ_64K, its); > + > + return 0; > +} > + > /* > * Local variables: > * mode: C > diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c > index aa53a1e..d230a1f 100644 > --- a/xen/arch/arm/vgic-v3.c > +++ b/xen/arch/arm/vgic-v3.c > @@ -31,6 +31,7 @@ > #include <asm/current.h> > #include <asm/mmio.h> > #include <asm/gic_v3_defs.h> > +#include <asm/gic-its.h> > #include <asm/vgic.h> > #include <asm/vgic-emul.h> > > @@ -1572,6 +1573,7 @@ static int vgic_v3_domain_init(struct domain *d) > */ > if ( is_hardware_domain(d) ) > { > + struct host_its *hw_its; > unsigned int first_cpu = 0; > > d->arch.vgic.dbase = vgic_v3_hw.dbase; > @@ -1597,6 +1599,16 @@ static int vgic_v3_domain_init(struct domain *d) > > first_cpu += size / d->arch.vgic.rdist_stride; > } > + d->arch.vgic.nr_regions = vgic_v3_hw.nr_rdist_regions; > + > + list_for_each_entry(hw_its, &host_its_list, entry) > + { > + /* Emulate the control registers frame (lower 64K). */ > + vgic_v3_its_init_virtual(d, hw_its, hw_its->addr); > + > + d->arch.vgic.has_its = true; > + } > + > } > else > { > diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h > index 0cd3500..1c2f7c7 100644 > --- a/xen/include/asm-arm/domain.h > +++ b/xen/include/asm-arm/domain.h > @@ -111,6 +111,7 @@ struct arch_domain > uint32_t rdist_stride; /* Re-Distributor stride */ > uint64_t rdist_propbase; > uint8_t *proptable; > + bool has_its; > #endif > } vgic; > > diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h > index ba6b2d5..b58e092 100644 > --- a/xen/include/asm-arm/gic-its.h > +++ b/xen/include/asm-arm/gic-its.h > @@ -123,6 +123,13 @@ void gicv3_set_redist_addr(paddr_t address, int redist_id); > /* Map a collection for this host CPU to each host ITS. */ > void gicv3_its_setup_collection(int cpu); > > +/* Create and register a virtual ITS at the given guest address. > + * If a host ITS is specified, a hardware domain can reach out to that host > + * ITS to deal with devices and LPI mappings and can enable/disable LPIs. > + */ > +int vgic_v3_its_init_virtual(struct domain *d, struct host_its *hw_its, > + paddr_t guest_addr); > + > /* Map a device on the host by allocating an ITT on the host (ITS). > * "bits" specifies how many events (interrupts) this device will need. > * Setting "valid" to false deallocates the device. > @@ -204,6 +211,12 @@ static inline bool gicv3_lpi_is_enabled(struct domain *d, uint32_t lpi) > { > return false; > } > +static inline int vgic_v3_its_init_virtual(struct domain *d, > + struct host_its *hw_its, > + paddr_t guest_addr) > +{ > + return 0; > +} > > #endif /* CONFIG_HAS_ITS */ > > -- > 2.9.0 >
diff --git a/xen/arch/arm/vgic-its.c b/xen/arch/arm/vgic-its.c index 1e429b7..5c605b5 100644 --- a/xen/arch/arm/vgic-its.c +++ b/xen/arch/arm/vgic-its.c @@ -829,6 +829,28 @@ static const struct mmio_handler_ops vgic_its_mmio_handler = { .write = vgic_v3_its_mmio_write, }; +int vgic_v3_its_init_virtual(struct domain *d, struct host_its *hw_its, + paddr_t guest_addr) +{ + struct virt_its *its; + + its = xzalloc(struct virt_its); + if ( ! its ) + return -ENOMEM; + + its->d = d; + its->hw_its = hw_its; + its->baser0 = 0x7917000000000400; + its->baser1 = 0x3c01000000000400; + its->cbaser = 0x380e000000000400; + spin_lock_init(&its->vcmd_lock); + spin_lock_init(&its->its_lock); + + register_mmio_handler(d, &vgic_its_mmio_handler, guest_addr, SZ_64K, its); + + return 0; +} + /* * Local variables: * mode: C diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index aa53a1e..d230a1f 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -31,6 +31,7 @@ #include <asm/current.h> #include <asm/mmio.h> #include <asm/gic_v3_defs.h> +#include <asm/gic-its.h> #include <asm/vgic.h> #include <asm/vgic-emul.h> @@ -1572,6 +1573,7 @@ static int vgic_v3_domain_init(struct domain *d) */ if ( is_hardware_domain(d) ) { + struct host_its *hw_its; unsigned int first_cpu = 0; d->arch.vgic.dbase = vgic_v3_hw.dbase; @@ -1597,6 +1599,16 @@ static int vgic_v3_domain_init(struct domain *d) first_cpu += size / d->arch.vgic.rdist_stride; } + d->arch.vgic.nr_regions = vgic_v3_hw.nr_rdist_regions; + + list_for_each_entry(hw_its, &host_its_list, entry) + { + /* Emulate the control registers frame (lower 64K). */ + vgic_v3_its_init_virtual(d, hw_its, hw_its->addr); + + d->arch.vgic.has_its = true; + } + } else { diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index 0cd3500..1c2f7c7 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -111,6 +111,7 @@ struct arch_domain uint32_t rdist_stride; /* Re-Distributor stride */ uint64_t rdist_propbase; uint8_t *proptable; + bool has_its; #endif } vgic; diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h index ba6b2d5..b58e092 100644 --- a/xen/include/asm-arm/gic-its.h +++ b/xen/include/asm-arm/gic-its.h @@ -123,6 +123,13 @@ void gicv3_set_redist_addr(paddr_t address, int redist_id); /* Map a collection for this host CPU to each host ITS. */ void gicv3_its_setup_collection(int cpu); +/* Create and register a virtual ITS at the given guest address. + * If a host ITS is specified, a hardware domain can reach out to that host + * ITS to deal with devices and LPI mappings and can enable/disable LPIs. + */ +int vgic_v3_its_init_virtual(struct domain *d, struct host_its *hw_its, + paddr_t guest_addr); + /* Map a device on the host by allocating an ITT on the host (ITS). * "bits" specifies how many events (interrupts) this device will need. * Setting "valid" to false deallocates the device. @@ -204,6 +211,12 @@ static inline bool gicv3_lpi_is_enabled(struct domain *d, uint32_t lpi) { return false; } +static inline int vgic_v3_its_init_virtual(struct domain *d, + struct host_its *hw_its, + paddr_t guest_addr) +{ + return 0; +} #endif /* CONFIG_HAS_ITS */
For each hardware ITS create and initialize a virtual ITS for Dom0. We use the same memory mapped address to keep the doorbell working. Signed-off-by: Andre Przywara <andre.przywara@arm.com> --- xen/arch/arm/vgic-its.c | 22 ++++++++++++++++++++++ xen/arch/arm/vgic-v3.c | 12 ++++++++++++ xen/include/asm-arm/domain.h | 1 + xen/include/asm-arm/gic-its.h | 13 +++++++++++++ 4 files changed, 48 insertions(+)