Skip to content

H extention#735

Open
jensen-yan wants to merge 3 commits intoxs-devfrom
h-extention
Open

H extention#735
jensen-yan wants to merge 3 commits intoxs-devfrom
h-extention

Conversation

@jensen-yan
Copy link
Collaborator

@jensen-yan jensen-yan commented Jan 26, 2026

cherry-pick from upstream gem5,
https://github.com/OpenXiangShan/riscv-hyp-tests
for this unit-tests, still have bugs.

Summary by CodeRabbit

  • New Features

    • Added broad RISC-V hypervisor support: hypervisor load/store operations, new fence/invalidation instructions, and new memory-translation templates for hyper modes.
    • Introduced new memory-translation flags to force guest virtual translation and to adjust execute/HLVX semantics.
  • Bug Fixes

    • Improved load-reserved memory-barrier handling.
    • Fixed namespace/formatting closure to ensure correct build behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

Navyera and others added 2 commits January 26, 2026 13:06
- Hypervisor Loads, Stores, Fences, etc.
- Small change to enable H-extension in RiscvISA.py by default

Change-Id: I033ea064b904dfcb6bcff2a2dc0424113e47e245
Change-Id: I137147dafbebe700213f9f1469a5f335a9062c43
@github-actions
Copy link

🚀 Performance test triggered: spec06-0.8c

@coderabbitai
Copy link

coderabbitai bot commented Jan 26, 2026

📝 Walkthrough

Walkthrough

This PR adds hypervisor-focused load/store and fence instructions, hypervisor-aware memory flags and templates, MIDELEG CSR read handling, new memflags definitions, and updates TLB/page-table walker permission logic to propagate HLVX/FORCE_VIRT semantics.

Changes

Cohort / File(s) Summary
ISA Core & Includes
src/arch/riscv/isa.cc, src/arch/riscv/isa/includes.isa
Added MISCREG_MIDELEG handling in ISA::readMiscReg; included memflags.hh and regs/misc.hh in decoder output; fixed missing closing brace/EOF formatting.
Decoder: Hypervisor Instrs
src/arch/riscv/isa/decoder.isa
Added HLV/HSV instruction families and VVMA/GVMA fence/invalidate variants with privilege/H-extension checks; many new hypervisor memory op paths use FORCE_VIRT/HLVX mem flags; removed one LoadH path and added not-implemented fallbacks.
Memory Formats & Templates
src/arch/riscv/isa/formats/mem.isa, src/arch/riscv/isa/formats/amo.isa, src/arch/riscv/isa/vector/base/vector_mem.isa
Refactored mem_flags wrapping to avoid -Wparentheses; introduced HyperLoad/HyperStore templates and formats (Execute/InitiateAcc/CompleteAcc variants) integrating H-extension semantics into load/store flow.
Translation Flags Header
src/arch/riscv/memflags.hh
New header defining gem5::RiscvISA::XlateFlags with FORCE_VIRT, HLVX, and LR constants and a static_assert ensuring fit in Request::ARCH_BITS.
Page Table Walker
src/arch/riscv/pagetable_walker.cc, src/arch/riscv/pagetable.hh
Added PTE fields (n, pbmt, reserved) and checks; isHInst now derives from request flags or explicit h_inst; walker enforces reserved/pbmt gating and propagates h-inst/HLVX into permission checks.
TLB Permission Logic & APIs
src/arch/riscv/tlb.hh, src/arch/riscv/tlb.cc
Threaded ThreadContext* and hlvx through permission APIs (checkPermissions, checkGPermissions, L2TLBCheck); added hlvx-aware permission logic, PBMT/reserved-PTE handling, and FORCE_VIRT-triggered virtual addressing paths.

Sequence Diagram

sequenceDiagram
    participant Decoder
    participant Exec as InstExecutor
    participant TLB
    participant PTW as PageTableWalker
    participant Memory

    Decoder->>Exec: Decode HLV/HSV, set mem_flags (FORCE_VIRT/HLVX)
    Exec->>TLB: Translate request (flags in Request)
    activate TLB
    TLB->>TLB: Extract hlvx / FORCE_VIRT from Request flags
    alt Two-stage (G+VS)
        TLB->>PTW: Start G-stage walk (hlvx)
        activate PTW
        PTW->>PTW: Validate PTE bits, check permissions (hlvx-aware)
        PTW-->>TLB: G-stage result
        deactivate PTW

        TLB->>PTW: Start VS-stage walk (hlvx)
        activate PTW
        PTW->>PTW: Validate PTE bits, check permissions (hlvx-aware)
        PTW-->>TLB: VS-stage result
        deactivate PTW
    else Single-stage
        TLB->>PTW: Start leaf walk (hlvx)
        activate PTW
        PTW->>PTW: Validate PTE, check permissions (hlvx-aware)
        PTW-->>TLB: Translation result
        deactivate PTW
    end
    deactivate TLB
    Exec->>Memory: Access using translated address
    Memory-->>Exec: Return data / fault
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • tastynoob
  • Yakkhini

Poem

🐰 I hopped through pages, flags held tight,
HLVX whispers through the TLB night.
FORCE_VIRT nudged a virt walk start,
MIDELEG read warmed my little heart.
Hyper loads dance—permissions right!

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.54% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'H extention' is related to the changeset but is misspelled ('extention' should be 'extension') and lacks specificity about what H-extension support entails. Correct the spelling to 'H extension' and consider adding more context, such as 'Add H extension support' or 'Implement RISC-V H extension with hypervisor instructions' for clarity.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/arch/riscv/isa/decoder.isa`:
- Around line 2153-2165: The decoder currently maps sinval_vvma, sfence_w_inval,
and sfence_inval_ir to no-op stubs that only warn (leaving stale translations);
change these paths to fail-fast until proper invalidation is implemented by
replacing the warn-only handlers with a hard trap/unsupported-instruction error
(or explicit throw/terminate) so execution cannot continue with stale state;
locate the cases for sinval_vvma, sfence_w_inval, and sfence_inval_ir in the
decoder and update their bodies to return/raise an unrecoverable error (or call
the existing unsupported/op-fail helper) instead of just logging a warning.
- Around line 2432-2434: The store in HyperStore::hsv_h has a missing semicolon
after the assignment "Mem_uh = Rs2_uh" which breaks generated C++; update the
hsv_h store block to terminate the assignment with a semicolon (i.e., change
"Mem_uh = Rs2_uh" to "Mem_uh = Rs2_uh;") and keep the surrounding mem_flags
array intact so the decoder.isa block for HyperStore::hsv_h remains
syntactically valid.

In `@src/arch/riscv/tlb.cc`:
- Around line 1420-1424: The code is attempting to assign into a temporary
std::pair; replace that with a proper structured binding or two-variable
assignment from the return of checkGPermissions. Call checkGPermissions(status,
vaddr, fault_gpaddr, mode, e[0]->pte, (req->getFlags() & (Request::ARCH_BITS &
XlateFlags::HLVX)) || req->get_h_inst()) and capture its result into the
existing variables continuePtw and fault (e.g. use auto [continuePtw, fault] =
... if they are being declared here, or assign the returned pair to a temporary
std::pair and then set continuePtw = tmp.first; fault = tmp.second; if they are
already declared). Ensure you reference the function checkGPermissions and the
flags expression exactly as in the diff.

Comment on lines +2153 to +2165
0xb: sinval_vvma({{
warn("sinval_vvma not implemented");
}}, IsNonSpeculative, IsSerializeAfter, No_OpClass);

0xc: decode RS2{
0x0: sfence_w_inval({{
warn("sfence_w_inval not implemented");
}}, IsNonSpeculative, IsSerializeAfter, No_OpClass);

0x1: sfence_inval_ir({{
warn("sfence_inval_ir not implemented");
}}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid no-op invalidation instructions.

These paths only warn and continue, which can leave stale translations and break guest behavior. Either implement the invalidation or fail fast until it’s supported.

🛠️ Suggested fail-fast behavior until invalidation is implemented
-                    warn("sinval_vvma not implemented");
+                    return std::make_shared<IllegalInstFault>(
+                            "sinval_vvma not implemented", machInst);
...
-                        warn("sfence_w_inval not implemented");
+                        return std::make_shared<IllegalInstFault>(
+                                "sfence_w_inval not implemented", machInst);
...
-                        warn("sfence_inval_ir not implemented");
+                        return std::make_shared<IllegalInstFault>(
+                                "sfence_inval_ir not implemented", machInst);
...
-                        warn("hinval_vvma not implemented");
+                        return std::make_shared<IllegalInstFault>(
+                                "hinval_vvma not implemented", machInst);
...
-                            warn("hinval_gvma unimplemented");
+                            return std::make_shared<IllegalInstFault>(
+                                    "hinval_gvma not implemented", machInst);

Also applies to: 2189-2191, 2242-2244

🤖 Prompt for AI Agents
In `@src/arch/riscv/isa/decoder.isa` around lines 2153 - 2165, The decoder
currently maps sinval_vvma, sfence_w_inval, and sfence_inval_ir to no-op stubs
that only warn (leaving stale translations); change these paths to fail-fast
until proper invalidation is implemented by replacing the warn-only handlers
with a hard trap/unsupported-instruction error (or explicit throw/terminate) so
execution cannot continue with stale state; locate the cases for sinval_vvma,
sfence_w_inval, and sfence_inval_ir in the decoder and update their bodies to
return/raise an unrecoverable error (or call the existing unsupported/op-fail
helper) instead of just logging a warning.

Comment on lines +2432 to +2434
0x33: HyperStore::hsv_h({{
Mem_uh = Rs2_uh
}}, mem_flags=[
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix missing semicolon in hsv_h store.

This will break generated C++.

🐛 Proposed fix
-                        Mem_uh = Rs2_uh
+                        Mem_uh = Rs2_uh;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
0x33: HyperStore::hsv_h({{
Mem_uh = Rs2_uh
}}, mem_flags=[
0x33: HyperStore::hsv_h({{
Mem_uh = Rs2_uh;
}}, mem_flags=[
🤖 Prompt for AI Agents
In `@src/arch/riscv/isa/decoder.isa` around lines 2432 - 2434, The store in
HyperStore::hsv_h has a missing semicolon after the assignment "Mem_uh = Rs2_uh"
which breaks generated C++; update the hsv_h store block to terminate the
assignment with a semicolon (i.e., change "Mem_uh = Rs2_uh" to "Mem_uh =
Rs2_uh;") and keep the surrounding mem_flags array intact so the decoder.isa
block for HyperStore::hsv_h remains syntactically valid.

Comment on lines 1420 to 1424
std::pair(continuePtw,fault) = checkGPermissions(status, vaddr,
fault_gpaddr, mode, e[0]->pte,
(req->getFlags() &
(Request::ARCH_BITS & XlateFlags::HLVX)) ||
req->get_h_inst());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix invalid std::pair assignment (won’t compile).
Line 1420 constructs a temporary pair and assigns to it; this is invalid C++.

🛠️ Proposed fix
-        std::pair(continuePtw,fault) = checkGPermissions(status, vaddr,
-            fault_gpaddr, mode, e[0]->pte,
-            (req->getFlags() &
-                (Request::ARCH_BITS & XlateFlags::HLVX)) ||
-                req->get_h_inst());
+        auto check_res = checkGPermissions(status, vaddr,
+            fault_gpaddr, mode, e[0]->pte,
+            (req->getFlags() &
+                (Request::ARCH_BITS & XlateFlags::HLVX)) ||
+                req->get_h_inst());
+        continuePtw = check_res.first;
+        fault = check_res.second;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
std::pair(continuePtw,fault) = checkGPermissions(status, vaddr,
fault_gpaddr, mode, e[0]->pte,
(req->getFlags() &
(Request::ARCH_BITS & XlateFlags::HLVX)) ||
req->get_h_inst());
auto check_res = checkGPermissions(status, vaddr,
fault_gpaddr, mode, e[0]->pte,
(req->getFlags() &
(Request::ARCH_BITS & XlateFlags::HLVX)) ||
req->get_h_inst());
continuePtw = check_res.first;
fault = check_res.second;
🤖 Prompt for AI Agents
In `@src/arch/riscv/tlb.cc` around lines 1420 - 1424, The code is attempting to
assign into a temporary std::pair; replace that with a proper structured binding
or two-variable assignment from the return of checkGPermissions. Call
checkGPermissions(status, vaddr, fault_gpaddr, mode, e[0]->pte, (req->getFlags()
& (Request::ARCH_BITS & XlateFlags::HLVX)) || req->get_h_inst()) and capture its
result into the existing variables continuePtw and fault (e.g. use auto
[continuePtw, fault] = ... if they are being declared here, or assign the
returned pair to a temporary std::pair and then set continuePtw = tmp.first;
fault = tmp.second; if they are already declared). Ensure you reference the
function checkGPermissions and the flags expression exactly as in the diff.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0c403cbb4f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +2153 to +2155
0xb: sinval_vvma({{
warn("sinval_vvma not implemented");
}}, IsNonSpeculative, IsSerializeAfter, No_OpClass);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Implement sinval.vvma invalidation or trap

When a guest/OS uses sinval.vvma after updating page tables, this implementation only logs a warning and returns NoFault, so no TLB/translation invalidation occurs and no illegal-instruction trap is raised. That means stale translations can be reused, leading to accesses using old mappings or permissions after address-space changes (e.g., context switches or unmaps). If the invalidation isn’t implemented yet, this should at least raise an illegal instruction so software doesn’t continue with silently incorrect translations.

Useful? React with 👍 / 👎.

@github-actions
Copy link

🚀 Coremark Smoke Test Results

Branch IPC Change
Base (xs-dev) 2.1727 -
This PR 2.1727 ➡️ 0.0000 (0.00%)

✅ Difftest smoke test passed!

Change-Id: Icee9bfd8ad9869e0a6fdf72306aac87f5f36c32f
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/arch/riscv/tlb.cc`:
- Around line 1152-1163: The read-permission check no longer respects status.mxr
so execute-only pages are treated as unreadable; update the permission logic in
the TLB path by making exec_like consider MXR for read accesses (i.e., treat a
Read as exec_like when status.mxr is set), then keep the existing checks
(reservedPteBitsFault, createPagefault, and the pte.x / pte.r / pte.w branches)
unchanged so execute-only pages become readable under MXR; locate and modify the
definition of exec_like in this block (and/or where checkPermissions is used) to
incorporate status.mxr for BaseMMU::Read.
🧹 Nitpick comments (1)
src/arch/riscv/pagetable_walker.cc (1)

58-102: Optional: de-duplicate PBMTE helper with TLB.

pbmtEnabled mirrors the helper in src/arch/riscv/tlb.cc; consider centralizing it to avoid drift.

Comment on lines +1152 to 1163
const bool exec_like = (mode == BaseMMU::Execute) ||
(mode == BaseMMU::Read && hlvx);

if (reservedPteBitsFault(tc, pte))
return createPagefault(vaddr, gpaddr, mode, G);

if (exec_like && !pte.x) {
fault = createPagefault(vaddr, gpaddr, mode, G);
} else if (mode == BaseMMU::Write && !pte.w) {
} else if (!exec_like && mode == BaseMMU::Read && !pte.r) {
fault = createPagefault(vaddr, gpaddr, mode, G);
} else if (mode == BaseMMU::Execute && !pte.x) {
} else if (mode == BaseMMU::Write && !pte.w) {
fault = createPagefault(vaddr, gpaddr, mode, G);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Restore MXR handling for read permissions.

checkPermissions no longer honors status.mxr, so execute-only pages become unreadable even when MXR is set. This is a functional regression for standard RISC‑V behavior.

🛠️ Proposed fix
-    } else if (!exec_like && mode == BaseMMU::Read && !pte.r) {
+    } else if (!exec_like && mode == BaseMMU::Read &&
+               !(pte.r || (status.mxr && pte.x))) {
         fault = createPagefault(vaddr, gpaddr, mode, G);
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const bool exec_like = (mode == BaseMMU::Execute) ||
(mode == BaseMMU::Read && hlvx);
if (reservedPteBitsFault(tc, pte))
return createPagefault(vaddr, gpaddr, mode, G);
if (exec_like && !pte.x) {
fault = createPagefault(vaddr, gpaddr, mode, G);
} else if (mode == BaseMMU::Write && !pte.w) {
} else if (!exec_like && mode == BaseMMU::Read && !pte.r) {
fault = createPagefault(vaddr, gpaddr, mode, G);
} else if (mode == BaseMMU::Execute && !pte.x) {
} else if (mode == BaseMMU::Write && !pte.w) {
fault = createPagefault(vaddr, gpaddr, mode, G);
const bool exec_like = (mode == BaseMMU::Execute) ||
(mode == BaseMMU::Read && hlvx);
if (reservedPteBitsFault(tc, pte))
return createPagefault(vaddr, gpaddr, mode, G);
if (exec_like && !pte.x) {
fault = createPagefault(vaddr, gpaddr, mode, G);
} else if (!exec_like && mode == BaseMMU::Read &&
!(pte.r || (status.mxr && pte.x))) {
fault = createPagefault(vaddr, gpaddr, mode, G);
} else if (mode == BaseMMU::Write && !pte.w) {
fault = createPagefault(vaddr, gpaddr, mode, G);
🤖 Prompt for AI Agents
In `@src/arch/riscv/tlb.cc` around lines 1152 - 1163, The read-permission check no
longer respects status.mxr so execute-only pages are treated as unreadable;
update the permission logic in the TLB path by making exec_like consider MXR for
read accesses (i.e., treat a Read as exec_like when status.mxr is set), then
keep the existing checks (reservedPteBitsFault, createPagefault, and the pte.x /
pte.r / pte.w branches) unchanged so execute-only pages become readable under
MXR; locate and modify the definition of exec_like in this block (and/or where
checkPermissions is used) to incorporate status.mxr for BaseMMU::Read.

@github-actions
Copy link

🚀 Coremark Smoke Test Results

Branch IPC Change
Base (xs-dev) 2.1727 -
This PR 2.1727 ➡️ 0.0000 (0.00%)

✅ Difftest smoke test passed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants