Skip to content

Commit 1deaf75

Browse files
jones-drewavpatel
authored andcommitted
RISC-V: KVM: Improve vector save/restore errors
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 <[email protected]> Signed-off-by: Anup Patel <[email protected]>
1 parent 1099c80 commit 1deaf75

File tree

1 file changed

+33
-27
lines changed

1 file changed

+33
-27
lines changed

arch/riscv/kvm/vcpu_vector.c

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -91,44 +91,44 @@ void kvm_riscv_vcpu_free_vector_context(struct kvm_vcpu *vcpu)
9191
}
9292
#endif
9393

94-
static void *kvm_riscv_vcpu_vreg_addr(struct kvm_vcpu *vcpu,
94+
static int kvm_riscv_vcpu_vreg_addr(struct kvm_vcpu *vcpu,
9595
unsigned long reg_num,
96-
size_t reg_size)
96+
size_t reg_size,
97+
void **reg_val)
9798
{
9899
struct kvm_cpu_context *cntx = &vcpu->arch.guest_context;
99-
void *reg_val;
100100
size_t vlenb = riscv_v_vsize / 32;
101101

102102
if (reg_num < KVM_REG_RISCV_VECTOR_REG(0)) {
103103
if (reg_size != sizeof(unsigned long))
104-
return NULL;
104+
return -EINVAL;
105105
switch (reg_num) {
106106
case KVM_REG_RISCV_VECTOR_CSR_REG(vstart):
107-
reg_val = &cntx->vector.vstart;
107+
*reg_val = &cntx->vector.vstart;
108108
break;
109109
case KVM_REG_RISCV_VECTOR_CSR_REG(vl):
110-
reg_val = &cntx->vector.vl;
110+
*reg_val = &cntx->vector.vl;
111111
break;
112112
case KVM_REG_RISCV_VECTOR_CSR_REG(vtype):
113-
reg_val = &cntx->vector.vtype;
113+
*reg_val = &cntx->vector.vtype;
114114
break;
115115
case KVM_REG_RISCV_VECTOR_CSR_REG(vcsr):
116-
reg_val = &cntx->vector.vcsr;
116+
*reg_val = &cntx->vector.vcsr;
117117
break;
118118
case KVM_REG_RISCV_VECTOR_CSR_REG(datap):
119119
default:
120-
return NULL;
120+
return -ENOENT;
121121
}
122122
} else if (reg_num <= KVM_REG_RISCV_VECTOR_REG(31)) {
123123
if (reg_size != vlenb)
124-
return NULL;
125-
reg_val = cntx->vector.datap
124+
return -EINVAL;
125+
*reg_val = cntx->vector.datap
126126
+ (reg_num - KVM_REG_RISCV_VECTOR_REG(0)) * vlenb;
127127
} else {
128-
return NULL;
128+
return -ENOENT;
129129
}
130130

131-
return reg_val;
131+
return 0;
132132
}
133133

134134
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,
141141
unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
142142
KVM_REG_SIZE_MASK |
143143
rtype);
144-
void *reg_val = NULL;
145144
size_t reg_size = KVM_REG_SIZE(reg->id);
145+
void *reg_val;
146+
int rc;
146147

147-
if (rtype == KVM_REG_RISCV_VECTOR &&
148-
riscv_isa_extension_available(isa, v)) {
149-
reg_val = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size);
150-
}
151-
152-
if (!reg_val)
148+
if (rtype != KVM_REG_RISCV_VECTOR)
153149
return -EINVAL;
154150

151+
if (!riscv_isa_extension_available(isa, v))
152+
return -ENOENT;
153+
154+
rc = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size, &reg_val);
155+
if (rc)
156+
return rc;
157+
155158
if (copy_to_user(uaddr, reg_val, reg_size))
156159
return -EFAULT;
157160

@@ -168,17 +171,20 @@ int kvm_riscv_vcpu_set_reg_vector(struct kvm_vcpu *vcpu,
168171
unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
169172
KVM_REG_SIZE_MASK |
170173
rtype);
171-
void *reg_val = NULL;
172174
size_t reg_size = KVM_REG_SIZE(reg->id);
175+
void *reg_val;
176+
int rc;
173177

174-
if (rtype == KVM_REG_RISCV_VECTOR &&
175-
riscv_isa_extension_available(isa, v)) {
176-
reg_val = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size);
177-
}
178-
179-
if (!reg_val)
178+
if (rtype != KVM_REG_RISCV_VECTOR)
180179
return -EINVAL;
181180

181+
if (!riscv_isa_extension_available(isa, v))
182+
return -ENOENT;
183+
184+
rc = kvm_riscv_vcpu_vreg_addr(vcpu, reg_num, reg_size, &reg_val);
185+
if (rc)
186+
return rc;
187+
182188
if (copy_from_user(reg_val, uaddr, reg_size))
183189
return -EFAULT;
184190

0 commit comments

Comments
 (0)