Skip to content

Commit 6f576fc

Browse files
SiFiveHollandavpatel
authored andcommitted
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@sifive.com> Reviewed-by: Anup Patel <anup@brainfault.org> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Link: https://lore.kernel.org/r/20250111004702.2813013-3-samuel.holland@sifive.com Signed-off-by: Anup Patel <anup@brainfault.org>
1 parent bb053f8 commit 6f576fc

3 files changed

Lines changed: 94 additions & 1 deletion

File tree

arch/riscv/include/asm/kvm_vcpu_sbi_fwft.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ struct kvm_sbi_fwft_config {
2222
/* FWFT data structure per vcpu */
2323
struct kvm_sbi_fwft {
2424
struct kvm_sbi_fwft_config *configs;
25+
#ifndef CONFIG_32BIT
26+
bool have_vs_pmlen_7;
27+
bool have_vs_pmlen_16;
28+
#endif
2529
};
2630

2731
#define vcpu_to_fwft(vcpu) (&(vcpu)->arch.fwft_context)

arch/riscv/kvm/vcpu_onereg.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,6 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
173173
case KVM_RISCV_ISA_EXT_C:
174174
case KVM_RISCV_ISA_EXT_I:
175175
case KVM_RISCV_ISA_EXT_M:
176-
case KVM_RISCV_ISA_EXT_SMNPM:
177176
/* There is not architectural config bit to disable sscofpmf completely */
178177
case KVM_RISCV_ISA_EXT_SSCOFPMF:
179178
case KVM_RISCV_ISA_EXT_SSNPM:

arch/riscv/kvm/vcpu_sbi_fwft.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,103 @@ static long kvm_sbi_fwft_get_misaligned_delegation(struct kvm_vcpu *vcpu,
103103
return SBI_SUCCESS;
104104
}
105105

106+
#ifndef CONFIG_32BIT
107+
108+
static bool try_to_set_pmm(unsigned long value)
109+
{
110+
csr_set(CSR_HENVCFG, value);
111+
return (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
112+
}
113+
114+
static bool kvm_sbi_fwft_pointer_masking_pmlen_supported(struct kvm_vcpu *vcpu)
115+
{
116+
struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
117+
118+
if (!riscv_isa_extension_available(vcpu->arch.isa, SMNPM))
119+
return false;
120+
121+
fwft->have_vs_pmlen_7 = try_to_set_pmm(ENVCFG_PMM_PMLEN_7);
122+
fwft->have_vs_pmlen_16 = try_to_set_pmm(ENVCFG_PMM_PMLEN_16);
123+
124+
return fwft->have_vs_pmlen_7 || fwft->have_vs_pmlen_16;
125+
}
126+
127+
static long kvm_sbi_fwft_set_pointer_masking_pmlen(struct kvm_vcpu *vcpu,
128+
struct kvm_sbi_fwft_config *conf,
129+
unsigned long value)
130+
{
131+
struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
132+
unsigned long pmm;
133+
134+
switch (value) {
135+
case 0:
136+
pmm = ENVCFG_PMM_PMLEN_0;
137+
break;
138+
case 7:
139+
if (!fwft->have_vs_pmlen_7)
140+
return SBI_ERR_INVALID_PARAM;
141+
pmm = ENVCFG_PMM_PMLEN_7;
142+
break;
143+
case 16:
144+
if (!fwft->have_vs_pmlen_16)
145+
return SBI_ERR_INVALID_PARAM;
146+
pmm = ENVCFG_PMM_PMLEN_16;
147+
break;
148+
default:
149+
return SBI_ERR_INVALID_PARAM;
150+
}
151+
152+
vcpu->arch.cfg.henvcfg &= ~ENVCFG_PMM;
153+
vcpu->arch.cfg.henvcfg |= pmm;
154+
155+
/*
156+
* Instead of waiting for vcpu_load/put() to update HENVCFG CSR,
157+
* update here so that VCPU see's pointer masking mode change
158+
* immediately.
159+
*/
160+
csr_write(CSR_HENVCFG, vcpu->arch.cfg.henvcfg);
161+
162+
return SBI_SUCCESS;
163+
}
164+
165+
static long kvm_sbi_fwft_get_pointer_masking_pmlen(struct kvm_vcpu *vcpu,
166+
struct kvm_sbi_fwft_config *conf,
167+
unsigned long *value)
168+
{
169+
switch (vcpu->arch.cfg.henvcfg & ENVCFG_PMM) {
170+
case ENVCFG_PMM_PMLEN_0:
171+
*value = 0;
172+
break;
173+
case ENVCFG_PMM_PMLEN_7:
174+
*value = 7;
175+
break;
176+
case ENVCFG_PMM_PMLEN_16:
177+
*value = 16;
178+
break;
179+
default:
180+
return SBI_ERR_FAILURE;
181+
}
182+
183+
return SBI_SUCCESS;
184+
}
185+
186+
#endif
187+
106188
static const struct kvm_sbi_fwft_feature features[] = {
107189
{
108190
.id = SBI_FWFT_MISALIGNED_EXC_DELEG,
109191
.supported = kvm_sbi_fwft_misaligned_delegation_supported,
110192
.set = kvm_sbi_fwft_set_misaligned_delegation,
111193
.get = kvm_sbi_fwft_get_misaligned_delegation,
112194
},
195+
#ifndef CONFIG_32BIT
196+
{
197+
.id = SBI_FWFT_POINTER_MASKING_PMLEN,
198+
.supported = kvm_sbi_fwft_pointer_masking_pmlen_supported,
199+
.set = kvm_sbi_fwft_set_pointer_masking_pmlen,
200+
.get = kvm_sbi_fwft_get_pointer_masking_pmlen,
201+
},
202+
#endif
113203
};
114204

115205
static struct kvm_sbi_fwft_config *

0 commit comments

Comments
 (0)