[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 03/27] ARM: GICv3 ITS: allocate device and collection table
Hi, On 22/03/17 13:52, Julien Grall wrote: > Hi Andre, > > On 03/16/2017 11:20 AM, Andre Przywara wrote: >> Each ITS maps a pair of a DeviceID (for instance derived from a PCI >> b/d/f triplet) and an EventID (the MSI payload or interrupt ID) to a >> pair of LPI number and collection ID, which points to the target CPU. >> This mapping is stored in the device and collection tables, which >> software >> has to provide for the ITS to use. >> Allocate the required memory and hand it to the ITS. >> The maximum number of devices is limited to a compile-time constant >> exposed in Kconfig. >> >> Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx> >> --- >> docs/misc/xen-command-line.markdown | 8 ++ >> xen/arch/arm/Kconfig | 14 ++++ >> xen/arch/arm/gic-v3-its.c | 163 >> ++++++++++++++++++++++++++++++++++++ >> xen/arch/arm/gic-v3.c | 3 + >> xen/include/asm-arm/gic_v3_its.h | 63 +++++++++++++- >> 5 files changed, 250 insertions(+), 1 deletion(-) >> >> diff --git a/docs/misc/xen-command-line.markdown >> b/docs/misc/xen-command-line.markdown >> index 619016d..068d116 100644 >> --- a/docs/misc/xen-command-line.markdown >> +++ b/docs/misc/xen-command-line.markdown >> @@ -1158,6 +1158,14 @@ based interrupts. Any higher IRQs will be >> available for use via PCI MSI. >> ### maxcpus >> > `= <integer>` >> >> +### max\_its\_device\_bits >> +> `= <integer>` >> + >> +Specifies the maximum number of devices using MSIs on the ARM GICv3 ITS >> +controller to allocate table entries for. Each table entry uses a >> hardware >> +specific size, typically 8 or 16 bytes. >> +Defaults to 10 bits (to cover at most 1024 devices). > > The description is misleading. Even if the platform has less than 1024 > devices, 10 may not be enough if the Device ID are not contiguous. Right. > However, I don't think this is useful. A user may not know the DevIDs in > use of the platform and hence will not be able to choose a sensible value. > > I still think that we should allocate what the hardware asked us and if > it is necessary to limit this should be done per-platform. I think you are right, a configurable limit does not make much sense. I was wondering if we should have a hard coded *memory* limit instead, to prevent ridiculously high allocations, say entry_size=8 and 32 bits of device IDs, which would result in 32GB of memory for a flat device table. Or if we don't want to arbitrarily limit this, we always print the actual allocated size, maybe with a extra WARNING if it exceeds sane levels. >> + >> ### max\_lpi\_bits >> > `= <integer>` >> >> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig >> index 86f7b53..0d50156 100644 >> --- a/xen/arch/arm/Kconfig >> +++ b/xen/arch/arm/Kconfig >> @@ -64,6 +64,20 @@ config MAX_PHYS_LPI_BITS >> This can be overridden on the command line with the >> max_lpi_bits >> parameter. >> >> +config MAX_PHYS_ITS_DEVICE_BITS >> + depends on HAS_ITS >> + int "Number of device bits the ITS supports" >> + range 1 32 >> + default "10" >> + help >> + Specifies the maximum number of devices which want to use >> the ITS. >> + Xen needs to allocates memory for the whole range very early. >> + The allocation scheme may be sparse, so a much larger >> number must >> + be supported to cover devices with a high bus number or >> those on >> + separate bus segments. >> + This can be overridden on the command line with the >> + max_its_device_bits parameter. > > From what I understand the default you suggested fit neither Cavium nor > Qualcomm platform. It is also hard to see how a Distribution will be > able to choose a sensible value here. But it works for me (TM) ;-) I was hoping that people would scream and suggest usable values instead (because I don't know their limits). But indeed lets just remove that in favor of something more future proof. >> + >> endmenu >> >> menu "ARM errata workaround via the alternative framework" >> diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c >> index 4056e5b..9982fe9 100644 >> --- a/xen/arch/arm/gic-v3-its.c >> +++ b/xen/arch/arm/gic-v3-its.c > > [...] > >> +static int its_map_baser(void __iomem *basereg, uint64_t regc, >> + unsigned int nr_items) >> +{ >> + uint64_t attr, reg; >> + unsigned int entry_size = GITS_BASER_ENTRY_SIZE(regc); >> + unsigned int pagesz = 2, order, table_size; > > Please document what mean 2. > >> + void *buffer; >> + >> + attr = GIC_BASER_InnerShareable << GITS_BASER_SHAREABILITY_SHIFT; >> + attr |= GIC_BASER_CACHE_SameAsInner << >> GITS_BASER_OUTER_CACHEABILITY_SHIFT; >> + attr |= GIC_BASER_CACHE_RaWaWb << >> GITS_BASER_INNER_CACHEABILITY_SHIFT; >> + >> + /* >> + * Setup the BASE register with the attributes that we like. Then >> read >> + * it back and see what sticks (page size, cacheability and >> shareability >> + * attributes), retrying if necessary. >> + */ >> +retry: >> + table_size = ROUNDUP(nr_items * entry_size, >> BIT(BASER_PAGE_BITS(pagesz))); >> + /* The BASE registers support at most 256 pages. */ >> + table_size = min(table_size, 256U << BASER_PAGE_BITS(pagesz)); >> + /* The memory block must be aligned to the requested page size. */ >> + order = max(get_order_from_bytes(table_size), pagesz * 2); >> + >> + buffer = alloc_xenheap_pages(order, 0); > > Why don't you use _zalloc(...)? This would avoid to compute the order > and drop few lines. Because they need to be physically contiguous. Please correct me if I am wrong here, but the normal *alloc functions do not guarantee this (from checking the implementation). >> + if ( !buffer ) >> + return -ENOMEM; >> + >> + if ( !check_propbaser_phys_addr(buffer, BASER_PAGE_BITS(pagesz)) ) > > The name of the function does not make sense. You check an address for > the register BASER and not PROPBASER. Indeed. >> + { >> + free_xenheap_pages(buffer, 0); >> + return -ERANGE; >> + } >> + memset(buffer, 0, table_size); > > [...] > >> +int gicv3_its_init(void) >> +{ >> + struct host_its *hw_its; >> + int ret; >> + >> + list_for_each_entry(hw_its, &host_its_list, entry) { > > Coding style: > > list_for_each_entry(....) > { Yeah, I was looking at the Linux driver at the same time ;-) >> + ret = gicv3_its_init_single_its(hw_its); >> + if ( ret ) >> + return ret; >> + } >> + >> + return 0; >> +} >> + >> /* Scan the DT for any ITS nodes and create a list of host ITSes out >> of it. */ >> void gicv3_its_dt_init(const struct dt_device_node *node) >> { >> diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c >> index ed78363..cc1e219 100644 >> --- a/xen/arch/arm/gic-v3.c >> +++ b/xen/arch/arm/gic-v3.c >> @@ -1590,6 +1590,9 @@ static int __init gicv3_init(void) >> spin_lock(&gicv3.lock); >> >> gicv3_dist_init(); >> + res = gicv3_its_init(); >> + if ( res ) >> + printk(XENLOG_WARNING "GICv3: ITS: initialization failed: >> %d\n", res); > > I would have expect a panic here because the ITS subsystem could be half > initialized and it is not safe to continue. OK, let me check what actually happens here if there is no ITS ;-) Cheers, Andre > >> res = gicv3_cpu_init(); >> gicv3_hyp_init(); >> > > Cheers, > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |