From 80a1c934d4d234dd7dc88bc9986020726891124b Mon Sep 17 00:00:00 2001 From: Hasmet Akgun Date: Sat, 4 Apr 2026 20:31:29 -0500 Subject: [PATCH 1/8] Fix duplicate addition of mop_rr_7 --- disasm/disasm.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/disasm/disasm.cc b/disasm/disasm.cc index df56ff50..de3e7d2a 100644 --- a/disasm/disasm.cc +++ b/disasm/disasm.cc @@ -2086,7 +2086,6 @@ void disassembler_t::add_instructions(const isa_parser_t* isa, bool strict) DEFINE_RTYPE(mop_rr_4); DEFINE_RTYPE(mop_rr_5); DEFINE_RTYPE(mop_rr_6); - DEFINE_RTYPE(mop_rr_7); if (!ext_enabled_strict(EXT_ZICFISS)) { DEFINE_RTYPE(mop_rr_7); } else { From a515bc5205be023ab01d047afc4085676a328ee2 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 6 Apr 2026 15:23:20 -0700 Subject: [PATCH 2/8] Remove extraneous comment --- riscv/mmu.h | 1 - 1 file changed, 1 deletion(-) diff --git a/riscv/mmu.h b/riscv/mmu.h index 5ba0854e..2884fea5 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -173,7 +173,6 @@ public: try { \ BODY \ } catch (trap_load_address_misaligned& t) { \ - /* Misaligned fault will not be triggered by Zicbom */ \ throw trap_store_address_misaligned(t.has_gva(), t.get_tval(), t.get_tval2(), t.get_tinst()); \ } catch (trap_load_page_fault& t) { \ throw trap_store_page_fault(t.has_gva(), t.get_tval(), t.get_tval2(), t.get_tinst()); \ From 2219879651c6f7e6488c22286cd26aecb90c16e4 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 6 Apr 2026 15:23:39 -0700 Subject: [PATCH 3/8] Use underscore to indicate unused tuple field --- riscv/mmu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/riscv/mmu.h b/riscv/mmu.h index 2884fea5..ee8ebd15 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -252,7 +252,7 @@ public: store_slow_path(vaddr, size, nullptr, {}, false, true); } - auto [tlb_hit, host_addr, paddr] = access_tlb(tlb_store, vaddr); + auto [tlb_hit, _, paddr] = access_tlb(tlb_store, vaddr); if (!tlb_hit) paddr = translate(generate_access_info(vaddr, STORE, {}), 1); From 0d05926e3e627e6c9f81ecb9a4798dd0d6385407 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 6 Apr 2026 15:29:32 -0700 Subject: [PATCH 4/8] Convert ssamoswap load traps to store traps The difference can manifest when checking triggers. --- riscv/mmu.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/riscv/mmu.h b/riscv/mmu.h index ee8ebd15..f1fac1be 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -196,10 +196,12 @@ public: // for shadow stack amoswap template T ssamoswap(reg_t addr, reg_t value) { + convert_load_traps_to_store_traps({ store_slow_path(addr, sizeof(T), nullptr, {.ss_access=true}, false, true); auto data = load(addr, {.ss_access=true}); store(addr, value, {.ss_access=true}); return data; + }) } template From 79ac5e936854fb65cc790fc71e8c769fd7159e4c Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 6 Apr 2026 15:46:22 -0700 Subject: [PATCH 5/8] Correctly check for misalignment on SC/AMO --- riscv/mmu.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/riscv/mmu.cc b/riscv/mmu.cc index e2ca0f03..8a61ad14 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -377,8 +377,9 @@ void mmu_t::store_slow_path(reg_t original_addr, std::size_t len, auto [tlb_hit, host_addr, paddr] = access_tlb(tlb_store, original_addr, TLB_FLAGS & ~TLB_CHECK_TRIGGERS); bool intrapage = (original_addr % PGSIZE) + len <= PGSIZE; bool aligned = (original_addr & (len - 1)) == 0; + bool misaligned_ok = !require_alignment && intrapage && is_misaligned_enabled(); - if (likely(tlb_hit && (aligned || (intrapage && is_misaligned_enabled())))) { + if (likely(tlb_hit && (aligned || misaligned_ok))) { if (actually_store) perform_intrapage_store(original_addr, host_addr, paddr, len, bytes, xlate_flags); return; From 5ea492ac8d31e0dbe93a11cc95e503e610fccebc Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 6 Apr 2026 15:46:38 -0700 Subject: [PATCH 6/8] Check triggers for store_slow_path with !actually_store Fixes #2262 --- riscv/mmu.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 8a61ad14..7b7112fd 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -389,9 +389,15 @@ void mmu_t::store_slow_path(reg_t original_addr, std::size_t len, auto access_info = generate_access_info(original_addr, STORE, xlate_flags); reg_t transformed_addr = access_info.transformed_vaddr; - if (actually_store && check_triggers_store) - check_triggers(triggers::OPERATION_STORE, - transformed_addr, access_info.effective_virt, len, bytes); + if (check_triggers_store) { + if (actually_store) { + check_triggers(triggers::OPERATION_STORE, + transformed_addr, access_info.effective_virt, len, bytes); + } else { + check_triggers(triggers::OPERATION_STORE, + transformed_addr, access_info.effective_virt, len); + } + } if (transformed_addr & (len - 1)) { bool gva = access_info.effective_virt; From 4172e1a2cc85cce09a68516c6d6567cba62637ee Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 6 Apr 2026 15:56:43 -0700 Subject: [PATCH 7/8] Implement Zama16b extension --- disasm/isa_parser.cc | 2 ++ riscv/isa_parser.h | 1 + riscv/mmu.h | 12 ++++++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/disasm/isa_parser.cc b/disasm/isa_parser.cc index 4f48e5f9..3e80fc46 100644 --- a/disasm/isa_parser.cc +++ b/disasm/isa_parser.cc @@ -100,6 +100,8 @@ void isa_parser_t::add_extension(const std::string& ext_str, const char* str) } else if (ext_str == "zawrs") { extension_table[EXT_ZAWRS] = true; extension_table[EXT_ZALRSC] = true; + } else if (ext_str == "zama16b") { + extension_table[EXT_ZAMA16B] = true; } else if (ext_str == "zmmul") { extension_table[EXT_ZMMUL] = true; } else if (ext_str == "zba") { diff --git a/riscv/isa_parser.h b/riscv/isa_parser.h index ada74c76..bf65805e 100644 --- a/riscv/isa_parser.h +++ b/riscv/isa_parser.h @@ -95,6 +95,7 @@ typedef enum { EXT_ZACAS, EXT_ZABHA, EXT_ZAWRS, + EXT_ZAMA16B, EXT_INTERNAL_ZFH_MOVE, EXT_SMCSRIND, EXT_SSCSRIND, diff --git a/riscv/mmu.h b/riscv/mmu.h index f1fac1be..1ab83647 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -182,11 +182,19 @@ public: throw trap_store_guest_page_fault(t.get_tval(), t.get_tval2(), t.get_tinst()); \ } + inline bool enforce_amo_alignment(reg_t addr, size_t size) + { + if (proc->extension_enabled(EXT_ZAMA16B)) + return (addr / 16) != ((addr + size - 1) / 16); + + return true; + } + // template for functions that perform an atomic memory operation template T amo(reg_t addr, op f) { convert_load_traps_to_store_traps({ - store_slow_path(addr, sizeof(T), nullptr, {}, false, true); + store_slow_path(addr, sizeof(T), nullptr, {}, false, enforce_amo_alignment(addr, sizeof(T))); auto lhs = load(addr); store(addr, f(lhs)); return lhs; @@ -207,7 +215,7 @@ public: template T amo_compare_and_swap(reg_t addr, T comp, T swap) { convert_load_traps_to_store_traps({ - store_slow_path(addr, sizeof(T), nullptr, {}, false, true); + store_slow_path(addr, sizeof(T), nullptr, {}, false, enforce_amo_alignment(addr, sizeof(T))); auto lhs = load(addr); if (lhs == comp) store(addr, swap); From f05baff9f4703c9c6f9027e07b36f0da7af57047 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 6 Apr 2026 16:06:33 -0700 Subject: [PATCH 8/8] Remove unused UNUSED --- riscv/mmu.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 7b7112fd..5c57679f 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -370,7 +370,7 @@ void mmu_t::store_slow_path_intrapage(reg_t len, const uint8_t* bytes, mem_acces void mmu_t::store_slow_path(reg_t original_addr, std::size_t len, const std::uint8_t* bytes, xlate_flags_t xlate_flags, - bool actually_store, bool UNUSED require_alignment) + bool actually_store, bool require_alignment) { if (likely(!xlate_flags.is_special_access())) { // Fast path for simple cases