1
0

Forbid S-mode execution from user memory

285c81746f
This commit is contained in:
Andrew Waterman 2017-06-08 17:22:51 -07:00
parent 8aa16a11f3
commit cc2f87c214

View File

@ -79,6 +79,7 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
val totalEntries = nEntries + 1 val totalEntries = nEntries + 1
val normalEntries = nEntries val normalEntries = nEntries
val specialEntry = nEntries val specialEntry = nEntries
val aeEntry = specialEntry - (1 << log2Floor(nEntries))
val valid = Reg(init = UInt(0, totalEntries)) val valid = Reg(init = UInt(0, totalEntries))
val reg_entries = Reg(Vec(totalEntries, UInt(width = new Entry().getWidth))) val reg_entries = Reg(Vec(totalEntries, UInt(width = new Entry().getWidth)))
val entries = reg_entries.map(_.asTypeOf(new Entry)) val entries = reg_entries.map(_.asTypeOf(new Entry))
@ -117,7 +118,6 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
val prot_aa = fastCheck(_.supportsArithmetic) || cacheable val prot_aa = fastCheck(_.supportsArithmetic) || cacheable
val prot_x = fastCheck(_.executable) && pmp.io.x val prot_x = fastCheck(_.executable) && pmp.io.x
val prot_eff = fastCheck(Seq(RegionType.PUT_EFFECTS, RegionType.GET_EFFECTS) contains _.regionType) val prot_eff = fastCheck(Seq(RegionType.PUT_EFFECTS, RegionType.GET_EFFECTS) contains _.regionType)
val isSpecial = !(io.ptw.resp.bits.homogeneous || io.ptw.resp.bits.ae)
val lookup_tag = Cat(io.ptw.ptbr.asid, vpn(vpnBits-1,0)) val lookup_tag = Cat(io.ptw.ptbr.asid, vpn(vpnBits-1,0))
val hitsVec = (0 until totalEntries).map { i => vm_enabled && { val hitsVec = (0 until totalEntries).map { i => vm_enabled && {
@ -140,7 +140,7 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
// permission bit arrays // permission bit arrays
when (do_refill && !invalidate_refill) { when (do_refill && !invalidate_refill) {
val waddr = Mux(isSpecial, specialEntry.U, r_refill_waddr) val waddr = Mux(io.ptw.resp.bits.ae, aeEntry.U, Mux(!io.ptw.resp.bits.homogeneous, specialEntry.U, r_refill_waddr))
val pte = io.ptw.resp.bits.pte val pte = io.ptw.resp.bits.pte
val newEntry = Wire(new Entry) val newEntry = Wire(new Entry)
newEntry.ppn := pte.ppn newEntry.ppn := pte.ppn
@ -149,13 +149,10 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
newEntry.c := cacheable newEntry.c := cacheable
newEntry.u := pte.u newEntry.u := pte.u
newEntry.g := pte.g newEntry.g := pte.g
// if an access exception occurs during PTW, pretend the page has full
// permissions so that a page fault will not occur, but clear the
// phyiscal memory permissions, so that an access exception will occur.
newEntry.ae := io.ptw.resp.bits.ae newEntry.ae := io.ptw.resp.bits.ae
newEntry.sr := pte.sr() || io.ptw.resp.bits.ae newEntry.sr := pte.sr()
newEntry.sw := pte.sw() || io.ptw.resp.bits.ae newEntry.sw := pte.sw()
newEntry.sx := pte.sx() || io.ptw.resp.bits.ae newEntry.sx := pte.sx()
newEntry.pr := prot_r && !io.ptw.resp.bits.ae newEntry.pr := prot_r && !io.ptw.resp.bits.ae
newEntry.pw := prot_w && !io.ptw.resp.bits.ae newEntry.pw := prot_w && !io.ptw.resp.bits.ae
newEntry.px := prot_x && !io.ptw.resp.bits.ae newEntry.px := prot_x && !io.ptw.resp.bits.ae
@ -170,10 +167,12 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
val plru = new PseudoLRU(normalEntries) val plru = new PseudoLRU(normalEntries)
val repl_waddr = Mux(!valid(normalEntries-1, 0).andR, PriorityEncoder(~valid(normalEntries-1, 0)), plru.replace) val repl_waddr = Mux(!valid(normalEntries-1, 0).andR, PriorityEncoder(~valid(normalEntries-1, 0)), plru.replace)
val priv_ok = entries.map(_.ae).asUInt | Mux(priv_s, ~Mux(io.ptw.status.sum, UInt(0), entries.map(_.u).asUInt), entries.map(_.u).asUInt) val ptw_ae_array = entries(aeEntry).ae << aeEntry
val r_array = Cat(true.B, priv_ok & (entries.map(_.sr).asUInt | Mux(io.ptw.status.mxr, entries.map(_.sx).asUInt, UInt(0)))) val priv_rw_ok = Mux(!priv_s || io.ptw.status.sum, entries.map(_.u).asUInt, 0.U) | Mux(priv_s, ~entries.map(_.u).asUInt, 0.U)
val w_array = Cat(true.B, priv_ok & entries.map(_.sw).asUInt) val priv_x_ok = Mux(priv_s, ~entries.map(_.u).asUInt, entries.map(_.u).asUInt)
val x_array = Cat(true.B, priv_ok & entries.map(_.sx).asUInt) val r_array = Cat(true.B, priv_rw_ok & (entries.map(_.sr).asUInt | Mux(io.ptw.status.mxr, entries.map(_.sx).asUInt, UInt(0))))
val w_array = Cat(true.B, priv_rw_ok & entries.map(_.sw).asUInt)
val x_array = Cat(true.B, priv_x_ok & entries.map(_.sx).asUInt)
val pr_array = Cat(Fill(2, prot_r), entries.init.map(_.pr).asUInt) val pr_array = Cat(Fill(2, prot_r), entries.init.map(_.pr).asUInt)
val pw_array = Cat(Fill(2, prot_w), entries.init.map(_.pw).asUInt) val pw_array = Cat(Fill(2, prot_w), entries.init.map(_.pw).asUInt)
val px_array = Cat(Fill(2, prot_x), entries.init.map(_.px).asUInt) val px_array = Cat(Fill(2, prot_x), entries.init.map(_.px).asUInt)
@ -198,8 +197,9 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
Mux(Bool(usingAtomics) && isAMOArithmetic(io.req.bits.cmd), ~paa_array, 0.U) Mux(Bool(usingAtomics) && isAMOArithmetic(io.req.bits.cmd), ~paa_array, 0.U)
val ma_ld_array = Mux(misaligned && isRead(io.req.bits.cmd), ~eff_array, 0.U) val ma_ld_array = Mux(misaligned && isRead(io.req.bits.cmd), ~eff_array, 0.U)
val ma_st_array = Mux(misaligned && isWrite(io.req.bits.cmd), ~eff_array, 0.U) val ma_st_array = Mux(misaligned && isWrite(io.req.bits.cmd), ~eff_array, 0.U)
val pf_ld_array = Mux(isRead(io.req.bits.cmd), ~r_array, 0.U) val pf_ld_array = Mux(isRead(io.req.bits.cmd), ~(r_array | ptw_ae_array), 0.U)
val pf_st_array = Mux(isWrite(io.req.bits.cmd), ~w_array, 0.U) val pf_st_array = Mux(isWrite(io.req.bits.cmd), ~(w_array | ptw_ae_array), 0.U)
val pf_inst_array = ~(x_array | ptw_ae_array)
val tlb_hit = hits(totalEntries-1, 0).orR val tlb_hit = hits(totalEntries-1, 0).orR
val tlb_miss = vm_enabled && !bad_va && !tlb_hit && !io.req.bits.sfence.valid val tlb_miss = vm_enabled && !bad_va && !tlb_hit && !io.req.bits.sfence.valid
@ -217,7 +217,7 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
io.req.ready := state === s_ready io.req.ready := state === s_ready
io.resp.pf.ld := (bad_va && isRead(io.req.bits.cmd)) || (pf_ld_array & hits).orR io.resp.pf.ld := (bad_va && isRead(io.req.bits.cmd)) || (pf_ld_array & hits).orR
io.resp.pf.st := (bad_va && isWrite(io.req.bits.cmd)) || (pf_st_array & hits).orR io.resp.pf.st := (bad_va && isWrite(io.req.bits.cmd)) || (pf_st_array & hits).orR
io.resp.pf.inst := bad_va || (~x_array & hits).orR io.resp.pf.inst := bad_va || (pf_inst_array & hits).orR
io.resp.ae.ld := (ae_ld_array & hits).orR io.resp.ae.ld := (ae_ld_array & hits).orR
io.resp.ae.st := (ae_st_array & hits).orR io.resp.ae.st := (ae_st_array & hits).orR
io.resp.ae.inst := (~px_array & hits).orR io.resp.ae.inst := (~px_array & hits).orR