Skip to content

Commit 95c9910

Browse files
Andrew Jonesavpatel
authored andcommitted
RISC-V: KVM: Probe for SBI extension status
Rather than defaulting the status to available and allowing the user to set availability, default to uninitialized and only allow the user to set the status to unavailable. Then, when an extension is first used, ensure it is available by invoking its probe function, if it has one (an extension is assumed available if it doesn't have a probe function). Checking the status in kvm_vcpu_sbi_find_ext() ensures extension functions cannot be invoked when they're unavailable. Signed-off-by: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Anup Patel <anup@brainfault.org> Signed-off-by: Anup Patel <anup@brainfault.org>
1 parent 9f9e3eb commit 95c9910

2 files changed

Lines changed: 40 additions & 12 deletions

File tree

arch/riscv/include/asm/kvm_vcpu_sbi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define KVM_SBI_VERSION_MINOR 0
1616

1717
enum kvm_riscv_sbi_ext_status {
18+
KVM_RISCV_SBI_EXT_UNINITIALIZED,
1819
KVM_RISCV_SBI_EXT_AVAILABLE,
1920
KVM_RISCV_SBI_EXT_UNAVAILABLE,
2021
};

arch/riscv/kvm/vcpu_sbi.c

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,15 @@ static int riscv_vcpu_set_sbi_ext_single(struct kvm_vcpu *vcpu,
155155
if (!sext)
156156
return -ENOENT;
157157

158-
scontext->ext_status[sext->ext_idx] = reg_val ?
159-
KVM_RISCV_SBI_EXT_AVAILABLE : KVM_RISCV_SBI_EXT_UNAVAILABLE;
158+
/*
159+
* We can't set the extension status to available here, since it may
160+
* have a probe() function which needs to confirm availability first,
161+
* but it may be too early to call that here. We can set the status to
162+
* unavailable, though.
163+
*/
164+
if (!reg_val)
165+
scontext->ext_status[sext->ext_idx] =
166+
KVM_RISCV_SBI_EXT_UNAVAILABLE;
160167

161168
return 0;
162169
}
@@ -181,8 +188,15 @@ static int riscv_vcpu_get_sbi_ext_single(struct kvm_vcpu *vcpu,
181188
if (!sext)
182189
return -ENOENT;
183190

184-
*reg_val = scontext->ext_status[sext->ext_idx] ==
185-
KVM_RISCV_SBI_EXT_AVAILABLE;
191+
/*
192+
* If the extension status is still uninitialized, then we should probe
193+
* to determine if it's available, but it may be too early to do that
194+
* here. The best we can do is report that the extension has not been
195+
* disabled, i.e. we return 1 when the extension is available and also
196+
* when it only may be available.
197+
*/
198+
*reg_val = scontext->ext_status[sext->ext_idx] !=
199+
KVM_RISCV_SBI_EXT_UNAVAILABLE;
186200

187201
return 0;
188202
}
@@ -309,19 +323,32 @@ int kvm_riscv_vcpu_get_reg_sbi_ext(struct kvm_vcpu *vcpu,
309323
const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(
310324
struct kvm_vcpu *vcpu, unsigned long extid)
311325
{
312-
int i;
313-
const struct kvm_riscv_sbi_extension_entry *sext;
314326
struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context;
327+
const struct kvm_riscv_sbi_extension_entry *entry;
328+
const struct kvm_vcpu_sbi_extension *ext;
329+
int i;
315330

316331
for (i = 0; i < ARRAY_SIZE(sbi_ext); i++) {
317-
sext = &sbi_ext[i];
318-
if (sext->ext_ptr->extid_start <= extid &&
319-
sext->ext_ptr->extid_end >= extid) {
320-
if (sext->ext_idx < KVM_RISCV_SBI_EXT_MAX &&
321-
scontext->ext_status[sext->ext_idx] ==
332+
entry = &sbi_ext[i];
333+
ext = entry->ext_ptr;
334+
335+
if (ext->extid_start <= extid && ext->extid_end >= extid) {
336+
if (entry->ext_idx >= KVM_RISCV_SBI_EXT_MAX ||
337+
scontext->ext_status[entry->ext_idx] ==
338+
KVM_RISCV_SBI_EXT_AVAILABLE)
339+
return ext;
340+
if (scontext->ext_status[entry->ext_idx] ==
322341
KVM_RISCV_SBI_EXT_UNAVAILABLE)
323342
return NULL;
324-
return sbi_ext[i].ext_ptr;
343+
if (ext->probe && !ext->probe(vcpu)) {
344+
scontext->ext_status[entry->ext_idx] =
345+
KVM_RISCV_SBI_EXT_UNAVAILABLE;
346+
return NULL;
347+
}
348+
349+
scontext->ext_status[entry->ext_idx] =
350+
KVM_RISCV_SBI_EXT_AVAILABLE;
351+
return ext;
325352
}
326353
}
327354

0 commit comments

Comments
 (0)