* [RFC 00/13] vITS save/restore @ 2017-01-12 15:56 Eric Auger [not found] ` <1484236613-24633-8-git-send-email-eric.auger@redhat.com> ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: Eric Auger @ 2017-01-12 15:56 UTC (permalink / raw) To: linux-arm-kernel This series specifies and implements an API aimed at saving and restoring the state of the in-kernel emulated ITS device. The ITS is programmed through registers and tables. Those later tables are allocated by the guest. Their base address is programmed in registers or table entries before the ITS is enabled. The ITS is free to use some of them to flush its internal caches. This is likely to be used when entering low power state. Therefore, for save/restore use case, it looks natural to use this guest RAM allocated space to save the table related data. However, currently,The ITS in-kernel emulated device does not use all of those tables and for those it uses, it does not always sync them with its cached data. Additional sync must happen for: - the collection table - the device table - the per-device translation tables - the LPI pending tables. The LPI configration table and the command queues do not need extra syncs. So the bulk of the work in this series consists in the table save/restore rather than register save/restore. An alternative to flushing the tables into guest RAM could have been to flush them into a separate user-space buffer. However the drawback of this alternative is that the virtualizer would allocate dedicated buffers to store the data that should normally be laid out in guest RAM. It would also be obliged to re-compute their size from register/table content. So saving the tables in guest RAM better fit the ITS programming model and optimizes the memory usage. The drawback of this solution is it brings additional challenges at user-space level to make sure the guest RAM is frozen after table sync. The code is functional while saving/restoring a guest using virtio-net-pci. However many points deserve additional tests. I share the series at that stage to get the documentation reviewed and main principles discussed. The series applies on top of Vijaya's series: - [PATCH v10 0/8] arm/arm64: vgic: Implement API for vGICv3 live migration http://www.spinics.net/lists/arm-kernel/msg546383.html Best Regards Eric Git: complete series available at https://github.com/eauger/linux/tree/v4.10-rc3-its-mig-rfc-v1 * Testing: - on Cavium using a virtio-net-pci guest and virsh save/restore commands Eric Auger (13): KVM: arm/arm64: Add vITS save/restore API documentation arm/arm64: vgic: turn vgic_find_mmio_region into public KVM: arm64: ITS: KVM_DEV_ARM_VGIC_GRP_ITS_REGS group KVM: arm64: ITS: Implement vgic_its_has_attr_regs and attr_regs_access KVM: arm64: ITS: Implement vgic_mmio_uaccess_write_its_creadr KVM: arm64: ITS: Expose ITT_Entry_Size in GITS_TYPER KVM: arm64: ITS: Change entry_size and indirect bit in BASER KVM: arm64: ITS: On MAPD interpret and store itt_addr and size KVM: arm64: ITS: KVM_DEV_ARM_VGIC_GRP_ITS_TABLES group KVM: arm64: ITS: vgic_its_alloc_itte/device KVM: arm64: ITS: Collection table save/restore KVM: arm64: ITS: Device and translation table flush KVM: arm64: ITS: Pending table save/restore Documentation/virtual/kvm/devices/arm-vgic-its.txt | 70 +++ arch/arm/include/uapi/asm/kvm.h | 2 + arch/arm64/include/uapi/asm/kvm.h | 2 + include/kvm/arm_vgic.h | 3 + include/linux/irqchip/arm-gic-v3.h | 1 + virt/kvm/arm/vgic/vgic-its.c | 655 +++++++++++++++++++-- virt/kvm/arm/vgic/vgic-mmio.c | 3 +- virt/kvm/arm/vgic/vgic-mmio.h | 14 +- 8 files changed, 705 insertions(+), 45 deletions(-) -- 2.5.5 ^ permalink raw reply [flat|nested] 12+ messages in thread
[parent not found: <1484236613-24633-8-git-send-email-eric.auger@redhat.com>]
* [RFC 07/13] KVM: arm64: ITS: Change entry_size and indirect bit in BASER [not found] ` <1484236613-24633-8-git-send-email-eric.auger@redhat.com> @ 2017-01-12 17:05 ` Marc Zyngier 2017-01-13 8:57 ` Auger Eric 0 siblings, 1 reply; 12+ messages in thread From: Marc Zyngier @ 2017-01-12 17:05 UTC (permalink / raw) To: linux-arm-kernel On 12/01/17 15:56, Eric Auger wrote: > Change the device table entry_size to 16 bytes instead of 8. > We also Store the device and collection device in the its > struct. > > The patch also clears the indirect bit for the device BASER. > The indirect bit is set as read-only. Err... Why? We *really* want to continue supporting indirect tables, as this is a massive memory saver for the guest. > > Signed-off-by: Eric Auger <eric.auger@redhat.com> > > --- > > TODO: investigate support of 2 level tables, ie. enabling > Indirect = 1. Support of 2 level tables is implementation > defined. Clearly, that's a regression. What exactly is the issue that decided you to disable it? Thanks, M. -- Jazz is not dead. It just smells funny... ^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC 07/13] KVM: arm64: ITS: Change entry_size and indirect bit in BASER 2017-01-12 17:05 ` [RFC 07/13] KVM: arm64: ITS: Change entry_size and indirect bit in BASER Marc Zyngier @ 2017-01-13 8:57 ` Auger Eric 2017-01-13 9:22 ` Marc Zyngier 0 siblings, 1 reply; 12+ messages in thread From: Auger Eric @ 2017-01-13 8:57 UTC (permalink / raw) To: linux-arm-kernel Hi Marc, On 12/01/2017 18:05, Marc Zyngier wrote: > On 12/01/17 15:56, Eric Auger wrote: >> Change the device table entry_size to 16 bytes instead of 8. >> We also Store the device and collection device in the its >> struct. >> >> The patch also clears the indirect bit for the device BASER. >> The indirect bit is set as read-only. > > Err... Why? We *really* want to continue supporting indirect tables, as > this is a massive memory saver for the guest. > >> >> Signed-off-by: Eric Auger <eric.auger@redhat.com> >> >> --- >> >> TODO: investigate support of 2 level tables, ie. enabling >> Indirect = 1. Support of 2 level tables is implementation >> defined. > > Clearly, that's a regression. What exactly is the issue that decided you > to disable it? Well no valuable reason besides I saw it was optional, lack of time/knowledge and a bit of laziness. I will address this requirement in my next respin. For my curiosity why did we choose not allowing the feature for collections. Is that just because we think their number if going sufficiently small compared to devices? Thanks Eric > > Thanks, > > M. > ^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC 07/13] KVM: arm64: ITS: Change entry_size and indirect bit in BASER 2017-01-13 8:57 ` Auger Eric @ 2017-01-13 9:22 ` Marc Zyngier 0 siblings, 0 replies; 12+ messages in thread From: Marc Zyngier @ 2017-01-13 9:22 UTC (permalink / raw) To: linux-arm-kernel On 13/01/17 08:57, Auger Eric wrote: > Hi Marc, > > On 12/01/2017 18:05, Marc Zyngier wrote: >> On 12/01/17 15:56, Eric Auger wrote: >>> Change the device table entry_size to 16 bytes instead of 8. >>> We also Store the device and collection device in the its >>> struct. >>> >>> The patch also clears the indirect bit for the device BASER. >>> The indirect bit is set as read-only. >> >> Err... Why? We *really* want to continue supporting indirect tables, as >> this is a massive memory saver for the guest. >> >>> >>> Signed-off-by: Eric Auger <eric.auger@redhat.com> >>> >>> --- >>> >>> TODO: investigate support of 2 level tables, ie. enabling >>> Indirect = 1. Support of 2 level tables is implementation >>> defined. >> >> Clearly, that's a regression. What exactly is the issue that decided you >> to disable it? > Well no valuable reason besides I saw it was optional, lack of > time/knowledge and a bit of laziness. I will address this requirement in > my next respin. Ah, I was worried about something much more fundamental! ;-) > For my curiosity why did we choose not allowing the feature for > collections. Is that just because we think their number if going > sufficiently small compared to devices? Collections are usually a much smaller number (directly related to the number of CPUs in the system), and can be kept very compact. Devices, on the other hand, can be extremely sparse (to the point where a guest can fail to allocate enough memory to cover the required range). TBH, we could allow it for collections as well. It is just not that useful. Thanks, M. -- Jazz is not dead. It just smells funny... ^ permalink raw reply [flat|nested] 12+ messages in thread
[parent not found: <1484236613-24633-7-git-send-email-eric.auger@redhat.com>]
* [RFC 06/13] KVM: arm64: ITS: Expose ITT_Entry_Size in GITS_TYPER [not found] ` <1484236613-24633-7-git-send-email-eric.auger@redhat.com> @ 2017-01-12 17:06 ` Andre Przywara 2017-01-13 8:31 ` Auger Eric 0 siblings, 1 reply; 12+ messages in thread From: Andre Przywara @ 2017-01-12 17:06 UTC (permalink / raw) To: linux-arm-kernel Hi Eric, On 12/01/17 15:56, Eric Auger wrote: > An ITT_Entry_Size of 2x8Bytes is reported to the guest > to provision for ITTE state storage. > > Signed-off-by: Eric Auger <eric.auger@redhat.com> > --- > include/linux/irqchip/arm-gic-v3.h | 1 + > virt/kvm/arm/vgic/vgic-its.c | 3 +++ > 2 files changed, 4 insertions(+) > > diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h > index 170e00a..8cfd81bc 100644 > --- a/include/linux/irqchip/arm-gic-v3.h > +++ b/include/linux/irqchip/arm-gic-v3.h > @@ -233,6 +233,7 @@ > #define GITS_CTLR_QUIESCENT (1U << 31) > > #define GITS_TYPER_PLPIS (1UL << 0) > +#define GITS_TYPER_ITT_ENTRY_SIZE_SHIFT 4 > #define GITS_TYPER_IDBITS_SHIFT 8 > #define GITS_TYPER_DEVBITS_SHIFT 13 > #define GITS_TYPER_DEVBITS(r) ((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1) > diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c > index e174220..96378b8 100644 > --- a/virt/kvm/arm/vgic/vgic-its.c > +++ b/virt/kvm/arm/vgic/vgic-its.c > @@ -33,6 +33,8 @@ > #include "vgic.h" > #include "vgic-mmio.h" > > +#define ITTE_SIZE 16 > + > /* > * 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 > @@ -399,6 +401,7 @@ static unsigned long vgic_mmio_read_its_typer(struct kvm *kvm, > */ > reg |= 0x0f << GITS_TYPER_DEVBITS_SHIFT; > reg |= 0x0f << GITS_TYPER_IDBITS_SHIFT; > + reg |= ITTE_SIZE << GITS_TYPER_ITT_ENTRY_SIZE_SHIFT; The field is defined as the "... number of bytes per translation table entry, minus one.". So it should be: (ITTE_SIZE - 1) << ... Cheers, Andre. > > return extract_bytes(reg, addr & 7, len); > } > ^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC 06/13] KVM: arm64: ITS: Expose ITT_Entry_Size in GITS_TYPER 2017-01-12 17:06 ` [RFC 06/13] KVM: arm64: ITS: Expose ITT_Entry_Size in GITS_TYPER Andre Przywara @ 2017-01-13 8:31 ` Auger Eric 0 siblings, 0 replies; 12+ messages in thread From: Auger Eric @ 2017-01-13 8:31 UTC (permalink / raw) To: linux-arm-kernel Hi Andre, On 12/01/2017 18:06, Andre Przywara wrote: > Hi Eric, > > On 12/01/17 15:56, Eric Auger wrote: >> An ITT_Entry_Size of 2x8Bytes is reported to the guest >> to provision for ITTE state storage. >> >> Signed-off-by: Eric Auger <eric.auger@redhat.com> >> --- >> include/linux/irqchip/arm-gic-v3.h | 1 + >> virt/kvm/arm/vgic/vgic-its.c | 3 +++ >> 2 files changed, 4 insertions(+) >> >> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h >> index 170e00a..8cfd81bc 100644 >> --- a/include/linux/irqchip/arm-gic-v3.h >> +++ b/include/linux/irqchip/arm-gic-v3.h >> @@ -233,6 +233,7 @@ >> #define GITS_CTLR_QUIESCENT (1U << 31) >> >> #define GITS_TYPER_PLPIS (1UL << 0) >> +#define GITS_TYPER_ITT_ENTRY_SIZE_SHIFT 4 >> #define GITS_TYPER_IDBITS_SHIFT 8 >> #define GITS_TYPER_DEVBITS_SHIFT 13 >> #define GITS_TYPER_DEVBITS(r) ((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1) >> diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c >> index e174220..96378b8 100644 >> --- a/virt/kvm/arm/vgic/vgic-its.c >> +++ b/virt/kvm/arm/vgic/vgic-its.c >> @@ -33,6 +33,8 @@ >> #include "vgic.h" >> #include "vgic-mmio.h" >> >> +#define ITTE_SIZE 16 >> + >> /* >> * 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 >> @@ -399,6 +401,7 @@ static unsigned long vgic_mmio_read_its_typer(struct kvm *kvm, >> */ >> reg |= 0x0f << GITS_TYPER_DEVBITS_SHIFT; >> reg |= 0x0f << GITS_TYPER_IDBITS_SHIFT; >> + reg |= ITTE_SIZE << GITS_TYPER_ITT_ENTRY_SIZE_SHIFT; > > The field is defined as the "... number of bytes per translation table > entry, minus one.". So it should be: (ITTE_SIZE - 1) << ... You're perfectly right. I will fix that Thanks Eric > > Cheers, > Andre. > >> >> return extract_bytes(reg, addr & 7, len); >> } >> ^ permalink raw reply [flat|nested] 12+ messages in thread
[parent not found: <1484236613-24633-2-git-send-email-eric.auger@redhat.com>]
* [RFC 01/13] KVM: arm/arm64: Add vITS save/restore API documentation [not found] ` <1484236613-24633-2-git-send-email-eric.auger@redhat.com> @ 2017-01-12 16:52 ` Marc Zyngier 2017-01-13 9:07 ` Auger Eric 2017-02-03 14:00 ` Peter Maydell 1 sibling, 1 reply; 12+ messages in thread From: Marc Zyngier @ 2017-01-12 16:52 UTC (permalink / raw) To: linux-arm-kernel Hi Eric, On 12/01/17 15:56, Eric Auger wrote: > Add description for how to access vITS registers and how to flush/restore > vITS tables into/from memory > > Signed-off-by: Eric Auger <eric.auger@redhat.com> > --- > Documentation/virtual/kvm/devices/arm-vgic-its.txt | 70 ++++++++++++++++++++++ > 1 file changed, 70 insertions(+) > > diff --git a/Documentation/virtual/kvm/devices/arm-vgic-its.txt b/Documentation/virtual/kvm/devices/arm-vgic-its.txt > index 6081a5b..bd74613 100644 > --- a/Documentation/virtual/kvm/devices/arm-vgic-its.txt > +++ b/Documentation/virtual/kvm/devices/arm-vgic-its.txt > @@ -36,3 +36,73 @@ Groups: > -ENXIO: ITS not properly configured as required prior to setting > this attribute > -ENOMEM: Memory shortage when allocating ITS internal data > + > + KVM_DEV_ARM_VGIC_GRP_ITS_REGS > + Attributes: > + The attr field of kvm_device_attr encodes the offset of the > + ITS register, relative to the ITS control frame base address > + (ITS_base). > + > + kvm_device_attr.addr points to a __u64 value whatever the width > + of the addressed register (32/64 bits). > + > + Writes to read-only registers are ignored by the kernel except > + for a single register, GITS_READR. Normally this register is RO > + but it needs to be restored otherwise commands in the queue will > + be re-executed after CWRITER setting. > + > + For other registers, Getting or setting a register has the same > + effect as reading/writing the register on real hardware. > + Errors: > + -ENXIO: Offset does not correspond to any supported register > + -EFAULT: Invalid user pointer for attr->addr > + -EINVAL: Offset is not 64-bit aligned > + > + KVM_DEV_ARM_VGIC_GRP_ITS_TABLES > + Attributes > + The attr field of kvm_device_attr is not used. > + > + request the flush-save/restore of the ITS tables, namely > + the device table, the collection table, all the ITT tables, > + the LPI pending tables. On save, the tables are flushed > + into guest memory at the location provisionned by the guest provisioned > + in GITS_BASER (device and collection tables), on MAPD command > + (ITT_addr), GICR_PENDBASERs (pending tables). > + > + This means the GIC should be restored before the ITS and all > + ITS registers but the GITS_CTRL must be restored before > + restoring the ITS tables. > + > + Note the LPI configuration table is read-only for the > + in-kernel ITS and its save/restore goes through the standard > + RAM save/restore. > + > + The layout of the tables in guest memory defines an ABI. > + The entries are laid out in memory as follows; > + > + Device Table Entry (DTE) layout: entry size = 16 bytes > + > + bits: | 63 ... 32 | 31 ... 6 | 5 | 4 ... 0 | > + values: | DeviceID | Resv | V | Size | > + > + bits: | 63 ... 44 | 43 ... 0 | > + values: | Resv | ITT_addr | While I appreciate this layout represents the absolute maximum an ITS could implement, I'm a bit concerned about the amount of memory we may end-up requiring here. All the ITSs implementations I know of seem to get away with 8 bytes per entry. Maybe I'm just too worried. Also, please mention that ITT_addr is actually ITT_addr[51:8], as we're guaranteed to have an ITT that is 256 byte aligned. > + > + Collection Table Entry (CTE) layout: entry size = 8 bytes > + > + bits: | 63| 62 .. 52 | 51 ... 16 | 15 ... 0 | > + values: | V | RES0 | RDBase | ICID | > + > + Interrupt Translation Table Entry (ITTE) layout: entry size = 16 bytes The actual name is Interrupt Translation Entry (ITE). I have a patch renaming this all over the vgic-its.c file... > + > + bits: | 63 ... 32 | 31 ... 17 | 16 | 15 ... 0 | > + values: | DeviceID | RES0 | V | ICID | > + > + bits: | 63 ... 32 | 31 ... 0 | > + values: | pINTID | EventID | Same concern here. 32bit DevID, EventID and INTID seem a bit over the top. But maybe we shouldn't be concerned about memory... ;-) > + > + LPI Pending Table layout: > + > + As specified in the ARM Generic Interrupt Controller Architecture > + Specification GIC Architecture version 3.0 and version 4. The first > + 1kB contains only zeros. > You definitely want to relax this. An ITS implementation is allowed (and actually encouraged) to maintain a coarse map in the first kB, and use this to quickly scan the table, which would be very useful on restore. Thanks, M. -- Jazz is not dead. It just smells funny... ^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC 01/13] KVM: arm/arm64: Add vITS save/restore API documentation 2017-01-12 16:52 ` [RFC 01/13] KVM: arm/arm64: Add vITS save/restore API documentation Marc Zyngier @ 2017-01-13 9:07 ` Auger Eric 2017-01-13 9:46 ` Marc Zyngier 0 siblings, 1 reply; 12+ messages in thread From: Auger Eric @ 2017-01-13 9:07 UTC (permalink / raw) To: linux-arm-kernel Hi Marc, On 12/01/2017 17:52, Marc Zyngier wrote: > Hi Eric, > > On 12/01/17 15:56, Eric Auger wrote: >> Add description for how to access vITS registers and how to flush/restore >> vITS tables into/from memory >> >> Signed-off-by: Eric Auger <eric.auger@redhat.com> >> --- >> Documentation/virtual/kvm/devices/arm-vgic-its.txt | 70 ++++++++++++++++++++++ >> 1 file changed, 70 insertions(+) >> >> diff --git a/Documentation/virtual/kvm/devices/arm-vgic-its.txt b/Documentation/virtual/kvm/devices/arm-vgic-its.txt >> index 6081a5b..bd74613 100644 >> --- a/Documentation/virtual/kvm/devices/arm-vgic-its.txt >> +++ b/Documentation/virtual/kvm/devices/arm-vgic-its.txt >> @@ -36,3 +36,73 @@ Groups: >> -ENXIO: ITS not properly configured as required prior to setting >> this attribute >> -ENOMEM: Memory shortage when allocating ITS internal data >> + >> + KVM_DEV_ARM_VGIC_GRP_ITS_REGS >> + Attributes: >> + The attr field of kvm_device_attr encodes the offset of the >> + ITS register, relative to the ITS control frame base address >> + (ITS_base). >> + >> + kvm_device_attr.addr points to a __u64 value whatever the width >> + of the addressed register (32/64 bits). >> + >> + Writes to read-only registers are ignored by the kernel except >> + for a single register, GITS_READR. Normally this register is RO >> + but it needs to be restored otherwise commands in the queue will >> + be re-executed after CWRITER setting. >> + >> + For other registers, Getting or setting a register has the same >> + effect as reading/writing the register on real hardware. >> + Errors: >> + -ENXIO: Offset does not correspond to any supported register >> + -EFAULT: Invalid user pointer for attr->addr >> + -EINVAL: Offset is not 64-bit aligned >> + >> + KVM_DEV_ARM_VGIC_GRP_ITS_TABLES >> + Attributes >> + The attr field of kvm_device_attr is not used. >> + >> + request the flush-save/restore of the ITS tables, namely >> + the device table, the collection table, all the ITT tables, >> + the LPI pending tables. On save, the tables are flushed >> + into guest memory at the location provisionned by the guest > > provisioned > >> + in GITS_BASER (device and collection tables), on MAPD command >> + (ITT_addr), GICR_PENDBASERs (pending tables). >> + >> + This means the GIC should be restored before the ITS and all >> + ITS registers but the GITS_CTRL must be restored before >> + restoring the ITS tables. >> + >> + Note the LPI configuration table is read-only for the >> + in-kernel ITS and its save/restore goes through the standard >> + RAM save/restore. >> + >> + The layout of the tables in guest memory defines an ABI. >> + The entries are laid out in memory as follows; >> + >> + Device Table Entry (DTE) layout: entry size = 16 bytes >> + >> + bits: | 63 ... 32 | 31 ... 6 | 5 | 4 ... 0 | >> + values: | DeviceID | Resv | V | Size | >> + >> + bits: | 63 ... 44 | 43 ... 0 | >> + values: | Resv | ITT_addr | > > While I appreciate this layout represents the absolute maximum an ITS > could implement, I'm a bit concerned about the amount of memory we may > end-up requiring here. All the ITSs implementations I know of seem to > get away with 8 bytes per entry. Maybe I'm just too worried. OK so I would propose a 16b DeviceId and 16b eventid bits: | 63 ... 48 | 47 ... 4 | 3 ... 0 | values: | DeviceID | ITT_addr | Size | I can use the size field as a validity indicator > > Also, please mention that ITT_addr is actually ITT_addr[51:8], as we're > guaranteed to have an ITT that is 256 byte aligned. sure > >> + >> + Collection Table Entry (CTE) layout: entry size = 8 bytes >> + >> + bits: | 63| 62 .. 52 | 51 ... 16 | 15 ... 0 | >> + values: | V | RES0 | RDBase | ICID | >> + >> + Interrupt Translation Table Entry (ITTE) layout: entry size = 16 bytes > > The actual name is Interrupt Translation Entry (ITE). I have a patch > renaming this all over the vgic-its.c file... ok > >> + >> + bits: | 63 ... 32 | 31 ... 17 | 16 | 15 ... 0 | >> + values: | DeviceID | RES0 | V | ICID | >> + >> + bits: | 63 ... 32 | 31 ... 0 | >> + values: | pINTID | EventID | > > Same concern here. 32bit DevID, EventID and INTID seem a bit over the > top. But maybe we shouldn't be concerned about memory... ;-) So I would suggest encoding 16b DeviceId 16b eventid 16b collection ID 16b pINTID bits: | 63 ... 48 | 47 ... 32 | 31 ... 15 | 15 ... 0 | values: | DeviceID | pINTID | EventId | ICID | a null pINTID would meen the ITE is invalid. Does that make sense or should I instead reduce the number of bits allocated to collections and keep the pINTID bit number larger? > >> + >> + LPI Pending Table layout: >> + >> + As specified in the ARM Generic Interrupt Controller Architecture >> + Specification GIC Architecture version 3.0 and version 4. The first >> + 1kB contains only zeros. >> > > You definitely want to relax this. An ITS implementation is allowed (and > actually encouraged) to maintain a coarse map in the first kB, and use > this to quickly scan the table, which would be very useful on restore. Maybe I miss something here. Currently I restore the ITEs before the pending tables. So considering all the ITEs I know which LPI are defined and which pending bits need to be restored. Why would I need to use a coarse map for? I understand the CPU cannot write the pending tables in our back, spec says behavior would be unpredictable, right? Thanks Eric > > Thanks, > > M. > ^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC 01/13] KVM: arm/arm64: Add vITS save/restore API documentation 2017-01-13 9:07 ` Auger Eric @ 2017-01-13 9:46 ` Marc Zyngier 2017-01-30 16:15 ` Auger Eric 0 siblings, 1 reply; 12+ messages in thread From: Marc Zyngier @ 2017-01-13 9:46 UTC (permalink / raw) To: linux-arm-kernel On 13/01/17 09:07, Auger Eric wrote: > Hi Marc, > > On 12/01/2017 17:52, Marc Zyngier wrote: >> Hi Eric, >> >> On 12/01/17 15:56, Eric Auger wrote: >>> Add description for how to access vITS registers and how to flush/restore >>> vITS tables into/from memory >>> >>> Signed-off-by: Eric Auger <eric.auger@redhat.com> >>> --- >>> Documentation/virtual/kvm/devices/arm-vgic-its.txt | 70 ++++++++++++++++++++++ >>> 1 file changed, 70 insertions(+) >>> >>> diff --git a/Documentation/virtual/kvm/devices/arm-vgic-its.txt b/Documentation/virtual/kvm/devices/arm-vgic-its.txt >>> index 6081a5b..bd74613 100644 >>> --- a/Documentation/virtual/kvm/devices/arm-vgic-its.txt >>> +++ b/Documentation/virtual/kvm/devices/arm-vgic-its.txt >>> @@ -36,3 +36,73 @@ Groups: >>> -ENXIO: ITS not properly configured as required prior to setting >>> this attribute >>> -ENOMEM: Memory shortage when allocating ITS internal data >>> + >>> + KVM_DEV_ARM_VGIC_GRP_ITS_REGS >>> + Attributes: >>> + The attr field of kvm_device_attr encodes the offset of the >>> + ITS register, relative to the ITS control frame base address >>> + (ITS_base). >>> + >>> + kvm_device_attr.addr points to a __u64 value whatever the width >>> + of the addressed register (32/64 bits). >>> + >>> + Writes to read-only registers are ignored by the kernel except >>> + for a single register, GITS_READR. Normally this register is RO >>> + but it needs to be restored otherwise commands in the queue will >>> + be re-executed after CWRITER setting. >>> + >>> + For other registers, Getting or setting a register has the same >>> + effect as reading/writing the register on real hardware. >>> + Errors: >>> + -ENXIO: Offset does not correspond to any supported register >>> + -EFAULT: Invalid user pointer for attr->addr >>> + -EINVAL: Offset is not 64-bit aligned >>> + >>> + KVM_DEV_ARM_VGIC_GRP_ITS_TABLES >>> + Attributes >>> + The attr field of kvm_device_attr is not used. >>> + >>> + request the flush-save/restore of the ITS tables, namely >>> + the device table, the collection table, all the ITT tables, >>> + the LPI pending tables. On save, the tables are flushed >>> + into guest memory at the location provisionned by the guest >> >> provisioned >> >>> + in GITS_BASER (device and collection tables), on MAPD command >>> + (ITT_addr), GICR_PENDBASERs (pending tables). >>> + >>> + This means the GIC should be restored before the ITS and all >>> + ITS registers but the GITS_CTRL must be restored before >>> + restoring the ITS tables. >>> + >>> + Note the LPI configuration table is read-only for the >>> + in-kernel ITS and its save/restore goes through the standard >>> + RAM save/restore. >>> + >>> + The layout of the tables in guest memory defines an ABI. >>> + The entries are laid out in memory as follows; >>> + >>> + Device Table Entry (DTE) layout: entry size = 16 bytes >>> + >>> + bits: | 63 ... 32 | 31 ... 6 | 5 | 4 ... 0 | >>> + values: | DeviceID | Resv | V | Size | >>> + >>> + bits: | 63 ... 44 | 43 ... 0 | >>> + values: | Resv | ITT_addr | >> >> While I appreciate this layout represents the absolute maximum an ITS >> could implement, I'm a bit concerned about the amount of memory we may >> end-up requiring here. All the ITSs implementations I know of seem to >> get away with 8 bytes per entry. Maybe I'm just too worried. > > OK so I would propose a 16b DeviceId and 16b eventid > > bits: | 63 ... 48 | 47 ... 4 | 3 ... 0 | > values: | DeviceID | ITT_addr | Size | > > I can use the size field as a validity indicator Note that you are allowed to use a 0 size field. It means 1 bit of EventID (2 possible interrupts). So maybe using a particular address as a valid flag? > >> >> Also, please mention that ITT_addr is actually ITT_addr[51:8], as we're >> guaranteed to have an ITT that is 256 byte aligned. > sure >> >>> + >>> + Collection Table Entry (CTE) layout: entry size = 8 bytes >>> + >>> + bits: | 63| 62 .. 52 | 51 ... 16 | 15 ... 0 | >>> + values: | V | RES0 | RDBase | ICID | >>> + >>> + Interrupt Translation Table Entry (ITTE) layout: entry size = 16 bytes >> >> The actual name is Interrupt Translation Entry (ITE). I have a patch >> renaming this all over the vgic-its.c file... > ok >> >>> + >>> + bits: | 63 ... 32 | 31 ... 17 | 16 | 15 ... 0 | >>> + values: | DeviceID | RES0 | V | ICID | >>> + >>> + bits: | 63 ... 32 | 31 ... 0 | >>> + values: | pINTID | EventID | >> >> Same concern here. 32bit DevID, EventID and INTID seem a bit over the >> top. But maybe we shouldn't be concerned about memory... ;-) > So I would suggest encoding > 16b DeviceId > 16b eventid > 16b collection ID > 16b pINTID > > bits: | 63 ... 48 | 47 ... 32 | 31 ... 15 | 15 ... 0 | > values: | DeviceID | pINTID | EventId | ICID | > > a null pINTID would meen the ITE is invalid. > > Does that make sense or should I instead reduce the number of bits > allocated to collections and keep the pINTID bit number larger? 16bit worth of collections is quite a lot (64k CPUs?). I'd be perfectly fine with a smaller number, but let's see what people think. > > >> >>> + >>> + LPI Pending Table layout: >>> + >>> + As specified in the ARM Generic Interrupt Controller Architecture >>> + Specification GIC Architecture version 3.0 and version 4. The first >>> + 1kB contains only zeros. >>> >> >> You definitely want to relax this. An ITS implementation is allowed (and >> actually encouraged) to maintain a coarse map in the first kB, and use >> this to quickly scan the table, which would be very useful on restore. > Maybe I miss something here. Currently I restore the ITEs before the > pending tables. So considering all the ITEs I know which LPI are defined > and which pending bits need to be restored. Why would I need to use a > coarse map for? You could, instead of testing all the bits for which you can generate an LPI, look at the coarse map, which usually uses one bit to represent something like 64 bits of pending table, and find out what is currently pending. That's what HW does, but maybe there is no need to do this for the SW implementation, specially if we have very few LPIs. > I understand the CPU cannot write the pending tables in our back, spec > says behavior would be unpredictable, right? Absolutely. Only the ITS can touch that memory. Thanks, M. -- Jazz is not dead. It just smells funny... ^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC 01/13] KVM: arm/arm64: Add vITS save/restore API documentation 2017-01-13 9:46 ` Marc Zyngier @ 2017-01-30 16:15 ` Auger Eric 0 siblings, 0 replies; 12+ messages in thread From: Auger Eric @ 2017-01-30 16:15 UTC (permalink / raw) To: linux-arm-kernel Hi Marc, On 13/01/2017 10:46, Marc Zyngier wrote: > On 13/01/17 09:07, Auger Eric wrote: >> Hi Marc, >> >> On 12/01/2017 17:52, Marc Zyngier wrote: >>> Hi Eric, >>> >>> On 12/01/17 15:56, Eric Auger wrote: >>>> Add description for how to access vITS registers and how to flush/restore >>>> vITS tables into/from memory >>>> >>>> Signed-off-by: Eric Auger <eric.auger@redhat.com> >>>> --- >>>> Documentation/virtual/kvm/devices/arm-vgic-its.txt | 70 ++++++++++++++++++++++ >>>> 1 file changed, 70 insertions(+) >>>> >>>> diff --git a/Documentation/virtual/kvm/devices/arm-vgic-its.txt b/Documentation/virtual/kvm/devices/arm-vgic-its.txt >>>> index 6081a5b..bd74613 100644 >>>> --- a/Documentation/virtual/kvm/devices/arm-vgic-its.txt >>>> +++ b/Documentation/virtual/kvm/devices/arm-vgic-its.txt >>>> @@ -36,3 +36,73 @@ Groups: >>>> -ENXIO: ITS not properly configured as required prior to setting >>>> this attribute >>>> -ENOMEM: Memory shortage when allocating ITS internal data >>>> + >>>> + KVM_DEV_ARM_VGIC_GRP_ITS_REGS >>>> + Attributes: >>>> + The attr field of kvm_device_attr encodes the offset of the >>>> + ITS register, relative to the ITS control frame base address >>>> + (ITS_base). >>>> + >>>> + kvm_device_attr.addr points to a __u64 value whatever the width >>>> + of the addressed register (32/64 bits). >>>> + >>>> + Writes to read-only registers are ignored by the kernel except >>>> + for a single register, GITS_READR. Normally this register is RO >>>> + but it needs to be restored otherwise commands in the queue will >>>> + be re-executed after CWRITER setting. >>>> + >>>> + For other registers, Getting or setting a register has the same >>>> + effect as reading/writing the register on real hardware. >>>> + Errors: >>>> + -ENXIO: Offset does not correspond to any supported register >>>> + -EFAULT: Invalid user pointer for attr->addr >>>> + -EINVAL: Offset is not 64-bit aligned >>>> + >>>> + KVM_DEV_ARM_VGIC_GRP_ITS_TABLES >>>> + Attributes >>>> + The attr field of kvm_device_attr is not used. >>>> + >>>> + request the flush-save/restore of the ITS tables, namely >>>> + the device table, the collection table, all the ITT tables, >>>> + the LPI pending tables. On save, the tables are flushed >>>> + into guest memory at the location provisionned by the guest >>> >>> provisioned >>> >>>> + in GITS_BASER (device and collection tables), on MAPD command >>>> + (ITT_addr), GICR_PENDBASERs (pending tables). >>>> + >>>> + This means the GIC should be restored before the ITS and all >>>> + ITS registers but the GITS_CTRL must be restored before >>>> + restoring the ITS tables. >>>> + >>>> + Note the LPI configuration table is read-only for the >>>> + in-kernel ITS and its save/restore goes through the standard >>>> + RAM save/restore. >>>> + >>>> + The layout of the tables in guest memory defines an ABI. >>>> + The entries are laid out in memory as follows; >>>> + >>>> + Device Table Entry (DTE) layout: entry size = 16 bytes >>>> + >>>> + bits: | 63 ... 32 | 31 ... 6 | 5 | 4 ... 0 | >>>> + values: | DeviceID | Resv | V | Size | >>>> + >>>> + bits: | 63 ... 44 | 43 ... 0 | >>>> + values: | Resv | ITT_addr | >>> >>> While I appreciate this layout represents the absolute maximum an ITS >>> could implement, I'm a bit concerned about the amount of memory we may >>> end-up requiring here. All the ITSs implementations I know of seem to >>> get away with 8 bytes per entry. Maybe I'm just too worried. >> >> OK so I would propose a 16b DeviceId and 16b eventid >> >> bits: | 63 ... 48 | 47 ... 4 | 3 ... 0 | >> values: | DeviceID | ITT_addr | Size | >> >> I can use the size field as a validity indicator > > Note that you are allowed to use a 0 size field. It means 1 bit of > EventID (2 possible interrupts). So maybe using a particular address as > a valid flag? Is it really acceptable to encode the deviceId and eventid on 16 bits instead of 32 bits max each? Currently I do not use the deviceId indexing, ie. the device id is directly encoded in the entry. The spec rather suggests device id indexing in flat table and this is also stems from 2 stage table support. So I have 2 strategies: - ignore the device id indexing and store valid data at the beginning of available buffers (pros: no sparsity, cons: shrinks device and eventid to 16 bits). Natural in flat mode, less natural in 2 stage mode. - implement device id indexing (pros: keep the full range for deviceid and eventid, cons: sparsity). Then sparsity needs to be handled somehow. Now I better understand your remark on first kB of the pending table... > >> >>> >>> Also, please mention that ITT_addr is actually ITT_addr[51:8], as we're >>> guaranteed to have an ITT that is 256 byte aligned. >> sure >>> >>>> + >>>> + Collection Table Entry (CTE) layout: entry size = 8 bytes >>>> + >>>> + bits: | 63| 62 .. 52 | 51 ... 16 | 15 ... 0 | >>>> + values: | V | RES0 | RDBase | ICID | >>>> + >>>> + Interrupt Translation Table Entry (ITTE) layout: entry size = 16 bytes >>> >>> The actual name is Interrupt Translation Entry (ITE). I have a patch >>> renaming this all over the vgic-its.c file... >> ok >>> >>>> + >>>> + bits: | 63 ... 32 | 31 ... 17 | 16 | 15 ... 0 | >>>> + values: | DeviceID | RES0 | V | ICID | >>>> + >>>> + bits: | 63 ... 32 | 31 ... 0 | >>>> + values: | pINTID | EventID | >>> >>> Same concern here. 32bit DevID, EventID and INTID seem a bit over the >>> top. But maybe we shouldn't be concerned about memory... ;-) >> So I would suggest encoding >> 16b DeviceId >> 16b eventid >> 16b collection ID >> 16b pINTID >> >> bits: | 63 ... 48 | 47 ... 32 | 31 ... 15 | 15 ... 0 | >> values: | DeviceID | pINTID | EventId | ICID | >> >> a null pINTID would meen the ITE is invalid. >> >> Does that make sense or should I instead reduce the number of bits >> allocated to collections and keep the pINTID bit number larger? > > 16bit worth of collections is quite a lot (64k CPUs?). I'd be perfectly > fine with a smaller number, but let's see what people think. This is useless to store the deviceId here since the deviceId is known from the upper level device table. I will fix that in v2. But anyway if I encode the ITE on 8 bytes I must shrink the pINTID/EventId compared to their max size (32b). If EventId is encoded on 16b then I guess the pINTID should be encoded on the same number of bits. ICID on 10 bits? Thoughts? Thanks Eric > >> >> >>> >>>> + >>>> + LPI Pending Table layout: >>>> + >>>> + As specified in the ARM Generic Interrupt Controller Architecture >>>> + Specification GIC Architecture version 3.0 and version 4. The first >>>> + 1kB contains only zeros. >>>> >>> >>> You definitely want to relax this. An ITS implementation is allowed (and >>> actually encouraged) to maintain a coarse map in the first kB, and use >>> this to quickly scan the table, which would be very useful on restore. >> Maybe I miss something here. Currently I restore the ITEs before the >> pending tables. So considering all the ITEs I know which LPI are defined >> and which pending bits need to be restored. Why would I need to use a >> coarse map for? > > You could, instead of testing all the bits for which you can generate an > LPI, look at the coarse map, which usually uses one bit to represent > something like 64 bits of pending table, and find out what is currently > pending. That's what HW does, but maybe there is no need to do this for > the SW implementation, specially if we have very few LPIs. > >> I understand the CPU cannot write the pending tables in our back, spec >> says behavior would be unpredictable, right? > > Absolutely. Only the ITS can touch that memory. > > Thanks, > > M. > ^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC 01/13] KVM: arm/arm64: Add vITS save/restore API documentation [not found] ` <1484236613-24633-2-git-send-email-eric.auger@redhat.com> 2017-01-12 16:52 ` [RFC 01/13] KVM: arm/arm64: Add vITS save/restore API documentation Marc Zyngier @ 2017-02-03 14:00 ` Peter Maydell 2017-02-03 14:51 ` Marc Zyngier 1 sibling, 1 reply; 12+ messages in thread From: Peter Maydell @ 2017-02-03 14:00 UTC (permalink / raw) To: linux-arm-kernel On 12 January 2017 at 15:56, Eric Auger <eric.auger@redhat.com> wrote: > Add description for how to access vITS registers and how to flush/restore > vITS tables into/from memory > > Signed-off-by: Eric Auger <eric.auger@redhat.com> > --- > Documentation/virtual/kvm/devices/arm-vgic-its.txt | 70 ++++++++++++++++++++++ > 1 file changed, 70 insertions(+) > > diff --git a/Documentation/virtual/kvm/devices/arm-vgic-its.txt b/Documentation/virtual/kvm/devices/arm-vgic-its.txt > index 6081a5b..bd74613 100644 > --- a/Documentation/virtual/kvm/devices/arm-vgic-its.txt > +++ b/Documentation/virtual/kvm/devices/arm-vgic-its.txt > @@ -36,3 +36,73 @@ Groups: > -ENXIO: ITS not properly configured as required prior to setting > this attribute > -ENOMEM: Memory shortage when allocating ITS internal data > + > + KVM_DEV_ARM_VGIC_GRP_ITS_REGS > + Attributes: > + The attr field of kvm_device_attr encodes the offset of the > + ITS register, relative to the ITS control frame base address > + (ITS_base). > + > + kvm_device_attr.addr points to a __u64 value whatever the width > + of the addressed register (32/64 bits). > + > + Writes to read-only registers are ignored by the kernel except > + for a single register, GITS_READR. Normally this register is RO > + but it needs to be restored otherwise commands in the queue will > + be re-executed after CWRITER setting. Dumb question -- is it possible/sensible to process the command queue rather than migrating a list of outstanding commands? thanks -- PMM ^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC 01/13] KVM: arm/arm64: Add vITS save/restore API documentation 2017-02-03 14:00 ` Peter Maydell @ 2017-02-03 14:51 ` Marc Zyngier 0 siblings, 0 replies; 12+ messages in thread From: Marc Zyngier @ 2017-02-03 14:51 UTC (permalink / raw) To: linux-arm-kernel On 03/02/17 14:00, Peter Maydell wrote: > On 12 January 2017 at 15:56, Eric Auger <eric.auger@redhat.com> wrote: >> Add description for how to access vITS registers and how to flush/restore >> vITS tables into/from memory >> >> Signed-off-by: Eric Auger <eric.auger@redhat.com> >> --- >> Documentation/virtual/kvm/devices/arm-vgic-its.txt | 70 ++++++++++++++++++++++ >> 1 file changed, 70 insertions(+) >> >> diff --git a/Documentation/virtual/kvm/devices/arm-vgic-its.txt b/Documentation/virtual/kvm/devices/arm-vgic-its.txt >> index 6081a5b..bd74613 100644 >> --- a/Documentation/virtual/kvm/devices/arm-vgic-its.txt >> +++ b/Documentation/virtual/kvm/devices/arm-vgic-its.txt >> @@ -36,3 +36,73 @@ Groups: >> -ENXIO: ITS not properly configured as required prior to setting >> this attribute >> -ENOMEM: Memory shortage when allocating ITS internal data >> + >> + KVM_DEV_ARM_VGIC_GRP_ITS_REGS >> + Attributes: >> + The attr field of kvm_device_attr encodes the offset of the >> + ITS register, relative to the ITS control frame base address >> + (ITS_base). >> + >> + kvm_device_attr.addr points to a __u64 value whatever the width >> + of the addressed register (32/64 bits). >> + >> + Writes to read-only registers are ignored by the kernel except >> + for a single register, GITS_READR. Normally this register is RO >> + but it needs to be restored otherwise commands in the queue will >> + be re-executed after CWRITER setting. > > Dumb question -- is it possible/sensible to process the command > queue rather than migrating a list of outstanding commands? It is not always possible, specially if the ITS implements the "stall" mechanism, where it waits for SW acknowledgement in case of a command error. Thanks, M. -- Jazz is not dead. It just smells funny... ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2017-02-03 14:51 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-01-12 15:56 [RFC 00/13] vITS save/restore Eric Auger [not found] ` <1484236613-24633-8-git-send-email-eric.auger@redhat.com> 2017-01-12 17:05 ` [RFC 07/13] KVM: arm64: ITS: Change entry_size and indirect bit in BASER Marc Zyngier 2017-01-13 8:57 ` Auger Eric 2017-01-13 9:22 ` Marc Zyngier [not found] ` <1484236613-24633-7-git-send-email-eric.auger@redhat.com> 2017-01-12 17:06 ` [RFC 06/13] KVM: arm64: ITS: Expose ITT_Entry_Size in GITS_TYPER Andre Przywara 2017-01-13 8:31 ` Auger Eric [not found] ` <1484236613-24633-2-git-send-email-eric.auger@redhat.com> 2017-01-12 16:52 ` [RFC 01/13] KVM: arm/arm64: Add vITS save/restore API documentation Marc Zyngier 2017-01-13 9:07 ` Auger Eric 2017-01-13 9:46 ` Marc Zyngier 2017-01-30 16:15 ` Auger Eric 2017-02-03 14:00 ` Peter Maydell 2017-02-03 14:51 ` Marc Zyngier
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).