[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v9 3/8] system/physmem: Support IOMMU granularity smaller than TA
From: |
Ethan Chen |
Subject: |
[PATCH v9 3/8] system/physmem: Support IOMMU granularity smaller than TARGET_PAGE size |
Date: |
Thu, 9 Jan 2025 10:44:36 +0800 |
If the IOMMU granularity is smaller than the TARGET_PAGE size, there may be
multiple entries within the same page. To obtain the correct result, pass
the original address to the IOMMU.
Similar to the RISC-V PMP solution, the TLB_INVALID_MASK will be set when
there are multiple entries in the same page, ensuring that the IOMMU is
checked on every access.
Signed-off-by: Ethan Chen <ethan84@andestech.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
---
accel/tcg/cputlb.c | 20 ++++++++++++++++----
system/physmem.c | 4 ++++
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 71c16a1ac1..ed55f02eab 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1063,8 +1063,23 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx,
prot = full->prot;
asidx = cpu_asidx_from_attrs(cpu, full->attrs);
- section = address_space_translate_for_iotlb(cpu, asidx, paddr_page,
+ section = address_space_translate_for_iotlb(cpu, asidx, full->phys_addr,
&xlat, &sz, full->attrs,
&prot);
+ /* Update page size */
+ full->lg_page_size = ctz64(sz);
+ if (full->lg_page_size > TARGET_PAGE_BITS) {
+ full->lg_page_size = TARGET_PAGE_BITS;
+ } else {
+ sz = TARGET_PAGE_SIZE;
+ }
+
+ is_ram = memory_region_is_ram(section->mr);
+ is_romd = memory_region_is_romd(section->mr);
+ /* If the translated mr is ram/rom, make xlat align the TARGET_PAGE */
+ if (is_ram || is_romd) {
+ xlat &= TARGET_PAGE_MASK;
+ }
+
assert(sz >= TARGET_PAGE_SIZE);
tlb_debug("vaddr=%016" VADDR_PRIx " paddr=0x" HWADDR_FMT_plx
@@ -1077,9 +1092,6 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx,
read_flags |= TLB_INVALID_MASK;
}
- is_ram = memory_region_is_ram(section->mr);
- is_romd = memory_region_is_romd(section->mr);
-
if (is_ram || is_romd) {
/* RAM and ROMD both have associated host memory. */
addend = (uintptr_t)memory_region_get_ram_ptr(section->mr) + xlat;
diff --git a/system/physmem.c b/system/physmem.c
index c76503aea8..d64543b413 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -702,6 +702,10 @@ address_space_translate_for_iotlb(CPUState *cpu, int
asidx, hwaddr orig_addr,
iotlb = imrc->translate(iommu_mr, addr, IOMMU_NONE, iommu_idx);
addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
| (addr & iotlb.addr_mask));
+ /* Update size */
+ if (iotlb.addr_mask != -1 && *plen > iotlb.addr_mask + 1) {
+ *plen = iotlb.addr_mask + 1;
+ }
/* Update the caller's prot bits to remove permissions the IOMMU
* is giving us a failure response for. If we get down to no
* permissions left at all we can give up now.
--
2.34.1
- [PATCH v9 0/8] Support RISC-V IOPMP, Ethan Chen, 2025/01/08
- [PATCH v9 1/8] hw/core: Add config stream, Ethan Chen, 2025/01/08
- [PATCH v9 2/8] memory: Introduce memory region fetch operation, Ethan Chen, 2025/01/08
- [PATCH v9 3/8] system/physmem: Support IOMMU granularity smaller than TARGET_PAGE size,
Ethan Chen <=
- [PATCH v9 4/8] target/riscv: Add support for IOPMP, Ethan Chen, 2025/01/08
- [PATCH v9 5/8] hw/misc/riscv_iopmp_txn_info: Add struct for transaction infomation, Ethan Chen, 2025/01/08
- [PATCH v9 6/8] hw/misc/riscv_iopmp: Add RISC-V IOPMP device, Ethan Chen, 2025/01/08
- [PATCH v9 8/8] hw/riscv/virt: Add IOPMP support, Ethan Chen, 2025/01/08
- [PATCH v9 7/8] hw/misc/riscv_iopmp_dispatcher: Device for redirect IOPMP transaction infomation, Ethan Chen, 2025/01/08