Skip to content

Commit

Permalink
fix(misalign): Should use offset of original vaddr to generate gpaddr
Browse files Browse the repository at this point in the history
For example, a `ld` instruction on address 0x81000ffb will be splited into two loads:
1. ld 0x81000ff8. vaddr = 0x81000ff8, fullva = 0x80000ffb
2. ld 0x81001000. vaddr = 0x81001000, fullva = 0x80000ffb

When load 1 trigger a guest page fault, we should use offset of original vaddr to generate gpaddr in TLB, and and when load 2 trigger a guest page fault, we should just use offset of after-splitted vaddr(all zero) in misalignbuffer.
  • Loading branch information
good-circle authored and Tang-Haojin committed Oct 30, 2024
1 parent 6444fe0 commit 7eef70f
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 3 deletions.
9 changes: 8 additions & 1 deletion src/main/scala/xiangshan/cache/mmu/TLB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,14 @@ class TLB(Width: Int, nRespDups: Int = 1, Block: Seq[Boolean], q: TLBParameters)
(isFakePte(d) && vsatp.mode === Sv48) -> 3.U,
(!isFakePte(d)) -> (level(d) - 1.U),
))
val gpaddr_offset = Mux(isLeaf(d), get_off(req_out(i).vaddr), Cat(getVpnn(get_pn(req_out(i).vaddr), vpn_idx), 0.U(log2Up(XLEN/8).W)))
// We use `fullva` here when `isLeaf`, in order to cope with the situation of an unaligned load/store cross page
// for example, a `ld` instruction on address 0x81000ffb will be splited into two loads
// 1. ld 0x81000ff8. vaddr = 0x81000ff8, fullva = 0x80000ffb
// 2. ld 0x81001000. vaddr = 0x81001000, fullva = 0x80000ffb
// When load 1 trigger a guest page fault, we should use offset of fullva when generate gpaddr
// and when load 2 trigger a guest page fault, we should just use offset of vaddr(all zero).
// Whether cross-page will be determined in misalign buffer(situation 2) so we only need to judge situation 1 here.
val gpaddr_offset = Mux(isLeaf(d), get_off(req_out(i).fullva), Cat(getVpnn(get_pn(req_out(i).fullva), vpn_idx), 0.U(log2Up(XLEN/8).W)))
val gpaddr = Cat(gvpn(d), gpaddr_offset)
resp(i).bits.paddr(d) := Mux(enable, paddr, vaddr)
resp(i).bits.gpaddr(d) := Mux(r_s2xlate(d) === onlyStage2, vaddr, gpaddr)
Expand Down
5 changes: 3 additions & 2 deletions src/main/scala/xiangshan/mem/lsqueue/LoadMisalignBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -588,8 +588,9 @@ class LoadMisalignBuffer(implicit p: Parameters) extends XSModule
val overwriteGpaddr = RegEnable(
Mux(
cross16BytesBoundary && (curPtr === 1.U),
splitLoadResp(curPtr).gpaddr,
Cat(get_pn(splitLoadResp(curPtr).gpaddr), get_off(splitLoadResp(curPtr).fullva))),
// when cross-page, offset should always be 0
Cat(get_pn(splitLoadResp(curPtr).gpaddr), get_off(0.U(splitLoadResp(curPtr).gpaddr.getWidth.W))),
splitLoadResp(curPtr).gpaddr),
shouldOverwrite)
val overwriteIsHyper = RegEnable(splitLoadResp(curPtr).isHyper, shouldOverwrite)
val overwriteIsForVSnonLeafPTE = RegEnable(splitLoadResp(curPtr).isForVSnonLeafPTE, shouldOverwrite)
Expand Down

0 comments on commit 7eef70f

Please sign in to comment.