You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi there! I appreciate your involvement in this project.
I'm developing a plugin to add shadow stack functionality to VexRiscv. I've implemented instructions, 'sspush' for pushing onto the shadow stack and 'sspop' for popping from it. However, these instructions are being executed at unintended timings.
Upon checking the waveform, at 128223900ns, it's evident that 3A646A29 is confirmed as an instruction sspop in the execute stage, reducing ShadowStackPlugin_ssp by -1. However, this instruction clearly doesn't match the key = M"00000000000000000100-----0101011" of the custom instruction sspop (listed below), and comparing this with the disassembled C program shows that 800005d4 should have nop as 00000013. Is this some sort of bug? I couldn't find such an instruction in the C program. This 3A646A29 instruction appeared unexpectedly as if interrupting.
I would appreciate any insights from anyone familiar with this phenomenon. Thank you in advance!
The 'sspush' and 'sspop' instructions are defined as follows:
package vexriscv.plugin
import vexriscv.plugin.Plugin
import vexriscv.{Stageable, DecoderService, VexRiscv}
import spinal.core._
import spinal.lib._
class ShadowStackPlugin extends Plugin[VexRiscv] {
object IS_SS_POP extends Stageable(Bool)
object IS_SS_PUSH extends Stageable(Bool)
object IS_SS_GET extends Stageable(Bool)
override def setup(pipeline: VexRiscv): Unit = {
import pipeline.config._
val decoderService = pipeline.service(classOf[DecoderService])
// add sspop
decoderService.addDefault(IS_SS_POP, False)
decoderService.add(
key = M"00000000000000000100-----0101011",
List(
IS_SS_POP -> True,
REGFILE_WRITE_VALID -> True
)
)
// add sspush
decoderService.addDefault(IS_SS_PUSH, False)
decoderService.add(
key = M"000000000000-----010000000001011",
List(
IS_SS_PUSH -> True,
RS1_USE -> True
)
)
}
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
val ssgetStage = execute
val sspopStage = execute
val sspushStage = execute
val global = pipeline plug new Area {
val width = 32
val depth = 32
val bottom = 1
val ssp = Reg(UInt(log2Up(depth) + 1 bits)) init (bottom)
val shadowStack = Mem(UInt(width bits), depth)
shadowStack.init(List.fill(depth)(U"32'd8"))
}
// sspop
sspopStage plug new Area {
import sspopStage._
when(input(IS_SS_POP).rise() && global.bottom < global.ssp){
output(REGFILE_WRITE_DATA) := global.shadowStack((global.ssp - 1).resized).asBits
global.ssp := global.ssp - 1
}
}
// sspush
sspushStage plug new Area {
import sspushStage._
when(input(IS_SS_PUSH).rise() && global.ssp < global.depth){
val rs1 = input(RS1).asUInt
global.shadowStack(global.ssp.resized) := rs1
global.ssp := global.ssp + 1
}
}
}
}
The text was updated successfully, but these errors were encountered:
Hi there! I appreciate your involvement in this project.
I'm developing a plugin to add shadow stack functionality to VexRiscv. I've implemented instructions, 'sspush' for pushing onto the shadow stack and 'sspop' for popping from it. However, these instructions are being executed at unintended timings.
Upon checking the waveform, at
128223900ns
, it's evident that3A646A29
is confirmed as an instructionsspop
in the execute stage, reducing ShadowStackPlugin_ssp by -1. However, this instruction clearly doesn't match thekey = M"00000000000000000100-----0101011"
of the custom instruction sspop (listed below), and comparing this with the disassembled C program shows that800005d4
should havenop
as00000013
. Is this some sort of bug? I couldn't find such an instruction in the C program. This3A646A29
instruction appeared unexpectedly as if interrupting.I would appreciate any insights from anyone familiar with this phenomenon. Thank you in advance!
The 'sspush' and 'sspop' instructions are defined as follows:
The text was updated successfully, but these errors were encountered: