[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250111004702.2813013-3-samuel.holland@sifive.com>
Date: Fri, 10 Jan 2025 16:46:59 -0800
From: Samuel Holland <samuel.holland@...ive.com>
To: Anup Patel <anup@...infault.org>,
Atish Patra <atishp@...shpatra.org>,
kvm-riscv@...ts.infradead.org,
linux-riscv@...ts.infradead.org
Cc: Samuel Holland <samuel.holland@...ive.com>,
Albert Ou <aou@...s.berkeley.edu>,
Palmer Dabbelt <palmer@...belt.com>,
Paul Walmsley <paul.walmsley@...ive.com>,
kvm@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [RFC PATCH 2/2] RISC-V: KVM: Add support for SBI_FWFT_POINTER_MASKING_PMLEN
Pointer masking is controlled through a WARL field in henvcfg. Expose
the feature only if at least one PMLEN value is supported for VS-mode.
Allow the VMM to block access to the feature by disabling the Smnpm ISA
extension in the guest.
Signed-off-by: Samuel Holland <samuel.holland@...ive.com>
---
arch/riscv/include/asm/kvm_vcpu_sbi_fwft.h | 2 +
arch/riscv/kvm/vcpu_onereg.c | 1 -
arch/riscv/kvm/vcpu_sbi_fwft.c | 70 +++++++++++++++++++++-
3 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi_fwft.h b/arch/riscv/include/asm/kvm_vcpu_sbi_fwft.h
index 5782517f6e08..5176344d9162 100644
--- a/arch/riscv/include/asm/kvm_vcpu_sbi_fwft.h
+++ b/arch/riscv/include/asm/kvm_vcpu_sbi_fwft.h
@@ -30,6 +30,8 @@ struct kvm_sbi_fwft_config {
/* FWFT data structure per vcpu */
struct kvm_sbi_fwft {
struct kvm_sbi_fwft_config *configs;
+ bool have_vs_pmlen_7;
+ bool have_vs_pmlen_16;
};
#define vcpu_to_fwft(vcpu) (&(vcpu)->arch.fwft_context)
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 93115abca3b8..1d2033b33e6d 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -168,7 +168,6 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
case KVM_RISCV_ISA_EXT_C:
case KVM_RISCV_ISA_EXT_I:
case KVM_RISCV_ISA_EXT_M:
- case KVM_RISCV_ISA_EXT_SMNPM:
/* There is not architectural config bit to disable sscofpmf completely */
case KVM_RISCV_ISA_EXT_SSCOFPMF:
case KVM_RISCV_ISA_EXT_SSNPM:
diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
index 1e85ff6666af..6e8f818fd6f5 100644
--- a/arch/riscv/kvm/vcpu_sbi_fwft.c
+++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
@@ -68,13 +68,81 @@ static int kvm_sbi_fwft_get_misaligned_delegation(struct kvm_vcpu *vcpu,
return SBI_SUCCESS;
}
+static bool try_to_set_pmm(unsigned long value)
+{
+ csr_set(CSR_HENVCFG, value);
+ return (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
+}
+
+static bool kvm_sbi_fwft_pointer_masking_pmlen_supported(struct kvm_vcpu *vcpu)
+{
+ struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
+
+ if (!riscv_isa_extension_available(vcpu->arch.isa, SMNPM))
+ return false;
+
+ fwft->have_vs_pmlen_7 = try_to_set_pmm(ENVCFG_PMM_PMLEN_7);
+ fwft->have_vs_pmlen_16 = try_to_set_pmm(ENVCFG_PMM_PMLEN_16);
+
+ return fwft->have_vs_pmlen_7 || fwft->have_vs_pmlen_16;
+}
+
+static int kvm_sbi_fwft_set_pointer_masking_pmlen(struct kvm_vcpu *vcpu,
+ struct kvm_sbi_fwft_config *conf,
+ unsigned long value)
+{
+ struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
+ unsigned long pmm;
+
+ if (value == 0)
+ pmm = ENVCFG_PMM_PMLEN_0;
+ else if (value <= 7 && fwft->have_vs_pmlen_7)
+ pmm = ENVCFG_PMM_PMLEN_7;
+ else if (value <= 16 && fwft->have_vs_pmlen_16)
+ pmm = ENVCFG_PMM_PMLEN_16;
+ else
+ return SBI_ERR_INVALID_PARAM;
+
+ vcpu->arch.cfg.henvcfg &= ~ENVCFG_PMM;
+ vcpu->arch.cfg.henvcfg |= pmm;
+
+ return SBI_SUCCESS;
+}
+
+static int kvm_sbi_fwft_get_pointer_masking_pmlen(struct kvm_vcpu *vcpu,
+ struct kvm_sbi_fwft_config *conf,
+ unsigned long *value)
+{
+ switch (vcpu->arch.cfg.henvcfg & ENVCFG_PMM) {
+ case ENVCFG_PMM_PMLEN_0:
+ *value = 0;
+ break;
+ case ENVCFG_PMM_PMLEN_7:
+ *value = 7;
+ break;
+ case ENVCFG_PMM_PMLEN_16:
+ *value = 16;
+ break;
+ default:
+ return SBI_ERR_FAILURE;
+ }
+
+ return SBI_SUCCESS;
+}
+
static const struct kvm_sbi_fwft_feature features[] = {
{
.id = SBI_FWFT_MISALIGNED_EXC_DELEG,
.supported = kvm_sbi_fwft_misaligned_delegation_supported,
.set = kvm_sbi_fwft_set_misaligned_delegation,
.get = kvm_sbi_fwft_get_misaligned_delegation,
- }
+ },
+ {
+ .id = SBI_FWFT_POINTER_MASKING_PMLEN,
+ .supported = kvm_sbi_fwft_pointer_masking_pmlen_supported,
+ .set = kvm_sbi_fwft_set_pointer_masking_pmlen,
+ .get = kvm_sbi_fwft_get_pointer_masking_pmlen,
+ },
};
static struct kvm_sbi_fwft_config *
--
2.47.0
Powered by blists - more mailing lists