Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
7baf0bf
docs(ssp): shadow stack pointer - issue #560
sudo-apt-abdullah Aug 4, 2025
274f590
docs(ssp): improved it a bit
sudo-apt-abdullah Aug 4, 2025
7687c4e
docs(ssp): addressed the concerns
sudo-apt-abdullah Aug 5, 2025
0bf9bf3
docs(ssp): modified the file to increase readablity
sudo-apt-abdullah Aug 5, 2025
dc30397
docs(ssp): fixed the indentation
sudo-apt-abdullah Aug 5, 2025
cc23c1d
docs(ssp): fixed issue with CI check
sudo-apt-abdullah Aug 5, 2025
aacade9
fix: handle dynamic csr field locations when csr length is XLEN
dhower-qc Aug 5, 2025
46c47ad
Merge branch 'main' into issues
sudo-apt-abdullah Aug 6, 2025
076dce1
docs(ssp): added sse field in menvcfg csr
sudo-apt-abdullah Aug 7, 2025
8267051
docs(ssp): merged aacade9
sudo-apt-abdullah Aug 7, 2025
0b60f08
docs(ssp): added see field in senvcfg and henvcfg
sudo-apt-abdullah Aug 8, 2025
f676a67
Merge branch 'main' into issues
sudo-apt-abdullah Aug 8, 2025
f745105
docs(ssp): addressed the concerns so far
sudo-apt-abdullah Aug 11, 2025
9e451f9
Merge branch 'main' into issues
sudo-apt-abdullah Aug 11, 2025
0c5e4f8
Merge branch 'main' into issues
sudo-apt-abdullah Aug 18, 2025
86cfc3e
docs(ssp): addressed the concerns so far
sudo-apt-abdullah Aug 18, 2025
266196f
docs(ssp): added sw_write for xenvcfg.sse
sudo-apt-abdullah Aug 18, 2025
1c6ce38
Merge branch 'main' into issues
sudo-apt-abdullah Aug 21, 2025
33ea676
Merge branch 'main' into issues
sudo-apt-abdullah Aug 25, 2025
756dc6d
docs(ssp): Used the exact suggested syntax for definedBy
sudo-apt-abdullah Aug 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions spec/std/isa/csr/H/henvcfg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,36 @@ fields:
return CSR[menvcfg].CBIE;
}
reset_value: UNDEFINED_LEGAL
SSE:
location: 3
description: |
*Shadow Stack Enable*

If the SSE field is set to 1, the Zicfiss extension is activated in VS-mode. When the SSE
field is 0, the Zicfiss extension remains inactive in VS-mode, and the following rules apply
when V=1 :

- 32-bit Zicfiss instructions will revert to their behavior as defined by Zimop.

- 16-bit Zicfiss instructions will revert to their behavior as defined by Zcmop.

- The pte.xwr=010b encoding in VS-stage page tables becomes reserved.

- The senvcfg.SSE field will read as zero and is read-only.

- When menvcfg.SSE is one, SSAMOSWAP.W/D raises a virtual-instruction exception.
definedBy:
extension:
name: Zicfiss
type(): |
return (implemented?(ExtensionName::Zicfiss)) ? CsrFieldType::RW : CsrFieldType::RO;
reset_value(): |
return (implemented?(ExtensionName::Zicfiss)) ? UNDEFINED_LEGAL : 0;
sw_write(csr_value): |
if (CSR[menvcfg].SSE == 0){
return 0;
}
return csr_value.SSE;
FIOM:
location: 0
description: |
Expand Down Expand Up @@ -291,4 +321,8 @@ sw_read(): |
# henvcfg.ADUE must read-as-zero
value = value & ~(1 `<< 61);
}
if (implemented?(ExtensionName::Zicfiss) && CSR[menvcfg].SSE == 0) {
# henvcfg.SSE must read-as-zero
value = value & ~(1 `<< 3);
}
return value;
24 changes: 24 additions & 0 deletions spec/std/isa/csr/menvcfg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,30 @@ fields:
return CSR[menvcfg].CBIE;
}
reset_value: UNDEFINED_LEGAL
SSE:
location: 3
description: |
*Shadow Stack Enable*

When the SSE field is set to 1 the Zicfiss extension isactivated in S-mode. When SSE
field is 0, the following rules apply to privilege modes that are less than M:

- 32-bit Zicfiss instructions will revert to their behavior as defined by Zimop.

- 16-bit Zicfiss instructions will revert to their behavior as defined by Zcmop.

- The pte.xwr=010b encoding in VS/S-stage page tables becomes reserved.

- SSAMOSWAP.W/D raises an illegal-instruction exception.

When menvcfg.SSE is 0, the henvcfg.SSE and senvcfg.SSE fields are read-only zero.
definedBy:
extension:
name: Zicfiss
type(): |
return (implemented?(ExtensionName::Zicfiss)) ? CsrFieldType::RW : CsrFieldType::RO;
reset_value(): |
return (implemented?(ExtensionName::Zicfiss)) ? UNDEFINED_LEGAL : 0;
FIOM:
location: 0
description: |
Expand Down
34 changes: 34 additions & 0 deletions spec/std/isa/csr/senvcfg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,33 @@ fields:
return UNDEFINED_LEGAL_DETERMINISTIC;
}
reset_value: UNDEFINED_LEGAL
SSE:
location: 3
description: |
*Shadow Stack Enable*

When the SSE field is set to 1, the Zicfiss extension is
activated in VU/U-mode. When the SSE field is 0, the Zicfiss extension remains inactive
in VU/U-mode, and the following rules apply:

- 32-bit Zicfiss instructions will revert to their behavior as defined by Zimop.

- 16-bit Zicfiss instructions will revert to their behavior as defined by Zcmop.

- When menvcfg.SSE is one, SSAMOSWAP.W/D raises an illegal-instruction exception in U-mode
and a virtual-instruction exception in VU-mode.
definedBy:
extension:
name: Zicfiss
type(): |
return (implemented?(ExtensionName::Zicfiss)) ? CsrFieldType::RW : CsrFieldType::RO;
reset_value(): |
return (implemented?(ExtensionName::Zicfiss)) ? UNDEFINED_LEGAL : 0;
sw_write(csr_value): |
if (CSR[menvcfg].SSE == 0 || CSR[henvcfg].SSE == 0){
return 0;
}
return csr_value.SSE;
FIOM:
location: 0
description: |
Expand Down Expand Up @@ -148,3 +175,10 @@ fields:

type: RW
reset_value: 0
sw_read(): |
Bits<64> value = $bits(CSR[senvcfg]);
if (implemented?(ExtensionName::Zicfiss) && (CSR[menvcfg].SSE == 0 || CSR[henvcfg].SSE == 0)) {
# senvcfg.SSE must read-as-zero
value = value & ~(1 `<< 3);
}
return value;
55 changes: 55 additions & 0 deletions spec/std/isa/csr/ssp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright (c) Katherine Hsu
# SPDX-License-Identifier: BSD-3-Clause-Clear

# yaml-language-server: $schema=../../../schemas/csr_schema.json

$schema: "csr_schema.json#"
kind: csr
name: ssp
long_name: Shadow Stack Pointer
address: 0x011
writable: true
description:
- id: csr-ssp-purpose
normative: true
text: |
The `ssp` CSR is an unprivileged read-write (URW) CSR that reads and writes
XLEN low order bits of the shadow stack pointer. The `ssp` is always as wide
as the XLEN of the current privilege mode. The bits 1:0 of ssp are read-only
zero. If the UXLEN or SXLEN may never be 32, then the bit 2 is also read-only
zero.
priv_mode: U
length: XLEN
definedBy:
extension:
name: Zicfiss
fields:
VALUE:
location_rv64: 63-3
location_rv32: 31-2
description: |
The value in ssp points to the top of the shadow stack, which is the address
of the last element stored on the shadow stack.
type: RW
reset_value: UNDEFINED_LEGAL
sw_write(csr_value): |
if ((mode() < PrivilegeMode::M && CSR[menvcfg].SSE == 0) ||
(mode() == PrivilegeMode::U && CSR[senvcfg].SSE == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if ((mode() == PrivilegeMode::VS && CSR[henvcfg].SSE == 0) ||
(mode() == PrivilegeMode::VU && (CSR[henvcfg].SSE == 0 || CSR[senvcfg].SSE == 0))) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
} else {
return csr_value.VALUE;
}
sw_read(): |
if ((mode() < PrivilegeMode::M && CSR[menvcfg].SSE == 0) ||
(mode() == PrivilegeMode::U && CSR[senvcfg].SSE == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if ((mode() == PrivilegeMode::VS && CSR[henvcfg].SSE == 0) ||
(mode() == PrivilegeMode::VU && (CSR[henvcfg].SSE == 0 || CSR[senvcfg].SSE == 0))) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
} else if (XLEN == 32) {
return ($bits(CSR[ssp]) & ~3);
}
return ($bits(CSR[ssp]) & ~7);
24 changes: 14 additions & 10 deletions tools/ruby-gems/udb/lib/udb/obj/csr_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -754,21 +754,25 @@ def location_pretty(effective_xlen = nil)

if dynamic_location?
condition =
case csr.priv_mode
when "M"
"CSR[misa].MXL == %%"
when "S"
"CSR[mstatus].SXL == %%"
when "VS"
"CSR[hstatus].VSXL == %%"
if csr.data["length"] == "XLEN"
"the current XLEN is $$"
else
raise "Unexpected priv mode #{csr.priv_mode} for #{csr.name}"
case csr.priv_mode
when "M"
"CSR[misa].MXL == %%"
when "S"
"CSR[mstatus].SXL == %%"
when "VS"
"CSR[hstatus].VSXL == %%"
else
raise "Unexpected priv mode #{csr.priv_mode} for #{csr.name}"
end
end

if effective_xlen.nil?
<<~LOC
* #{derangeify.call(location(32))} when #{condition.sub('%%', '0')}
* #{derangeify.call(location(64))} when #{condition.sub('%%', '1')}
* #{derangeify.call(location(32))} when #{condition.sub('%%', '0').sub('$$', '32')}
* #{derangeify.call(location(64))} when #{condition.sub('%%', '1').sub('$$', '64')}
LOC
else
derangeify.call(location(effective_xlen))
Expand Down
Loading