[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 001/114] hw/arm/smmuv3: Another range invalidation fix
From: |
Peter Maydell |
Subject: |
[PULL 001/114] hw/arm/smmuv3: Another range invalidation fix |
Date: |
Tue, 25 May 2021 16:01:31 +0100 |
From: Eric Auger <eric.auger@redhat.com>
6d9cd115b9 ("hw/arm/smmuv3: Enforce invalidation on a power of two range")
failed to completely fix misalignment issues with range
invalidation. For instance invalidations patterns like "invalidate 32
4kB pages starting from 0xff395000 are not correctly handled" due
to the fact the previous fix only made sure the number of invalidated
pages were a power of 2 but did not properly handle the start
address was not aligned with the range. This can be noticed when
boothing a fedora 33 with protected virtio-blk-pci.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Fixes: 6d9cd115b9 ("hw/arm/smmuv3: Enforce invalidation on a power of two
range")
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/smmuv3.c | 50 +++++++++++++++++++++++++------------------------
1 file changed, 26 insertions(+), 24 deletions(-)
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 7bed2ac520b..01b60bee495 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -857,43 +857,45 @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, int
asid, dma_addr_t iova,
static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
{
- uint8_t scale = 0, num = 0, ttl = 0;
- dma_addr_t addr = CMD_ADDR(cmd);
+ dma_addr_t end, addr = CMD_ADDR(cmd);
uint8_t type = CMD_TYPE(cmd);
uint16_t vmid = CMD_VMID(cmd);
+ uint8_t scale = CMD_SCALE(cmd);
+ uint8_t num = CMD_NUM(cmd);
+ uint8_t ttl = CMD_TTL(cmd);
bool leaf = CMD_LEAF(cmd);
uint8_t tg = CMD_TG(cmd);
- uint64_t first_page = 0, last_page;
- uint64_t num_pages = 1;
+ uint64_t num_pages;
+ uint8_t granule;
int asid = -1;
- if (tg) {
- scale = CMD_SCALE(cmd);
- num = CMD_NUM(cmd);
- ttl = CMD_TTL(cmd);
- num_pages = (num + 1) * BIT_ULL(scale);
- }
-
if (type == SMMU_CMD_TLBI_NH_VA) {
asid = CMD_ASID(cmd);
}
+ if (!tg) {
+ trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, 1, ttl, leaf);
+ smmuv3_inv_notifiers_iova(s, asid, addr, tg, 1);
+ smmu_iotlb_inv_iova(s, asid, addr, tg, 1, ttl);
+ return;
+ }
+
+ /* RIL in use */
+
+ num_pages = (num + 1) * BIT_ULL(scale);
+ granule = tg * 2 + 10;
+
/* Split invalidations into ^2 range invalidations */
- last_page = num_pages - 1;
- while (num_pages) {
- uint8_t granule = tg * 2 + 10;
- uint64_t mask, count;
+ end = addr + (num_pages << granule) - 1;
- mask = dma_aligned_pow2_mask(first_page, last_page, 64 - granule);
- count = mask + 1;
+ while (addr != end + 1) {
+ uint64_t mask = dma_aligned_pow2_mask(addr, end, 64);
- trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, count, ttl, leaf);
- smmuv3_inv_notifiers_iova(s, asid, addr, tg, count);
- smmu_iotlb_inv_iova(s, asid, addr, tg, count, ttl);
-
- num_pages -= count;
- first_page += count;
- addr += count * BIT_ULL(granule);
+ num_pages = (mask + 1) >> granule;
+ trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, num_pages, ttl,
leaf);
+ smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages);
+ smmu_iotlb_inv_iova(s, asid, addr, tg, num_pages, ttl);
+ addr += mask + 1;
}
}
--
2.20.1
- [PULL 000/114] target-arm queue, Peter Maydell, 2021/05/25
- [PULL 001/114] hw/arm/smmuv3: Another range invalidation fix,
Peter Maydell <=
- [PULL 003/114] hw/arm/mps2-tz: Don't duplicate modelling of SRAM in AN524, Peter Maydell, 2021/05/25
- [PULL 002/114] hw/intc/arm_gicv3_cpuif: Fix EOIR write access check logic, Peter Maydell, 2021/05/25
- [PULL 004/114] hw/arm/mps2-tz: Make SRAM_ADDR_WIDTH board-specific, Peter Maydell, 2021/05/25
- [PULL 009/114] target/arm: Use correct SP in M-profile exception return, Peter Maydell, 2021/05/25
- [PULL 008/114] hw/arm: Model TCMs in the SSE-300, not the AN547, Peter Maydell, 2021/05/25
- [PULL 005/114] hw/arm/armsse.c: Correct modelling of SSE-300 internal SRAMs, Peter Maydell, 2021/05/25
- [PULL 007/114] hw/arm/mps2-tz: Allow board to specify a boot RAM size, Peter Maydell, 2021/05/25
- [PULL 011/114] accel/tcg: Pass length argument to tlb_flush_range_locked(), Peter Maydell, 2021/05/25
- [PULL 010/114] accel/tcg: Replace g_new() + memcpy() by g_memdup(), Peter Maydell, 2021/05/25
- [PULL 006/114] hw/arm/armsse: Convert armsse_realize() to use ERRP_GUARD, Peter Maydell, 2021/05/25