From fd213fc19e927efc0cf506659eef2ca639f5a375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me?= <124148386+cathales@users.noreply.github.com> Date: Thu, 12 Dec 2024 19:10:26 +0100 Subject: [PATCH 1/2] cut dangerous path from flush to issue (#2666) serdiv is the only FLU which has a combinational path from flush_i to the result bus --- .gitlab-ci/expected_synth.yml | 2 +- core/serdiv.sv | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci/expected_synth.yml b/.gitlab-ci/expected_synth.yml index 969e5e815d..9f151284aa 100644 --- a/.gitlab-ci/expected_synth.yml +++ b/.gitlab-ci/expected_synth.yml @@ -1,2 +1,2 @@ cv32a65x: - gates: 188627 + gates: 187456 diff --git a/core/serdiv.sv b/core/serdiv.sv index a9d3a1a30c..fd103fbb91 100644 --- a/core/serdiv.sv +++ b/core/serdiv.sv @@ -218,12 +218,10 @@ module serdiv endcase if (flush_i) begin - in_rdy_o = 1'b0; - out_vld_o = 1'b0; - a_reg_en = 1'b0; - b_reg_en = 1'b0; - load_en = 1'b0; - state_d = IDLE; + a_reg_en = 1'b0; + b_reg_en = 1'b0; + load_en = 1'b0; + state_d = IDLE; end end From f4355fa49b6ed592579146dbfc65a34f3bbd6ed2 Mon Sep 17 00:00:00 2001 From: Fatima Saleem <63645133+fatimasaleem@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:07:24 +0500 Subject: [PATCH 2/2] bug fix: canonical check on virtual address for data accesses (#2667) As mentioned in the spec, we need to perform a canonical check on the virtual address for instruction fetch, load, and store. If the check fails, it will cause the page-fault exception. This PR fixes the above two: - Changes INSTR_ACCESS_FAULT to INSTR_PAGE_FAULT - Adding virtual address check on data accesses as well --- core/cva6_mmu/cva6_mmu.sv | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/cva6_mmu/cva6_mmu.sv b/core/cva6_mmu/cva6_mmu.sv index ccb12e9fd8..8c1791bbf0 100644 --- a/core/cva6_mmu/cva6_mmu.sv +++ b/core/cva6_mmu/cva6_mmu.sv @@ -133,6 +133,7 @@ module cva6_mmu logic iaccess_err; // insufficient privilege to access this instruction page logic i_g_st_access_err; // insufficient privilege at g stage to access this instruction page logic daccess_err; // insufficient privilege to access this data page + logic canonical_addr_check; // canonical check on the virtual address for SV39 logic d_g_st_access_err; // insufficient privilege to access this data page logic ptw_active; // PTW is currently walking a page table logic walking_instr; // PTW is walking because of an ITLB miss @@ -380,7 +381,7 @@ module cva6_mmu // we work with SV39 or SV32, so if VM is enabled, check that all bits [CVA6Cfg.VLEN-1:CVA6Cfg.SV-1] are equal if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[CVA6Cfg.VLEN-1:CVA6Cfg.SV-1]) == 1'b1 || (|icache_areq_i.fetch_vaddr[CVA6Cfg.VLEN-1:CVA6Cfg.SV-1]) == 1'b0)) begin - icache_areq_o.fetch_exception.cause = riscv::INSTR_ACCESS_FAULT; + icache_areq_o.fetch_exception.cause = riscv::INSTR_PAGE_FAULT; icache_areq_o.fetch_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) icache_areq_o.fetch_exception.tval = CVA6Cfg.XLEN'(icache_areq_i.fetch_vaddr); @@ -512,6 +513,10 @@ module cva6_mmu lsu_valid_o = lsu_req_q; lsu_exception_o = misaligned_ex_i; + // we work with SV39 or SV32, so if VM is enabled, check that all bits [CVA6Cfg.VLEN-1:CVA6Cfg.SV-1] are equal to bit [CVA6Cfg.SV] + canonical_addr_check = (lsu_req_i && en_ld_st_translation_i && + !((&lsu_vaddr_i[CVA6Cfg.VLEN-1:CVA6Cfg.SV-1]) == 1'b1 || (|lsu_vaddr_i[CVA6Cfg.VLEN-1:CVA6Cfg.SV-1]) == 1'b0)); + // Check if the User flag is set, then we may only access it in supervisor mode // if SUM is enabled daccess_err = en_ld_st_translation_i && @@ -578,7 +583,7 @@ module cva6_mmu lsu_exception_o.tinst = '0; lsu_exception_o.gva = ld_st_v_i; end - end else if ((en_ld_st_translation_i || !CVA6Cfg.RVH) && (!dtlb_pte_q.w || daccess_err || !dtlb_pte_q.d)) begin + end else if ((en_ld_st_translation_i || !CVA6Cfg.RVH) && (!dtlb_pte_q.w || daccess_err || canonical_addr_check || !dtlb_pte_q.d)) begin lsu_exception_o.cause = riscv::STORE_PAGE_FAULT; lsu_exception_o.valid = 1'b1; if (CVA6Cfg.TvalEn) @@ -606,7 +611,7 @@ module cva6_mmu lsu_exception_o.gva = ld_st_v_i; end // check for sufficient access privileges - throw a page fault if necessary - end else if (daccess_err) begin + end else if (daccess_err || canonical_addr_check) begin lsu_exception_o.cause = riscv::LOAD_PAGE_FAULT; lsu_exception_o.valid = 1'b1; if (CVA6Cfg.TvalEn)