The logic of gicv3_redist_update() is as follows:
* it must be called in any code path that changes the state of
(only) redistributor interrupts
* if it finds a redistributor interrupt that is (now) higher
priority than the previous highest-priority pending interrupt,
then this must be the new highest-priority pending interrupt
* if it does *not* find a better redistributor interrupt, then:
- if the previous state was "no interrupts pending" then
the new state is still "no interrupts pending"
- if the previous best interrupt was not a redistributor
interrupt then that remains the best interrupt
- if the previous best interrupt *was* a redistributor interrupt,
then the new best interrupt must be some non-redistributor
interrupt, but we don't know which so must do a full scan
In commit 17fb5e36aa we effectively added the LPI interrupts
as a kind of "redistributor interrupt" for this purpose, by adding
cs->hpplpi to the set of things that gicv3_redist_update() considers
before it gives up and decides to do a full scan of distributor
interrupts. However we didn't quite get this right:
* the condition check for "was the previous best interrupt a
redistributor interrupt" must be updated to include LPIs
in what it considers to be redistributor interrupts
* every code path which updates the LPI state which
gicv3_redist_update() checks must also call gicv3_redist_update():
this is cs->hpplpi and the GICR_CTLR ENABLE_LPIS bit
This commit fixes this by:
* correcting the test on cs->hppi.irq in gicv3_redist_update()
* making gicv3_redist_update_lpi() always call gicv3_redist_update()
* introducing a new gicv3_redist_update_lpi_only() for the one
callsite (the post-load hook) which must not call
gicv3_redist_update()
* making gicv3_redist_lpi_pending() always call gicv3_redist_update(),
either directly or via gicv3_redist_update_lpi()
* removing a couple of now-unnecessary calls to gicv3_redist_update()
from some callers of those two functions
* calling gicv3_redist_update() when the GICR_CTLR ENABLE_LPIS
bit is cleared
(This means that the not-file-local gicv3_redist_* LPI related
functions now all take care of the updates of internally cached
GICv3 information, in the same way the older functions
gicv3_redist_set_irq() and gicv3_redist_send_sgi() do.)
The visible effect of this bug was that when the guest acknowledged
an LPI by reading ICC_IAR1_EL1, we marked it as not pending in the
LPI data structure but still left it in cs->hppi so we would offer it
to the guest again. In particular for setups using an emulated GICv3
and ITS and using devices which use LPIs (ie PCI devices) a Linux
guest would complain "irq 54: nobody cared" and then hang. (The hang
was intermittent, presumably depending on the timing between
different interrupts arriving and being completed.)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20211124202005.989935-1-peter.maydell@linaro.org
Our GICv3 QOM interface includes an array property
redist-region-count which allows board models to specify that the
registributor registers are not in a single contiguous range, but
split into multiple pieces. We implemented this for KVM, but
currently the TCG GICv3 model insists that there is only one region.
You can see the limit being hit with a setup like:
qemu-system-aarch64 -machine virt,gic-version=3 -smp 124
Add support for split regions to the TCG GICv3. To do this we switch
from allocating a simple array of MemoryRegions to an array of
GICv3RedistRegion structs so that we can use the GICv3RedistRegion as
the opaque pointer in the MemoryRegion read/write callbacks. Each
GICv3RedistRegion contains the MemoryRegion, a backpointer allowing
the read/write callback to get hold of the GICv3State, and an index
which allows us to calculate which CPU's redistributor is being
accessed.
Note that arm_gicv3_kvm always passes in NULL as the ops argument
to gicv3_init_irqs_and_mmio(), so the only MemoryRegion read/write
callbacks we need to update to handle this new scheme are the
gicv3_redist_read/write functions used by the emulated GICv3.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Implemented lpi processing at redistributor to get lpi config info
from lpi configuration table,determine priority,set pending state in
lpi pending table and forward the lpi to cpuif.Added logic to invoke
redistributor lpi processing with translated LPI which set/clear LPI
from ITS device as part of ITS INT,CLEAR,DISCARD command and
GITS_TRANSLATER processing.
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20210910143951.92242-7-shashi.mallela@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
When either GICD_IPRIORITYR or GICR_IPRIORITYR is read as a 32-bit
register, the post left-shift operator in the for loop causes an
extra shift after the least significant byte has been placed.
The 32-bit value actually returned is therefore the expected value
shifted left by 8 bits.
Signed-off-by: Amol Surati <suratiamol@gmail.com>
Message-id: 20180614054857.26248-1-suratiamol@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Coverity complains that the GICR_IPRIORITYR case in gicv3_readl()
can overflow an array, because it doesn't know that the offsets
passed to that function must be word aligned. Add some assert()s
which hopefully tell Coverity that this isn't possible.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1468261372-17508-1-git-send-email-peter.maydell@linaro.org