This patchset tries to fix the PMP bypass problem issue 
https://gitlab.com/qemu-project/qemu/-/issues/1542:

TLB will be cached if the matched PMP entry cover the whole page.  However PMP 
entries with higher priority may cover part of the page (but not match the 
access address), which means different regions in this page may have different 
permission rights. So it also cannot be cached (patch 1).

Writing to pmpaddr didn't trigger tlb flush (patch 3).

We set the tlb_size to 1 to make the TLB_INVALID_MASK set, and and the next 
access will again go through tlb_fill. However, this way will not work in 
tb_gen_code() => get_page_addr_code_hostp(): the TLB host address will be 
cached, and the following instructions can use this host address directly which 
may lead to the bypass of PMP related check (patch 5).

The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-pmp-fix-v4

v4:

Update comments for Patch 1, and move partial check code from Patch 2 to Patch 1

Restore log message change in Patch 2

Update commit message and the way to improve the problem in Patch 6


v3:

Ignore disabled PMP entry in pmp_get_tlb_size() in Patch 1

Drop Patch 5, since tb jmp cache have been flushed in tlb_flush, so flush tb 
seems unnecessary.

Fix commit message problems in Patch 8 (Patch 7 in new patchset)


v2:

Update commit message for patch 1

Add default tlb_size when pmp is diabled or there is no rules and only get the 
tlb size when translation success in patch 2

Update get_page_addr_code_hostp instead of probe_access_internal to fix the 
cached host address for instruction fetch in patch 6

Add patch 7 to make the short up really work in pmp_hart_has_privs

Add patch 8 to use pmp_update_rule_addr() and pmp_update_rule_nums() separately


Weiwei Li (7):
  target/riscv: Update pmp_get_tlb_size()
  target/riscv: Move pmp_get_tlb_size apart from
    get_physical_address_pmp
  target/riscv: Flush TLB when pmpaddr is updated
  target/riscv: Flush TLB only when pmpcfg/pmpaddr really changes
  accel/tcg: Uncache the host address for instruction fetch when tlb
    size < 1
  target/riscv: Make the short cut really work in pmp_hart_has_privs
  target/riscv: Separate pmp_update_rule() in pmpcfg_csr_write

 accel/tcg/cputlb.c        |  5 +++
 target/riscv/cpu_helper.c | 19 +++-----
 target/riscv/pmp.c        | 91 +++++++++++++++++++++++++++++----------
 target/riscv/pmp.h        |  3 +-
 4 files changed, 80 insertions(+), 38 deletions(-)

-- 
2.25.1


Reply via email to