* [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code
@ 2023-08-03 16:32 Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 01/10] RISC-V: KVM: return ENOENT in *_one_reg() when reg is unknown Daniel Henrique Barboza
` (11 more replies)
0 siblings, 12 replies; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-08-03 16:32 UTC (permalink / raw)
To: kvm-riscv
Hi,
This version includes a diff that Andrew mentioned in v2 [1] that I
missed. They were squashed into patch 1.
No other changes made. Patches rebased on top of riscv_kvm_queue.
Changes from v3:
- patch 1:
- added missing EINVAL - ENOENT conversions
- v3 link: https://lore.kernel.org/kvm/20230803140022.399333-1-dbarboza at ventanamicro.com/
[1] https://lore.kernel.org/kvm/20230801222629.210929-1-dbarboza at ventanamicro.com/
Andrew Jones (1):
RISC-V: KVM: Improve vector save/restore errors
Daniel Henrique Barboza (9):
RISC-V: KVM: return ENOENT in *_one_reg() when reg is unknown
RISC-V: KVM: use ENOENT in *_one_reg() when extension is unavailable
RISC-V: KVM: do not EOPNOTSUPP in set_one_reg() zicbo(m|z)
RISC-V: KVM: do not EOPNOTSUPP in set KVM_REG_RISCV_TIMER_REG
RISC-V: KVM: use EBUSY when !vcpu->arch.ran_atleast_once
RISC-V: KVM: avoid EBUSY when writing same ISA val
RISC-V: KVM: avoid EBUSY when writing the same machine ID val
RISC-V: KVM: avoid EBUSY when writing the same isa_ext val
docs: kvm: riscv: document EBUSY in KVM_SET_ONE_REG
Documentation/virt/kvm/api.rst | 2 +
arch/riscv/kvm/aia.c | 4 +-
arch/riscv/kvm/vcpu_fp.c | 12 +++---
arch/riscv/kvm/vcpu_onereg.c | 74 ++++++++++++++++++++++------------
arch/riscv/kvm/vcpu_sbi.c | 16 ++++----
arch/riscv/kvm/vcpu_timer.c | 11 ++---
arch/riscv/kvm/vcpu_vector.c | 60 ++++++++++++++-------------
7 files changed, 107 insertions(+), 72 deletions(-)
--
2.41.0
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 01/10] RISC-V: KVM: return ENOENT in *_one_reg() when reg is unknown
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
@ 2023-08-03 16:32 ` Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 02/10] RISC-V: KVM: use ENOENT in *_one_reg() when extension is unavailable Daniel Henrique Barboza
` (10 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-08-03 16:32 UTC (permalink / raw)
To: kvm-riscv
get_one_reg() and set_one_reg() are returning EINVAL errors for almost
everything: if a reg doesn't exist, if a reg ID is malformatted, if the
associated CPU extension that implements the reg isn't present in the
host, and for set_one_reg() if the value being written is invalid.
This isn't wrong according to the existing KVM API docs (EINVAL can be
used when there's no such register) but adding more ENOENT instances
will make easier for userspace to understand what went wrong.
Existing userspaces can be affected by this error code change. We
checked a few. As of current upstream code, crosvm doesn't check for any
particular errno code when using kvm_(get|set)_one_reg(). Neither does
QEMU. rust-vmm doesn't have kvm-riscv support yet. Thus we have a good
chance of changing these error codes now while the KVM RISC-V ecosystem
is still new, minimizing user impact.
Change all get_one_reg() and set_one_reg() implementations to return
-ENOENT at all "no such register" cases.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
arch/riscv/kvm/aia.c | 4 ++--
arch/riscv/kvm/vcpu_fp.c | 12 ++++++------
arch/riscv/kvm/vcpu_onereg.c | 36 ++++++++++++++++++------------------
arch/riscv/kvm/vcpu_sbi.c | 16 +++++++++-------
arch/riscv/kvm/vcpu_timer.c | 8 ++++----
5 files changed, 39 insertions(+), 37 deletions(-)
diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
index 585a3b42c52c..74bb27440527 100644
--- a/arch/riscv/kvm/aia.c
+++ b/arch/riscv/kvm/aia.c
@@ -176,7 +176,7 @@ int kvm_riscv_vcpu_aia_get_csr(struct kvm_vcpu *vcpu,
struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr;
if (reg_num >= sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long))
- return -EINVAL;
+ return -ENOENT;
*out_val = 0;
if (kvm_riscv_aia_available())
@@ -192,7 +192,7 @@ int kvm_riscv_vcpu_aia_set_csr(struct kvm_vcpu *vcpu,
struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr;
if (reg_num >= sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long))
- return -EINVAL;
+ return -ENOENT;
if (kvm_riscv_aia_available()) {
((unsigned long *)csr)[reg_num] = val;
diff --git a/arch/riscv/kvm/vcpu_fp.c b/arch/riscv/kvm/vcpu_fp.c
index 9d8cbc42057a..08ba48a395aa 100644
--- a/arch/riscv/kvm/vcpu_fp.c
+++ b/arch/riscv/kvm/vcpu_fp.c
@@ -96,7 +96,7 @@ int kvm_riscv_vcpu_get_reg_fp(struct kvm_vcpu *vcpu,
reg_num <= KVM_REG_RISCV_FP_F_REG(f[31]))
reg_val = &cntx->fp.f.f[reg_num];
else
- return -EINVAL;
+ return -ENOENT;
} else if ((rtype == KVM_REG_RISCV_FP_D) &&
riscv_isa_extension_available(vcpu->arch.isa, d)) {
if (reg_num == KVM_REG_RISCV_FP_D_REG(fcsr)) {
@@ -109,9 +109,9 @@ int kvm_riscv_vcpu_get_reg_fp(struct kvm_vcpu *vcpu,
return -EINVAL;
reg_val = &cntx->fp.d.f[reg_num];
} else
- return -EINVAL;
+ return -ENOENT;
} else
- return -EINVAL;
+ return -ENOENT;
if (copy_to_user(uaddr, reg_val, KVM_REG_SIZE(reg->id)))
return -EFAULT;
@@ -141,7 +141,7 @@ int kvm_riscv_vcpu_set_reg_fp(struct kvm_vcpu *vcpu,
reg_num <= KVM_REG_RISCV_FP_F_REG(f[31]))
reg_val = &cntx->fp.f.f[reg_num];
else
- return -EINVAL;
+ return -ENOENT;
} else if ((rtype == KVM_REG_RISCV_FP_D) &&
riscv_isa_extension_available(vcpu->arch.isa, d)) {
if (reg_num == KVM_REG_RISCV_FP_D_REG(fcsr)) {
@@ -154,9 +154,9 @@ int kvm_riscv_vcpu_set_reg_fp(struct kvm_vcpu *vcpu,
return -EINVAL;
reg_val = &cntx->fp.d.f[reg_num];
} else
- return -EINVAL;
+ return -ENOENT;
} else
- return -EINVAL;
+ return -ENOENT;
if (copy_from_user(reg_val, uaddr, KVM_REG_SIZE(reg->id)))
return -EFAULT;
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 85773e858120..456e9f31441a 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -156,7 +156,7 @@ static int kvm_riscv_vcpu_get_reg_config(struct kvm_vcpu *vcpu,
reg_val = satp_mode >> SATP_MODE_SHIFT;
break;
default:
- return -EINVAL;
+ return -ENOENT;
}
if (copy_to_user(uaddr, ®_val, KVM_REG_SIZE(reg->id)))
@@ -242,7 +242,7 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
return -EINVAL;
break;
default:
- return -EINVAL;
+ return -ENOENT;
}
return 0;
@@ -262,7 +262,7 @@ static int kvm_riscv_vcpu_get_reg_core(struct kvm_vcpu *vcpu,
if (KVM_REG_SIZE(reg->id) != sizeof(unsigned long))
return -EINVAL;
if (reg_num >= sizeof(struct kvm_riscv_core) / sizeof(unsigned long))
- return -EINVAL;
+ return -ENOENT;
if (reg_num == KVM_REG_RISCV_CORE_REG(regs.pc))
reg_val = cntx->sepc;
@@ -273,7 +273,7 @@ static int kvm_riscv_vcpu_get_reg_core(struct kvm_vcpu *vcpu,
reg_val = (cntx->sstatus & SR_SPP) ?
KVM_RISCV_MODE_S : KVM_RISCV_MODE_U;
else
- return -EINVAL;
+ return -ENOENT;
if (copy_to_user(uaddr, ®_val, KVM_REG_SIZE(reg->id)))
return -EFAULT;
@@ -295,7 +295,7 @@ static int kvm_riscv_vcpu_set_reg_core(struct kvm_vcpu *vcpu,
if (KVM_REG_SIZE(reg->id) != sizeof(unsigned long))
return -EINVAL;
if (reg_num >= sizeof(struct kvm_riscv_core) / sizeof(unsigned long))
- return -EINVAL;
+ return -ENOENT;
if (copy_from_user(®_val, uaddr, KVM_REG_SIZE(reg->id)))
return -EFAULT;
@@ -311,7 +311,7 @@ static int kvm_riscv_vcpu_set_reg_core(struct kvm_vcpu *vcpu,
else
cntx->sstatus &= ~SR_SPP;
} else
- return -EINVAL;
+ return -ENOENT;
return 0;
}
@@ -323,7 +323,7 @@ static int kvm_riscv_vcpu_general_get_csr(struct kvm_vcpu *vcpu,
struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr;
if (reg_num >= sizeof(struct kvm_riscv_csr) / sizeof(unsigned long))
- return -EINVAL;
+ return -ENOENT;
if (reg_num == KVM_REG_RISCV_CSR_REG(sip)) {
kvm_riscv_vcpu_flush_interrupts(vcpu);
@@ -342,7 +342,7 @@ static int kvm_riscv_vcpu_general_set_csr(struct kvm_vcpu *vcpu,
struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr;
if (reg_num >= sizeof(struct kvm_riscv_csr) / sizeof(unsigned long))
- return -EINVAL;
+ return -ENOENT;
if (reg_num == KVM_REG_RISCV_CSR_REG(sip)) {
reg_val &= VSIP_VALID_MASK;
@@ -381,7 +381,7 @@ static int kvm_riscv_vcpu_get_reg_csr(struct kvm_vcpu *vcpu,
rc = kvm_riscv_vcpu_aia_get_csr(vcpu, reg_num, ®_val);
break;
default:
- rc = -EINVAL;
+ rc = -ENOENT;
break;
}
if (rc)
@@ -420,7 +420,7 @@ static int kvm_riscv_vcpu_set_reg_csr(struct kvm_vcpu *vcpu,
rc = kvm_riscv_vcpu_aia_set_csr(vcpu, reg_num, reg_val);
break;
default:
- rc = -EINVAL;
+ rc = -ENOENT;
break;
}
if (rc)
@@ -437,7 +437,7 @@ static int riscv_vcpu_get_isa_ext_single(struct kvm_vcpu *vcpu,
if (reg_num >= KVM_RISCV_ISA_EXT_MAX ||
reg_num >= ARRAY_SIZE(kvm_isa_ext_arr))
- return -EINVAL;
+ return -ENOENT;
*reg_val = 0;
host_isa_ext = kvm_isa_ext_arr[reg_num];
@@ -455,7 +455,7 @@ static int riscv_vcpu_set_isa_ext_single(struct kvm_vcpu *vcpu,
if (reg_num >= KVM_RISCV_ISA_EXT_MAX ||
reg_num >= ARRAY_SIZE(kvm_isa_ext_arr))
- return -EINVAL;
+ return -ENOENT;
host_isa_ext = kvm_isa_ext_arr[reg_num];
if (!__riscv_isa_extension_available(NULL, host_isa_ext))
@@ -489,7 +489,7 @@ static int riscv_vcpu_get_isa_ext_multi(struct kvm_vcpu *vcpu,
unsigned long i, ext_id, ext_val;
if (reg_num > KVM_REG_RISCV_ISA_MULTI_REG_LAST)
- return -EINVAL;
+ return -ENOENT;
for (i = 0; i < BITS_PER_LONG; i++) {
ext_id = i + reg_num * BITS_PER_LONG;
@@ -512,7 +512,7 @@ static int riscv_vcpu_set_isa_ext_multi(struct kvm_vcpu *vcpu,
unsigned long i, ext_id;
if (reg_num > KVM_REG_RISCV_ISA_MULTI_REG_LAST)
- return -EINVAL;
+ return -ENOENT;
for_each_set_bit(i, ®_val, BITS_PER_LONG) {
ext_id = i + reg_num * BITS_PER_LONG;
@@ -554,7 +554,7 @@ static int kvm_riscv_vcpu_get_reg_isa_ext(struct kvm_vcpu *vcpu,
reg_val = ~reg_val;
break;
default:
- rc = -EINVAL;
+ rc = -ENOENT;
}
if (rc)
return rc;
@@ -592,7 +592,7 @@ static int kvm_riscv_vcpu_set_reg_isa_ext(struct kvm_vcpu *vcpu,
case KVM_REG_RISCV_SBI_MULTI_DIS:
return riscv_vcpu_set_isa_ext_multi(vcpu, reg_num, reg_val, false);
default:
- return -EINVAL;
+ return -ENOENT;
}
return 0;
@@ -627,7 +627,7 @@ int kvm_riscv_vcpu_set_reg(struct kvm_vcpu *vcpu,
break;
}
- return -EINVAL;
+ return -ENOENT;
}
int kvm_riscv_vcpu_get_reg(struct kvm_vcpu *vcpu,
@@ -659,5 +659,5 @@ int kvm_riscv_vcpu_get_reg(struct kvm_vcpu *vcpu,
break;
}
- return -EINVAL;
+ return -ENOENT;
}
diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
index 7b46e04fb667..9cd97091c723 100644
--- a/arch/riscv/kvm/vcpu_sbi.c
+++ b/arch/riscv/kvm/vcpu_sbi.c
@@ -140,8 +140,10 @@ static int riscv_vcpu_set_sbi_ext_single(struct kvm_vcpu *vcpu,
const struct kvm_riscv_sbi_extension_entry *sext = NULL;
struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context;
- if (reg_num >= KVM_RISCV_SBI_EXT_MAX ||
- (reg_val != 1 && reg_val != 0))
+ if (reg_num >= KVM_RISCV_SBI_EXT_MAX)
+ return -ENOENT;
+
+ if (reg_val != 1 && reg_val != 0)
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(sbi_ext); i++) {
@@ -175,7 +177,7 @@ static int riscv_vcpu_get_sbi_ext_single(struct kvm_vcpu *vcpu,
struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context;
if (reg_num >= KVM_RISCV_SBI_EXT_MAX)
- return -EINVAL;
+ return -ENOENT;
for (i = 0; i < ARRAY_SIZE(sbi_ext); i++) {
if (sbi_ext[i].ext_idx == reg_num) {
@@ -206,7 +208,7 @@ static int riscv_vcpu_set_sbi_ext_multi(struct kvm_vcpu *vcpu,
unsigned long i, ext_id;
if (reg_num > KVM_REG_RISCV_SBI_MULTI_REG_LAST)
- return -EINVAL;
+ return -ENOENT;
for_each_set_bit(i, ®_val, BITS_PER_LONG) {
ext_id = i + reg_num * BITS_PER_LONG;
@@ -226,7 +228,7 @@ static int riscv_vcpu_get_sbi_ext_multi(struct kvm_vcpu *vcpu,
unsigned long i, ext_id, ext_val;
if (reg_num > KVM_REG_RISCV_SBI_MULTI_REG_LAST)
- return -EINVAL;
+ return -ENOENT;
for (i = 0; i < BITS_PER_LONG; i++) {
ext_id = i + reg_num * BITS_PER_LONG;
@@ -272,7 +274,7 @@ int kvm_riscv_vcpu_set_reg_sbi_ext(struct kvm_vcpu *vcpu,
case KVM_REG_RISCV_SBI_MULTI_DIS:
return riscv_vcpu_set_sbi_ext_multi(vcpu, reg_num, reg_val, false);
default:
- return -EINVAL;
+ return -ENOENT;
}
return 0;
@@ -307,7 +309,7 @@ int kvm_riscv_vcpu_get_reg_sbi_ext(struct kvm_vcpu *vcpu,
reg_val = ~reg_val;
break;
default:
- rc = -EINVAL;
+ rc = -ENOENT;
}
if (rc)
return rc;
diff --git a/arch/riscv/kvm/vcpu_timer.c b/arch/riscv/kvm/vcpu_timer.c
index 3ac2ff6a65da..527d269cafff 100644
--- a/arch/riscv/kvm/vcpu_timer.c
+++ b/arch/riscv/kvm/vcpu_timer.c
@@ -170,7 +170,7 @@ int kvm_riscv_vcpu_get_reg_timer(struct kvm_vcpu *vcpu,
if (KVM_REG_SIZE(reg->id) != sizeof(u64))
return -EINVAL;
if (reg_num >= sizeof(struct kvm_riscv_timer) / sizeof(u64))
- return -EINVAL;
+ return -ENOENT;
switch (reg_num) {
case KVM_REG_RISCV_TIMER_REG(frequency):
@@ -187,7 +187,7 @@ int kvm_riscv_vcpu_get_reg_timer(struct kvm_vcpu *vcpu,
KVM_RISCV_TIMER_STATE_OFF;
break;
default:
- return -EINVAL;
+ return -ENOENT;
}
if (copy_to_user(uaddr, ®_val, KVM_REG_SIZE(reg->id)))
@@ -211,7 +211,7 @@ int kvm_riscv_vcpu_set_reg_timer(struct kvm_vcpu *vcpu,
if (KVM_REG_SIZE(reg->id) != sizeof(u64))
return -EINVAL;
if (reg_num >= sizeof(struct kvm_riscv_timer) / sizeof(u64))
- return -EINVAL;
+ return -ENOENT;
if (copy_from_user(®_val, uaddr, KVM_REG_SIZE(reg->id)))
return -EFAULT;
@@ -233,7 +233,7 @@ int kvm_riscv_vcpu_set_reg_timer(struct kvm_vcpu *vcpu,
ret = kvm_riscv_vcpu_timer_cancel(t);
break;
default:
- ret = -EINVAL;
+ ret = -ENOENT;
break;
}
--
2.41.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 02/10] RISC-V: KVM: use ENOENT in *_one_reg() when extension is unavailable
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 01/10] RISC-V: KVM: return ENOENT in *_one_reg() when reg is unknown Daniel Henrique Barboza
@ 2023-08-03 16:32 ` Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 03/10] RISC-V: KVM: do not EOPNOTSUPP in set_one_reg() zicbo(m|z) Daniel Henrique Barboza
` (9 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-08-03 16:32 UTC (permalink / raw)
To: kvm-riscv
Following a similar logic as the previous patch let's minimize the EINVAL
usage in *_one_reg() APIs by using ENOENT when an extension that
implements the reg is not available.
For consistency we're also replacing an EOPNOTSUPP instance that should
be an ENOENT since it's an "extension is not available" error.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
arch/riscv/kvm/vcpu_onereg.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 456e9f31441a..1ffd8ac3800a 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -135,12 +135,12 @@ static int kvm_riscv_vcpu_get_reg_config(struct kvm_vcpu *vcpu,
break;
case KVM_REG_RISCV_CONFIG_REG(zicbom_block_size):
if (!riscv_isa_extension_available(vcpu->arch.isa, ZICBOM))
- return -EINVAL;
+ return -ENOENT;
reg_val = riscv_cbom_block_size;
break;
case KVM_REG_RISCV_CONFIG_REG(zicboz_block_size):
if (!riscv_isa_extension_available(vcpu->arch.isa, ZICBOZ))
- return -EINVAL;
+ return -ENOENT;
reg_val = riscv_cboz_block_size;
break;
case KVM_REG_RISCV_CONFIG_REG(mvendorid):
@@ -459,7 +459,7 @@ static int riscv_vcpu_set_isa_ext_single(struct kvm_vcpu *vcpu,
host_isa_ext = kvm_isa_ext_arr[reg_num];
if (!__riscv_isa_extension_available(NULL, host_isa_ext))
- return -EOPNOTSUPP;
+ return -ENOENT;
if (!vcpu->arch.ran_atleast_once) {
/*
--
2.41.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 03/10] RISC-V: KVM: do not EOPNOTSUPP in set_one_reg() zicbo(m|z)
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 01/10] RISC-V: KVM: return ENOENT in *_one_reg() when reg is unknown Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 02/10] RISC-V: KVM: use ENOENT in *_one_reg() when extension is unavailable Daniel Henrique Barboza
@ 2023-08-03 16:32 ` Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 04/10] RISC-V: KVM: do not EOPNOTSUPP in set KVM_REG_RISCV_TIMER_REG Daniel Henrique Barboza
` (8 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-08-03 16:32 UTC (permalink / raw)
To: kvm-riscv
zicbom_block_size and zicboz_block_size have a peculiar API: they can be
read via get_one_reg() but any write will return a EOPNOTSUPP.
It makes sense to return a 'not supported' error since both values can't
be changed, but as far as userspace goes they're regs that are throwing
the same EOPNOTSUPP error even if they were read beforehand via
get_one_reg(), even if the same read value is being written back.
EOPNOTSUPP is also returned even if ZICBOM/ZICBOZ aren't enabled in the
host.
Change both to work more like their counterparts in get_one_reg() and
return -ENOENT if their respective extensions aren't available. After
that, check if the userspace is written a valid value (i.e. the host
value). Throw an -EINVAL if that's not case, let it slide otherwise.
This allows both regs to be read/written by userspace in a 'lazy'
manner, as long as the userspace doesn't change the reg vals.
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
arch/riscv/kvm/vcpu_onereg.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 1ffd8ac3800a..e06256dd8d24 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -216,9 +216,17 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
}
break;
case KVM_REG_RISCV_CONFIG_REG(zicbom_block_size):
- return -EOPNOTSUPP;
+ if (!riscv_isa_extension_available(vcpu->arch.isa, ZICBOM))
+ return -ENOENT;
+ if (reg_val != riscv_cbom_block_size)
+ return -EINVAL;
+ break;
case KVM_REG_RISCV_CONFIG_REG(zicboz_block_size):
- return -EOPNOTSUPP;
+ if (!riscv_isa_extension_available(vcpu->arch.isa, ZICBOZ))
+ return -ENOENT;
+ if (reg_val != riscv_cboz_block_size)
+ return -EINVAL;
+ break;
case KVM_REG_RISCV_CONFIG_REG(mvendorid):
if (!vcpu->arch.ran_atleast_once)
vcpu->arch.mvendorid = reg_val;
--
2.41.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 04/10] RISC-V: KVM: do not EOPNOTSUPP in set KVM_REG_RISCV_TIMER_REG
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
` (2 preceding siblings ...)
2023-08-03 16:32 ` [PATCH v4 03/10] RISC-V: KVM: do not EOPNOTSUPP in set_one_reg() zicbo(m|z) Daniel Henrique Barboza
@ 2023-08-03 16:32 ` Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 05/10] RISC-V: KVM: use EBUSY when !vcpu->arch.ran_atleast_once Daniel Henrique Barboza
` (7 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-08-03 16:32 UTC (permalink / raw)
To: kvm-riscv
The KVM_REG_RISCV_TIMER_REG can be read via get_one_reg(). But trying to
write anything in this reg via set_one_reg() results in an EOPNOTSUPP.
Change the API to behave like cbom_block_size: instead of always
erroring out with EOPNOTSUPP, allow userspace to write the same value
(riscv_timebase) back, throwing an EINVAL if a different value is
attempted.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
arch/riscv/kvm/vcpu_timer.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/kvm/vcpu_timer.c b/arch/riscv/kvm/vcpu_timer.c
index 527d269cafff..75486b25ac45 100644
--- a/arch/riscv/kvm/vcpu_timer.c
+++ b/arch/riscv/kvm/vcpu_timer.c
@@ -218,7 +218,8 @@ int kvm_riscv_vcpu_set_reg_timer(struct kvm_vcpu *vcpu,
switch (reg_num) {
case KVM_REG_RISCV_TIMER_REG(frequency):
- ret = -EOPNOTSUPP;
+ if (reg_val != riscv_timebase)
+ return -EINVAL;
break;
case KVM_REG_RISCV_TIMER_REG(time):
gt->time_delta = reg_val - get_cycles64();
--
2.41.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 05/10] RISC-V: KVM: use EBUSY when !vcpu->arch.ran_atleast_once
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
` (3 preceding siblings ...)
2023-08-03 16:32 ` [PATCH v4 04/10] RISC-V: KVM: do not EOPNOTSUPP in set KVM_REG_RISCV_TIMER_REG Daniel Henrique Barboza
@ 2023-08-03 16:32 ` Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 06/10] RISC-V: KVM: avoid EBUSY when writing same ISA val Daniel Henrique Barboza
` (6 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-08-03 16:32 UTC (permalink / raw)
To: kvm-riscv
vcpu_set_reg_config() and vcpu_set_reg_isa_ext() is throwing an
EOPNOTSUPP error when !vcpu->arch.ran_atleast_once. In similar cases
we're throwing an EBUSY error, like in mvendorid/marchid/mimpid
set_reg().
EOPNOTSUPP has a conotation of finality. EBUSY is more adequate in this
case since its a condition/error related to the vcpu lifecycle.
Change these EOPNOTSUPP instances to EBUSY.
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
arch/riscv/kvm/vcpu_onereg.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index e06256dd8d24..971a2eb83180 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -212,7 +212,7 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
vcpu->arch.isa[0] = reg_val;
kvm_riscv_vcpu_fp_reset(vcpu);
} else {
- return -EOPNOTSUPP;
+ return -EBUSY;
}
break;
case KVM_REG_RISCV_CONFIG_REG(zicbom_block_size):
@@ -484,7 +484,7 @@ static int riscv_vcpu_set_isa_ext_single(struct kvm_vcpu *vcpu,
return -EINVAL;
kvm_riscv_vcpu_fp_reset(vcpu);
} else {
- return -EOPNOTSUPP;
+ return -EBUSY;
}
return 0;
--
2.41.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 06/10] RISC-V: KVM: avoid EBUSY when writing same ISA val
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
` (4 preceding siblings ...)
2023-08-03 16:32 ` [PATCH v4 05/10] RISC-V: KVM: use EBUSY when !vcpu->arch.ran_atleast_once Daniel Henrique Barboza
@ 2023-08-03 16:32 ` Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 07/10] RISC-V: KVM: avoid EBUSY when writing the same machine ID val Daniel Henrique Barboza
` (5 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-08-03 16:32 UTC (permalink / raw)
To: kvm-riscv
kvm_riscv_vcpu_set_reg_config() will return -EBUSY if the ISA config reg
is being written after the VCPU ran at least once.
The same restriction isn't placed in kvm_riscv_vcpu_get_reg_config(), so
there's a chance that we'll -EBUSY out on an ISA config reg write even
if the userspace intended no changes to it.
We'll allow the same form of 'lazy writing' that registers such as
zicbom/zicboz_block_size supports: avoid erroring out if userspace made
no changes to the ISA config reg.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
arch/riscv/kvm/vcpu_onereg.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 971a2eb83180..a0b0364b038f 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -190,6 +190,13 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
if (fls(reg_val) >= RISCV_ISA_EXT_BASE)
return -EINVAL;
+ /*
+ * Return early (i.e. do nothing) if reg_val is the same
+ * value retrievable via kvm_riscv_vcpu_get_reg_config().
+ */
+ if (reg_val == (vcpu->arch.isa[0] & KVM_RISCV_BASE_ISA_MASK))
+ break;
+
if (!vcpu->arch.ran_atleast_once) {
/* Ignore the enable/disable request for certain extensions */
for (i = 0; i < RISCV_ISA_EXT_BASE; i++) {
--
2.41.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 07/10] RISC-V: KVM: avoid EBUSY when writing the same machine ID val
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
` (5 preceding siblings ...)
2023-08-03 16:32 ` [PATCH v4 06/10] RISC-V: KVM: avoid EBUSY when writing same ISA val Daniel Henrique Barboza
@ 2023-08-03 16:32 ` Daniel Henrique Barboza
2023-08-03 16:33 ` [PATCH v4 08/10] RISC-V: KVM: avoid EBUSY when writing the same isa_ext val Daniel Henrique Barboza
` (4 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-08-03 16:32 UTC (permalink / raw)
To: kvm-riscv
Right now we do not allow any write in mvendorid/marchid/mimpid if the
vcpu already started, preventing these regs to be changed.
However, if userspace doesn't change them, an alternative is to consider
the reg write a no-op and avoid erroring out altogether. Userpace can
then be oblivious about KVM internals if no changes were intended in the
first place.
Allow the same form of 'lazy writing' that registers such as
zicbom/zicboz_block_size supports: avoid erroring out if userspace makes
no changes in mvendorid/marchid/mimpid during reg write.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
arch/riscv/kvm/vcpu_onereg.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index a0b0364b038f..81cb6b2784db 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -235,18 +235,24 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
return -EINVAL;
break;
case KVM_REG_RISCV_CONFIG_REG(mvendorid):
+ if (reg_val == vcpu->arch.mvendorid)
+ break;
if (!vcpu->arch.ran_atleast_once)
vcpu->arch.mvendorid = reg_val;
else
return -EBUSY;
break;
case KVM_REG_RISCV_CONFIG_REG(marchid):
+ if (reg_val == vcpu->arch.marchid)
+ break;
if (!vcpu->arch.ran_atleast_once)
vcpu->arch.marchid = reg_val;
else
return -EBUSY;
break;
case KVM_REG_RISCV_CONFIG_REG(mimpid):
+ if (reg_val == vcpu->arch.mimpid)
+ break;
if (!vcpu->arch.ran_atleast_once)
vcpu->arch.mimpid = reg_val;
else
--
2.41.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 08/10] RISC-V: KVM: avoid EBUSY when writing the same isa_ext val
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
` (6 preceding siblings ...)
2023-08-03 16:32 ` [PATCH v4 07/10] RISC-V: KVM: avoid EBUSY when writing the same machine ID val Daniel Henrique Barboza
@ 2023-08-03 16:33 ` Daniel Henrique Barboza
2023-08-03 16:33 ` [PATCH v4 09/10] RISC-V: KVM: Improve vector save/restore errors Daniel Henrique Barboza
` (3 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-08-03 16:33 UTC (permalink / raw)
To: kvm-riscv
riscv_vcpu_set_isa_ext_single() will prevent any write of isa_ext regs
if the vcpu already started spinning.
But if there's no extension state (enabled/disabled) made by the
userspace, there's no need to -EBUSY out - we can treat the operation as
a no-op.
zicbom/zicboz_block_size, ISA config reg and mvendorid/march/mimpid
already works in a more permissive manner w.r.t userspace writes being a
no-op, so let's do the same with isa_ext writes.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
arch/riscv/kvm/vcpu_onereg.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 81cb6b2784db..989ea32dbcbe 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -482,6 +482,9 @@ static int riscv_vcpu_set_isa_ext_single(struct kvm_vcpu *vcpu,
if (!__riscv_isa_extension_available(NULL, host_isa_ext))
return -ENOENT;
+ if (reg_val == test_bit(host_isa_ext, vcpu->arch.isa))
+ return 0;
+
if (!vcpu->arch.ran_atleast_once) {
/*
* All multi-letter extension and a few single letter
--
2.41.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 09/10] RISC-V: KVM: Improve vector save/restore errors
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
` (7 preceding siblings ...)
2023-08-03 16:33 ` [PATCH v4 08/10] RISC-V: KVM: avoid EBUSY when writing the same isa_ext val Daniel Henrique Barboza
@ 2023-08-03 16:33 ` Daniel Henrique Barboza
2023-08-03 17:05 ` Andrew Jones
2023-08-03 16:33 ` [PATCH v4 10/10] docs: kvm: riscv: document EBUSY in KVM_SET_ONE_REG Daniel Henrique Barboza
` (2 subsequent siblings)
11 siblings, 1 reply; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-08-03 16:33 UTC (permalink / raw)
To: kvm-riscv
From: Andrew Jones <ajones@ventanamicro.com>
kvm_riscv_vcpu_(get/set)_reg_vector() now returns ENOENT if V is not
available, EINVAL if reg type is not of VECTOR type, and any error that
might be thrown by kvm_riscv_vcpu_vreg_addr().
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
arch/riscv/kvm/vcpu_vector.c | 60 ++++++++++++++++++++----------------
1 file changed, 33 insertions(+), 27 deletions(-)
diff --git a/arch/riscv/kvm/vcpu_vector.c b/arch/riscv/kvm/vcpu_vector.c
index edd2eecbddc2..39c5bceb4d1b 100644
--- a/arch/riscv/kvm/vcpu_vector.c
+++ b/arch/riscv/kvm/vcpu_vector.c
@@ -91,44 +91,44 @@ void kvm_riscv_vcpu_free_vector_context(struct kvm_vcpu *vcpu)
}
#endif
-static void *kvm_riscv_vcpu_vreg_addr(struct kvm_vcpu *vcpu,
+static int kvm_riscv_vcpu_vreg_addr(struct kvm_vcpu *vcpu,
unsigned long reg_num,
- size_t reg_size)
+ size_t reg_size,
+ void **reg_val)
{
struct kvm_cpu_context *cntx = &vcpu->arch.guest_context;
- void *reg_val;
size_t vlenb = riscv_v_vsize / 32;
if (reg_num < KVM_REG_RISCV_VECTOR_REG(0)) {
if (reg_size != sizeof(unsigned long))
- return NULL;
+ return -EINVAL;
switch (reg_num) {
case KVM_REG_RISCV_VECTOR_CSR_REG(vstart):
- reg_val = &cntx->vector.vstart;
+ *reg_val = &cntx->vector.vstart;
break;
case KVM_REG_RISCV_VECTOR_CSR_REG(vl):
- reg_val = &cntx->vector.vl;
+ *reg_val = &cntx->vector.vl;
break;
case KVM_REG_RISCV_VECTOR_CSR_REG(vtype):
- reg_val = &cntx->vector.vtype;
+ *reg_val = &cntx->vector.vtype;
break;
case KVM_REG_RISCV_VECTOR_CSR_REG(vcsr):
- reg_val = &cntx->vector.vcsr;
+ *reg_val = &cntx->vector.vcsr;
break;
case KVM_REG_RISCV_VECTOR_CSR_REG(datap):
default:
- return NULL;
+ return -ENOENT;
}
} else if (reg_num <= KVM_REG_RISCV_VECTOR_REG(31)) {
if (reg_size != vlenb)
- return NULL;
- reg_val = cntx->vector.datap
+ return -EINVAL;
+ *reg_val = cntx->vector.datap
+ (reg_num - KVM_REG_RISCV_VECTOR_REG(0)) * vlenb;
} else {
- return NULL;
+ return -ENOENT;
}
- return reg_val;
+ return 0;
}
int kvm_riscv_vcpu_get_reg_vector(struct kvm_vcpu *vcpu,
@@ -141,17 +141,20 @@ int kvm_riscv_vcpu_get_reg_vector(struct kvm_vcpu *vcpu,
unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
KVM_REG_SIZE_MASK |
rtype);
- void *reg_val = NULL;
size_t reg_size = KVM_REG_SIZE(reg->id);
+ void *reg_val;
+ int rc;
- if (rtype == KVM_REG_RISCV_VECTOR &&
- riscv_isa_extension_available(isa, v)) {
- reg_val = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size);
- }
-
- if (!reg_val)
+ if (rtype != KVM_REG_RISCV_VECTOR)
return -EINVAL;
+ if (!riscv_isa_extension_available(isa, v))
+ return -ENOENT;
+
+ rc = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size, ®_val);
+ if (rc)
+ return rc;
+
if (copy_to_user(uaddr, reg_val, reg_size))
return -EFAULT;
@@ -168,17 +171,20 @@ int kvm_riscv_vcpu_set_reg_vector(struct kvm_vcpu *vcpu,
unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
KVM_REG_SIZE_MASK |
rtype);
- void *reg_val = NULL;
size_t reg_size = KVM_REG_SIZE(reg->id);
+ void *reg_val;
+ int rc;
- if (rtype == KVM_REG_RISCV_VECTOR &&
- riscv_isa_extension_available(isa, v)) {
- reg_val = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size);
- }
-
- if (!reg_val)
+ if (rtype != KVM_REG_RISCV_VECTOR)
return -EINVAL;
+ if (!riscv_isa_extension_available(isa, v))
+ return -ENOENT;
+
+ rc = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size, ®_val);
+ if (rc)
+ return rc;
+
if (copy_from_user(reg_val, uaddr, reg_size))
return -EFAULT;
--
2.41.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 10/10] docs: kvm: riscv: document EBUSY in KVM_SET_ONE_REG
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
` (8 preceding siblings ...)
2023-08-03 16:33 ` [PATCH v4 09/10] RISC-V: KVM: Improve vector save/restore errors Daniel Henrique Barboza
@ 2023-08-03 16:33 ` Daniel Henrique Barboza
2023-08-03 16:56 ` [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Andrew Jones
2023-08-04 9:11 ` Anup Patel
11 siblings, 0 replies; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-08-03 16:33 UTC (permalink / raw)
To: kvm-riscv
The EBUSY errno is being used for KVM_SET_ONE_REG as a way to tell
userspace that a given reg can't be changed after the vcpu started.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
Documentation/virt/kvm/api.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index c0ddd3035462..3249fb56cc69 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -2259,6 +2259,8 @@ Errors:
EINVAL invalid register ID, or no such register or used with VMs in
protected virtualization mode on s390
EPERM (arm64) register access not allowed before vcpu finalization
+ EBUSY (riscv) changing register value not allowed after the vcpu
+ has run at least once
====== ============================================================
(These error codes are indicative only: do not rely on a specific error
--
2.41.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
` (9 preceding siblings ...)
2023-08-03 16:33 ` [PATCH v4 10/10] docs: kvm: riscv: document EBUSY in KVM_SET_ONE_REG Daniel Henrique Barboza
@ 2023-08-03 16:56 ` Andrew Jones
2023-08-04 9:11 ` Anup Patel
11 siblings, 0 replies; 16+ messages in thread
From: Andrew Jones @ 2023-08-03 16:56 UTC (permalink / raw)
To: kvm-riscv
On Thu, Aug 03, 2023 at 01:32:52PM -0300, Daniel Henrique Barboza wrote:
> Hi,
>
> This version includes a diff that Andrew mentioned in v2 [1] that I
> missed. They were squashed into patch 1.
>
> No other changes made. Patches rebased on top of riscv_kvm_queue.
>
> Changes from v3:
> - patch 1:
> - added missing EINVAL - ENOENT conversions
> - v3 link: https://lore.kernel.org/kvm/20230803140022.399333-1-dbarboza at ventanamicro.com/
>
> [1] https://lore.kernel.org/kvm/20230801222629.210929-1-dbarboza at ventanamicro.com/
>
>
For the series,
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 09/10] RISC-V: KVM: Improve vector save/restore errors
2023-08-03 16:33 ` [PATCH v4 09/10] RISC-V: KVM: Improve vector save/restore errors Daniel Henrique Barboza
@ 2023-08-03 17:05 ` Andrew Jones
2023-08-03 17:16 ` Andrew Jones
0 siblings, 1 reply; 16+ messages in thread
From: Andrew Jones @ 2023-08-03 17:05 UTC (permalink / raw)
To: kvm-riscv
On Thu, Aug 03, 2023 at 01:33:01PM -0300, Daniel Henrique Barboza wrote:
> From: Andrew Jones <ajones@ventanamicro.com>
>
> kvm_riscv_vcpu_(get/set)_reg_vector() now returns ENOENT if V is not
> available, EINVAL if reg type is not of VECTOR type, and any error that
> might be thrown by kvm_riscv_vcpu_vreg_addr().
>
> Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
> ---
> arch/riscv/kvm/vcpu_vector.c | 60 ++++++++++++++++++++----------------
> 1 file changed, 33 insertions(+), 27 deletions(-)
>
> diff --git a/arch/riscv/kvm/vcpu_vector.c b/arch/riscv/kvm/vcpu_vector.c
> index edd2eecbddc2..39c5bceb4d1b 100644
> --- a/arch/riscv/kvm/vcpu_vector.c
> +++ b/arch/riscv/kvm/vcpu_vector.c
> @@ -91,44 +91,44 @@ void kvm_riscv_vcpu_free_vector_context(struct kvm_vcpu *vcpu)
> }
> #endif
>
> -static void *kvm_riscv_vcpu_vreg_addr(struct kvm_vcpu *vcpu,
> +static int kvm_riscv_vcpu_vreg_addr(struct kvm_vcpu *vcpu,
> unsigned long reg_num,
> - size_t reg_size)
> + size_t reg_size,
> + void **reg_val)
> {
> struct kvm_cpu_context *cntx = &vcpu->arch.guest_context;
> - void *reg_val;
> size_t vlenb = riscv_v_vsize / 32;
>
> if (reg_num < KVM_REG_RISCV_VECTOR_REG(0)) {
> if (reg_size != sizeof(unsigned long))
> - return NULL;
> + return -EINVAL;
> switch (reg_num) {
> case KVM_REG_RISCV_VECTOR_CSR_REG(vstart):
> - reg_val = &cntx->vector.vstart;
> + *reg_val = &cntx->vector.vstart;
> break;
> case KVM_REG_RISCV_VECTOR_CSR_REG(vl):
> - reg_val = &cntx->vector.vl;
> + *reg_val = &cntx->vector.vl;
> break;
> case KVM_REG_RISCV_VECTOR_CSR_REG(vtype):
> - reg_val = &cntx->vector.vtype;
> + *reg_val = &cntx->vector.vtype;
> break;
> case KVM_REG_RISCV_VECTOR_CSR_REG(vcsr):
> - reg_val = &cntx->vector.vcsr;
> + *reg_val = &cntx->vector.vcsr;
> break;
> case KVM_REG_RISCV_VECTOR_CSR_REG(datap):
> default:
> - return NULL;
> + return -ENOENT;
> }
> } else if (reg_num <= KVM_REG_RISCV_VECTOR_REG(31)) {
> if (reg_size != vlenb)
> - return NULL;
> - reg_val = cntx->vector.datap
> + return -EINVAL;
> + *reg_val = cntx->vector.datap
> + (reg_num - KVM_REG_RISCV_VECTOR_REG(0)) * vlenb;
> } else {
> - return NULL;
> + return -ENOENT;
> }
>
> - return reg_val;
> + return 0;
> }
>
> int kvm_riscv_vcpu_get_reg_vector(struct kvm_vcpu *vcpu,
> @@ -141,17 +141,20 @@ int kvm_riscv_vcpu_get_reg_vector(struct kvm_vcpu *vcpu,
> unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
> KVM_REG_SIZE_MASK |
> rtype);
> - void *reg_val = NULL;
> size_t reg_size = KVM_REG_SIZE(reg->id);
> + void *reg_val;
> + int rc;
>
> - if (rtype == KVM_REG_RISCV_VECTOR &&
> - riscv_isa_extension_available(isa, v)) {
> - reg_val = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size);
> - }
> -
> - if (!reg_val)
> + if (rtype != KVM_REG_RISCV_VECTOR)
> return -EINVAL;
>
> + if (!riscv_isa_extension_available(isa, v))
> + return -ENOENT;
> +
> + rc = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size, ®_val);
> + if (rc)
> + return rc;
> +
> if (copy_to_user(uaddr, reg_val, reg_size))
> return -EFAULT;
>
> @@ -168,17 +171,20 @@ int kvm_riscv_vcpu_set_reg_vector(struct kvm_vcpu *vcpu,
> unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
> KVM_REG_SIZE_MASK |
> rtype);
> - void *reg_val = NULL;
> size_t reg_size = KVM_REG_SIZE(reg->id);
> + void *reg_val;
> + int rc;
>
> - if (rtype == KVM_REG_RISCV_VECTOR &&
> - riscv_isa_extension_available(isa, v)) {
> - reg_val = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size);
> - }
> -
> - if (!reg_val)
> + if (rtype != KVM_REG_RISCV_VECTOR)
> return -EINVAL;
>
> + if (!riscv_isa_extension_available(isa, v))
> + return -ENOENT;
> +
> + rc = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size, ®_val);
> + if (rc)
> + return rc;
> +
> if (copy_from_user(reg_val, uaddr, reg_size))
> return -EFAULT;
Ugh, this is totally wrong. We no longer set the register. I need to
rework this rework...
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 09/10] RISC-V: KVM: Improve vector save/restore errors
2023-08-03 17:05 ` Andrew Jones
@ 2023-08-03 17:16 ` Andrew Jones
0 siblings, 0 replies; 16+ messages in thread
From: Andrew Jones @ 2023-08-03 17:16 UTC (permalink / raw)
To: kvm-riscv
On Thu, Aug 03, 2023 at 08:05:47PM +0300, Andrew Jones wrote:
> On Thu, Aug 03, 2023 at 01:33:01PM -0300, Daniel Henrique Barboza wrote:
> > From: Andrew Jones <ajones@ventanamicro.com>
> >
> > kvm_riscv_vcpu_(get/set)_reg_vector() now returns ENOENT if V is not
> > available, EINVAL if reg type is not of VECTOR type, and any error that
> > might be thrown by kvm_riscv_vcpu_vreg_addr().
> >
> > Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
> > ---
> > arch/riscv/kvm/vcpu_vector.c | 60 ++++++++++++++++++++----------------
> > 1 file changed, 33 insertions(+), 27 deletions(-)
> >
> > diff --git a/arch/riscv/kvm/vcpu_vector.c b/arch/riscv/kvm/vcpu_vector.c
> > index edd2eecbddc2..39c5bceb4d1b 100644
> > --- a/arch/riscv/kvm/vcpu_vector.c
> > +++ b/arch/riscv/kvm/vcpu_vector.c
> > @@ -91,44 +91,44 @@ void kvm_riscv_vcpu_free_vector_context(struct kvm_vcpu *vcpu)
> > }
> > #endif
> >
> > -static void *kvm_riscv_vcpu_vreg_addr(struct kvm_vcpu *vcpu,
> > +static int kvm_riscv_vcpu_vreg_addr(struct kvm_vcpu *vcpu,
> > unsigned long reg_num,
> > - size_t reg_size)
> > + size_t reg_size,
> > + void **reg_val)
> > {
> > struct kvm_cpu_context *cntx = &vcpu->arch.guest_context;
> > - void *reg_val;
> > size_t vlenb = riscv_v_vsize / 32;
> >
> > if (reg_num < KVM_REG_RISCV_VECTOR_REG(0)) {
> > if (reg_size != sizeof(unsigned long))
> > - return NULL;
> > + return -EINVAL;
> > switch (reg_num) {
> > case KVM_REG_RISCV_VECTOR_CSR_REG(vstart):
> > - reg_val = &cntx->vector.vstart;
> > + *reg_val = &cntx->vector.vstart;
> > break;
> > case KVM_REG_RISCV_VECTOR_CSR_REG(vl):
> > - reg_val = &cntx->vector.vl;
> > + *reg_val = &cntx->vector.vl;
> > break;
> > case KVM_REG_RISCV_VECTOR_CSR_REG(vtype):
> > - reg_val = &cntx->vector.vtype;
> > + *reg_val = &cntx->vector.vtype;
> > break;
> > case KVM_REG_RISCV_VECTOR_CSR_REG(vcsr):
> > - reg_val = &cntx->vector.vcsr;
> > + *reg_val = &cntx->vector.vcsr;
> > break;
> > case KVM_REG_RISCV_VECTOR_CSR_REG(datap):
> > default:
> > - return NULL;
> > + return -ENOENT;
> > }
> > } else if (reg_num <= KVM_REG_RISCV_VECTOR_REG(31)) {
> > if (reg_size != vlenb)
> > - return NULL;
> > - reg_val = cntx->vector.datap
> > + return -EINVAL;
> > + *reg_val = cntx->vector.datap
> > + (reg_num - KVM_REG_RISCV_VECTOR_REG(0)) * vlenb;
> > } else {
> > - return NULL;
> > + return -ENOENT;
> > }
> >
> > - return reg_val;
> > + return 0;
> > }
> >
> > int kvm_riscv_vcpu_get_reg_vector(struct kvm_vcpu *vcpu,
> > @@ -141,17 +141,20 @@ int kvm_riscv_vcpu_get_reg_vector(struct kvm_vcpu *vcpu,
> > unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
> > KVM_REG_SIZE_MASK |
> > rtype);
> > - void *reg_val = NULL;
> > size_t reg_size = KVM_REG_SIZE(reg->id);
> > + void *reg_val;
> > + int rc;
> >
> > - if (rtype == KVM_REG_RISCV_VECTOR &&
> > - riscv_isa_extension_available(isa, v)) {
> > - reg_val = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size);
> > - }
> > -
> > - if (!reg_val)
> > + if (rtype != KVM_REG_RISCV_VECTOR)
> > return -EINVAL;
> >
> > + if (!riscv_isa_extension_available(isa, v))
> > + return -ENOENT;
> > +
> > + rc = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size, ®_val);
> > + if (rc)
> > + return rc;
> > +
> > if (copy_to_user(uaddr, reg_val, reg_size))
> > return -EFAULT;
> >
> > @@ -168,17 +171,20 @@ int kvm_riscv_vcpu_set_reg_vector(struct kvm_vcpu *vcpu,
> > unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
> > KVM_REG_SIZE_MASK |
> > rtype);
> > - void *reg_val = NULL;
> > size_t reg_size = KVM_REG_SIZE(reg->id);
> > + void *reg_val;
> > + int rc;
> >
> > - if (rtype == KVM_REG_RISCV_VECTOR &&
> > - riscv_isa_extension_available(isa, v)) {
> > - reg_val = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size);
> > - }
> > -
> > - if (!reg_val)
> > + if (rtype != KVM_REG_RISCV_VECTOR)
> > return -EINVAL;
> >
> > + if (!riscv_isa_extension_available(isa, v))
> > + return -ENOENT;
> > +
> > + rc = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size, ®_val);
> > + if (rc)
> > + return rc;
> > +
> > if (copy_from_user(reg_val, uaddr, reg_size))
> > return -EFAULT;
>
> Ugh, this is totally wrong. We no longer set the register. I need to
> rework this rework...
Oh, never mind. Skimming over (my own patch) I forgot we were fetching the
address not the value. I should have renamed 'reg_val' to 'reg_addr'.
There's another change that can be made, which is to drop rtype and its
check from these functions and just use KVM_REG_RISCV_VECTOR directly in
the mask. I'll send a cleanup patch with that and the rename, but that's
separate from this series.
Thanks,
drew
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
` (10 preceding siblings ...)
2023-08-03 16:56 ` [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Andrew Jones
@ 2023-08-04 9:11 ` Anup Patel
2023-08-05 16:32 ` Anup Patel
11 siblings, 1 reply; 16+ messages in thread
From: Anup Patel @ 2023-08-04 9:11 UTC (permalink / raw)
To: kvm-riscv
On Thu, Aug 3, 2023 at 10:03?PM Daniel Henrique Barboza
<dbarboza@ventanamicro.com> wrote:
>
> Hi,
>
> This version includes a diff that Andrew mentioned in v2 [1] that I
> missed. They were squashed into patch 1.
>
> No other changes made. Patches rebased on top of riscv_kvm_queue.
>
> Changes from v3:
> - patch 1:
> - added missing EINVAL - ENOENT conversions
> - v3 link: https://lore.kernel.org/kvm/20230803140022.399333-1-dbarboza at ventanamicro.com/
>
> [1] https://lore.kernel.org/kvm/20230801222629.210929-1-dbarboza at ventanamicro.com/
>
>
> Andrew Jones (1):
> RISC-V: KVM: Improve vector save/restore errors
>
> Daniel Henrique Barboza (9):
> RISC-V: KVM: return ENOENT in *_one_reg() when reg is unknown
> RISC-V: KVM: use ENOENT in *_one_reg() when extension is unavailable
> RISC-V: KVM: do not EOPNOTSUPP in set_one_reg() zicbo(m|z)
> RISC-V: KVM: do not EOPNOTSUPP in set KVM_REG_RISCV_TIMER_REG
> RISC-V: KVM: use EBUSY when !vcpu->arch.ran_atleast_once
> RISC-V: KVM: avoid EBUSY when writing same ISA val
> RISC-V: KVM: avoid EBUSY when writing the same machine ID val
> RISC-V: KVM: avoid EBUSY when writing the same isa_ext val
> docs: kvm: riscv: document EBUSY in KVM_SET_ONE_REG
I have queued all patches except PATCH9 for Linux-6.6.
Drew, please send v5 of PATCH.
Thanks,
Anup
>
> Documentation/virt/kvm/api.rst | 2 +
> arch/riscv/kvm/aia.c | 4 +-
> arch/riscv/kvm/vcpu_fp.c | 12 +++---
> arch/riscv/kvm/vcpu_onereg.c | 74 ++++++++++++++++++++++------------
> arch/riscv/kvm/vcpu_sbi.c | 16 ++++----
> arch/riscv/kvm/vcpu_timer.c | 11 ++---
> arch/riscv/kvm/vcpu_vector.c | 60 ++++++++++++++-------------
> 7 files changed, 107 insertions(+), 72 deletions(-)
>
> --
> 2.41.0
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code
2023-08-04 9:11 ` Anup Patel
@ 2023-08-05 16:32 ` Anup Patel
0 siblings, 0 replies; 16+ messages in thread
From: Anup Patel @ 2023-08-05 16:32 UTC (permalink / raw)
To: kvm-riscv
On Fri, Aug 4, 2023 at 2:41?PM Anup Patel <anup@brainfault.org> wrote:
>
> On Thu, Aug 3, 2023 at 10:03?PM Daniel Henrique Barboza
> <dbarboza@ventanamicro.com> wrote:
> >
> > Hi,
> >
> > This version includes a diff that Andrew mentioned in v2 [1] that I
> > missed. They were squashed into patch 1.
> >
> > No other changes made. Patches rebased on top of riscv_kvm_queue.
> >
> > Changes from v3:
> > - patch 1:
> > - added missing EINVAL - ENOENT conversions
> > - v3 link: https://lore.kernel.org/kvm/20230803140022.399333-1-dbarboza at ventanamicro.com/
> >
> > [1] https://lore.kernel.org/kvm/20230801222629.210929-1-dbarboza at ventanamicro.com/
> >
> >
> > Andrew Jones (1):
> > RISC-V: KVM: Improve vector save/restore errors
> >
> > Daniel Henrique Barboza (9):
> > RISC-V: KVM: return ENOENT in *_one_reg() when reg is unknown
> > RISC-V: KVM: use ENOENT in *_one_reg() when extension is unavailable
> > RISC-V: KVM: do not EOPNOTSUPP in set_one_reg() zicbo(m|z)
> > RISC-V: KVM: do not EOPNOTSUPP in set KVM_REG_RISCV_TIMER_REG
> > RISC-V: KVM: use EBUSY when !vcpu->arch.ran_atleast_once
> > RISC-V: KVM: avoid EBUSY when writing same ISA val
> > RISC-V: KVM: avoid EBUSY when writing the same machine ID val
> > RISC-V: KVM: avoid EBUSY when writing the same isa_ext val
> > docs: kvm: riscv: document EBUSY in KVM_SET_ONE_REG
>
> I have queued all patches except PATCH9 for Linux-6.6.
>
> Drew, please send v5 of PATCH.
I have queued PATCH9 as well.
Thanks,
Anup
>
> Thanks,
> Anup
>
> >
> > Documentation/virt/kvm/api.rst | 2 +
> > arch/riscv/kvm/aia.c | 4 +-
> > arch/riscv/kvm/vcpu_fp.c | 12 +++---
> > arch/riscv/kvm/vcpu_onereg.c | 74 ++++++++++++++++++++++------------
> > arch/riscv/kvm/vcpu_sbi.c | 16 ++++----
> > arch/riscv/kvm/vcpu_timer.c | 11 ++---
> > arch/riscv/kvm/vcpu_vector.c | 60 ++++++++++++++-------------
> > 7 files changed, 107 insertions(+), 72 deletions(-)
> >
> > --
> > 2.41.0
> >
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2023-08-05 16:32 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-03 16:32 [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 01/10] RISC-V: KVM: return ENOENT in *_one_reg() when reg is unknown Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 02/10] RISC-V: KVM: use ENOENT in *_one_reg() when extension is unavailable Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 03/10] RISC-V: KVM: do not EOPNOTSUPP in set_one_reg() zicbo(m|z) Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 04/10] RISC-V: KVM: do not EOPNOTSUPP in set KVM_REG_RISCV_TIMER_REG Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 05/10] RISC-V: KVM: use EBUSY when !vcpu->arch.ran_atleast_once Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 06/10] RISC-V: KVM: avoid EBUSY when writing same ISA val Daniel Henrique Barboza
2023-08-03 16:32 ` [PATCH v4 07/10] RISC-V: KVM: avoid EBUSY when writing the same machine ID val Daniel Henrique Barboza
2023-08-03 16:33 ` [PATCH v4 08/10] RISC-V: KVM: avoid EBUSY when writing the same isa_ext val Daniel Henrique Barboza
2023-08-03 16:33 ` [PATCH v4 09/10] RISC-V: KVM: Improve vector save/restore errors Daniel Henrique Barboza
2023-08-03 17:05 ` Andrew Jones
2023-08-03 17:16 ` Andrew Jones
2023-08-03 16:33 ` [PATCH v4 10/10] docs: kvm: riscv: document EBUSY in KVM_SET_ONE_REG Daniel Henrique Barboza
2023-08-03 16:56 ` [PATCH v4 00/10] RISC-V: KVM: change get_reg/set_reg error code Andrew Jones
2023-08-04 9:11 ` Anup Patel
2023-08-05 16:32 ` Anup Patel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).