Skip to content

Commit

Permalink
feat(pointer masking): support Ssnpm & Smnpm & Smmpm (#677)
Browse files Browse the repository at this point in the history
also fix 3 bugs:
1. in mmu.c; hyperinst_vm_enable should be true when Sv48 or Sv48x4
2. in mmu.c; only gpf should report guest page fault and hld_st should report page fault when !onlyStage2
3. in priv.c; henvcfg.stce/dte/pbmte is read_only 0 when menvcfg.stce/dte/pbmte = 0, however in other cases it is allowed that the corresponding bits of henvcfg is not 0 and these bits of menvcfg are 0
  • Loading branch information
good-circle authored Dec 3, 2024
1 parent 1761183 commit bb91d6f
Show file tree
Hide file tree
Showing 15 changed files with 229 additions and 56 deletions.
3 changes: 3 additions & 0 deletions configs/riscv64-dual-xs-ref_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ CONFIG_RV_SVINVAL=y
CONFIG_RV_SV48=y
CONFIG_RV_SVNAPOT=y
CONFIG_RV_SVPBMT=y
CONFIG_RV_SSNPM=y
CONFIG_RV_SMNPM=y
CONFIG_RV_SMMPM=y
CONFIG_RV_SSCOFPMF=y
CONFIG_RV_SHLCOFIDELEG=y
CONFIG_RV_SMSTATEEN=y
Expand Down
3 changes: 3 additions & 0 deletions configs/riscv64-xs-cpt_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ CONFIG_RV_SVINVAL=y
CONFIG_RV_SV48=y
CONFIG_RV_SVNAPOT=y
CONFIG_RV_SVPBMT=y
CONFIG_RV_SSNPM=y
CONFIG_RV_SMNPM=y
CONFIG_RV_SMMPM=y
CONFIG_RV_SSCOFPMF=y
CONFIG_RV_SHLCOFIDELEG=y
CONFIG_RV_SMSTATEEN=y
Expand Down
3 changes: 3 additions & 0 deletions configs/riscv64-xs-diff-spike_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ CONFIG_RV_SVINVAL=y
CONFIG_RV_SV48=y
CONFIG_RV_SVNAPOT=y
CONFIG_RV_SVPBMT=y
CONFIG_RV_SSNPM=y
CONFIG_RV_SMNPM=y
CONFIG_RV_SMMPM=y
CONFIG_RV_SSCOFPMF=y
CONFIG_RV_SHLCOFIDELEG=y
# CONFIG_RV_SMSTATEEN is not set
Expand Down
3 changes: 3 additions & 0 deletions configs/riscv64-xs-ref_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ CONFIG_RV_SVINVAL=y
CONFIG_RV_SV48=y
CONFIG_RV_SVNAPOT=y
CONFIG_RV_SVPBMT=y
CONFIG_RV_SSNPM=y
CONFIG_RV_SMNPM=y
CONFIG_RV_SMMPM=y
CONFIG_RV_SSCOFPMF=y
CONFIG_RV_SHLCOFIDELEG=y
CONFIG_RV_SMSTATEEN=y
Expand Down
3 changes: 3 additions & 0 deletions configs/riscv64-xs_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ CONFIG_RV_SVINVAL=y
CONFIG_RV_SV48=y
CONFIG_RV_SVNAPOT=y
CONFIG_RV_SVPBMT=y
CONFIG_RV_SSNPM=y
CONFIG_RV_SMNPM=y
CONFIG_RV_SMMPM=y
CONFIG_RV_SSCOFPMF=y
CONFIG_RV_SHLCOFIDELEG=y
CONFIG_RV_SMSTATEEN=y
Expand Down
3 changes: 3 additions & 0 deletions include/isa.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ int isa_mmu_state();
#ifndef isa_mmu_check
int isa_mmu_check(vaddr_t vaddr, int len, int type);
#endif
#ifndef get_effective_address
vaddr_t get_effective_address(vaddr_t vaddr, int type);
#endif
paddr_t isa_mmu_translate(vaddr_t vaddr, int len, int type);
bool isa_pmp_check_permission(paddr_t addr, int len, int type, int mode);

Expand Down
2 changes: 1 addition & 1 deletion ready-to-run
6 changes: 5 additions & 1 deletion src/isa/mips32/system/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,8 @@ paddr_t isa_mmu_translate(vaddr_t vaddr, int len, int type) {

bool isa_pmp_check_permission(paddr_t paddr, int len, int type, int mode) {
return true; // TODO: complete it
}
}

vaddr_t get_effective_address(vaddr_t vaddr, int type) {
return vaddr;
}
6 changes: 5 additions & 1 deletion src/isa/riscv32/system/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,8 @@ paddr_t isa_mmu_translate(vaddr_t vaddr, int len, int type) {

bool isa_pmp_check_permission(paddr_t addr, int len, int type, int mode) {
return true; // TODO: complete it
}
}

vaddr_t get_effective_address(vaddr_t vaddr, int type) {
return vaddr;
}
23 changes: 22 additions & 1 deletion src/isa/riscv64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,34 @@ config RV_SV48
# bool "Sv57"
# help
# Support Sv39, Sv48 and Sv57.

# The MODE field of CSR satp and vsatp could be set to Bare, Sv39, Sv48 or
# Sv47, and the MODE field of CSR hgatp could be set to Bare, Sv39x4, Sv48x4
# or Sv57x4.

endchoice

config RV_SSNPM
bool "RISC-V Ssnpm extension (part of RISC-V pointer masking extension)"
default n
help
A supervisor-level extension that provides pointer masking for the next
lower privilege mode (U-mode), and for VS- and VU-modes if the H extension
is present.

config RV_SMNPM
bool "RISC-V Smnpm extension (part of RISC-V pointer masking extension)"
default n
help
A machine-level extension that provides pointer masking for the next lower
privilege mode (S/HS if S-mode is implemented, or U-mode otherwise).

config RV_SMMPM
bool "RISC-V Smmpm extension (part of RISC-V pointer masking extension)"
default n
help
A machine-level extension that provides pointer masking for M-mode.

config RV_SVNAPOT
bool "RISC-V Svnapot extension for NAPOT Translation Contiguity (alpha)"
default n
Expand Down
35 changes: 20 additions & 15 deletions src/isa/riscv64/local-include/csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,9 @@ CSR_STRUCT_START(mseccfg)
uint64_t useed : 1; // [8]
uint64_t sseed : 1; // [9]
uint64_t mlpe : 1; // [10]
uint64_t pad1 :53; // [63:11]
uint64_t pad1 :21; // [31:11]
uint64_t pmm : 2; // [33:32]
uint64_t pad2 :30; // [63:34]
CSR_STRUCT_END(mseccfg)

#ifdef CONFIG_RV_SMSTATEEN
Expand Down Expand Up @@ -1089,20 +1091,23 @@ CSR_STRUCT_END(stopi)

#ifdef CONFIG_RVH
CSR_STRUCT_START(hstatus)
uint64_t pad0 : 5;
uint64_t vsbe : 1;
uint64_t gva : 1;
uint64_t spv : 1;
uint64_t spvp : 1;
uint64_t hu : 1;
uint64_t pad1 : 2;
uint64_t vgein : 6;
uint64_t pad2 : 2;
uint64_t vtvm : 1;
uint64_t vtw : 1;
uint64_t vtsr : 1;
uint64_t pad3 : 9;
uint64_t vsxl : 2;
uint64_t pad0 : 5; // [4:0]
uint64_t vsbe : 1; // [5]
uint64_t gva : 1; // [6]
uint64_t spv : 1; // [7]
uint64_t spvp : 1; // [8]
uint64_t hu : 1; // [9]
uint64_t pad1 : 2; // [11:10]
uint64_t vgein : 6; // [17:12]
uint64_t pad2 : 2; // [19:18]
uint64_t vtvm : 1; // [20]
uint64_t vtw : 1; // [21]
uint64_t vtsr : 1; // [22]
uint64_t pad3 : 9; // [31:23]
uint64_t vsxl : 2; // [33:32]
uint64_t pad4 : 14; // [47:34]
uint64_t hupmm : 2; // [49:48]
uint64_t pad5 : 14; // [63:50]
CSR_STRUCT_END(hstatus)

CSR_STRUCT_START(hedeleg)
Expand Down
68 changes: 64 additions & 4 deletions src/isa/riscv64/system/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ static inline bool check_permission(PTE *pte, bool ok, vaddr_t vaddr, int type)
}
return true;
}

#ifndef CONFIG_RVH
vaddr_t get_effective_address(vaddr_t vaddr, int type) {
return vaddr;
}
#endif

#ifdef CONFIG_RVH
bool has_two_stage_translation(){
return hld_st || (mstatus->mprv && mstatus->mpv) || cpu.v;
Expand Down Expand Up @@ -176,6 +183,59 @@ void raise_guest_excep(paddr_t gpaddr, vaddr_t vaddr, int type, bool is_support_
longjmp_exception(ex);
}

vaddr_t get_effective_address(vaddr_t vaddr, int type) {
if (type == MEM_TYPE_IFETCH || hlvx) {
return vaddr;
}

bool virt = cpu.v;
int mode = cpu.mode;
int pmm = 0;
int masked_width = 0;

if (hld_st) {
mode = hstatus->spvp;
virt = true;
} else if (mstatus->mprv) {
mode = mstatus->mpp;
virt = mstatus->mpv && mode != MODE_M;
}

if (mode == MODE_M) {
pmm = mseccfg->pmm;
} else if (!virt && mode == MODE_S) {
pmm = menvcfg->pmm;
} else if (virt && mode == MODE_S) {
pmm = henvcfg->pmm;
// Is cpu.mode here
} else if (hld_st && cpu.mode == MODE_U) {
pmm = hstatus->hupmm;
} else if (mode == MODE_U) {
pmm = senvcfg->pmm;
} else {
assert(0);
}

switch (pmm) {
case 2:
masked_width = 7;
break;
case 3:
masked_width = 16;
break;
}

bool isBare = mode == MODE_M;
bool isPaddr = !virt && satp->mode == SATP_MODE_BARE;
bool isGpaddr = virt && vsatp->mode == SATP_MODE_BARE;

if (isBare || isPaddr || isGpaddr) {
return ((uint64_t)vaddr << masked_width) >> masked_width;
} else {
return ((int64_t)vaddr << masked_width) >> masked_width;
}
}

paddr_t gpa_stage(paddr_t gpaddr, vaddr_t vaddr, int type, int trap_type, bool ishlvx, bool is_support_vs){
Logtr("gpa_stage gpaddr: " FMT_PADDR ", vaddr: " FMT_WORD ", type: %d", gpaddr, vaddr, type);
int max_level = 0;
Expand Down Expand Up @@ -495,7 +555,7 @@ int isa_mmu_check(vaddr_t vaddr, int len, int type) {
bool enable_39 = satp->mode == SATP_MODE_Sv39 || ((cpu.v || hld_st) && (vsatp->mode == SATP_MODE_Sv39 || hgatp->mode == HGATP_MODE_Sv39x4));
bool enable_48 = satp->mode == SATP_MODE_Sv48 || ((cpu.v || hld_st) && (vsatp->mode == SATP_MODE_Sv48 || hgatp->mode == HGATP_MODE_Sv48x4));
bool vm_enable = (mstatus->mprv && (!is_ifetch) ? mstatus->mpp : cpu.mode) < MODE_M && (enable_39 || enable_48);
bool hyperinst_vm_enable = hld_st && (vsatp->mode == SATP_MODE_Sv39 || hgatp->mode == HGATP_MODE_Sv39x4);
bool hyperinst_vm_enable = hld_st && (vsatp->mode == SATP_MODE_Sv39 || vsatp->mode == SATP_MODE_Sv48 || hgatp->mode == HGATP_MODE_Sv39x4 || hgatp->mode == HGATP_MODE_Sv48x4);
#else
bool enable_39 = satp->mode == SATP_MODE_Sv39;
bool enable_48 = satp->mode == SATP_MODE_Sv48;
Expand Down Expand Up @@ -541,7 +601,7 @@ int isa_mmu_check(vaddr_t vaddr, int len, int type) {
if(is_ifetch){
cpu.trapInfo.tval = vaddr;
#ifdef CONFIG_RVH
if (hld_st || gpf) {
if (gpf) {
cpu.trapInfo.tval2 = vaddr >> 2;
longjmp_exception(EX_IGPF);
} else {
Expand All @@ -554,7 +614,7 @@ int isa_mmu_check(vaddr_t vaddr, int len, int type) {
cpu.trapInfo.tval = vaddr;
#ifdef CONFIG_RVH
int ex;
if(hld_st || gpf){
if(gpf){
ex = cpu.amo ? EX_SGPF : EX_LGPF;
cpu.trapInfo.tval2 = vaddr >> 2;
} else {
Expand All @@ -568,7 +628,7 @@ int isa_mmu_check(vaddr_t vaddr, int len, int type) {
} else {
cpu.trapInfo.tval = vaddr;
#ifdef CONFIG_RVH
if (hld_st || gpf) {
if (gpf) {
cpu.trapInfo.tval2 = vaddr >> 2;
longjmp_exception(EX_SGPF);
} else {
Expand Down
Loading

0 comments on commit bb91d6f

Please sign in to comment.