Skip to content

Commit 2a88f38

Browse files
danielhbavpatel
authored andcommitted
RISC-V: KVM: return ENOENT in *_one_reg() when reg is unknown
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> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Signed-off-by: Anup Patel <anup@brainfault.org>
1 parent 2776421 commit 2a88f38

5 files changed

Lines changed: 39 additions & 37 deletions

File tree

arch/riscv/kvm/aia.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ int kvm_riscv_vcpu_aia_get_csr(struct kvm_vcpu *vcpu,
176176
struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr;
177177

178178
if (reg_num >= sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long))
179-
return -EINVAL;
179+
return -ENOENT;
180180

181181
*out_val = 0;
182182
if (kvm_riscv_aia_available())
@@ -192,7 +192,7 @@ int kvm_riscv_vcpu_aia_set_csr(struct kvm_vcpu *vcpu,
192192
struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr;
193193

194194
if (reg_num >= sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long))
195-
return -EINVAL;
195+
return -ENOENT;
196196

197197
if (kvm_riscv_aia_available()) {
198198
((unsigned long *)csr)[reg_num] = val;

arch/riscv/kvm/vcpu_fp.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ int kvm_riscv_vcpu_get_reg_fp(struct kvm_vcpu *vcpu,
9696
reg_num <= KVM_REG_RISCV_FP_F_REG(f[31]))
9797
reg_val = &cntx->fp.f.f[reg_num];
9898
else
99-
return -EINVAL;
99+
return -ENOENT;
100100
} else if ((rtype == KVM_REG_RISCV_FP_D) &&
101101
riscv_isa_extension_available(vcpu->arch.isa, d)) {
102102
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,
109109
return -EINVAL;
110110
reg_val = &cntx->fp.d.f[reg_num];
111111
} else
112-
return -EINVAL;
112+
return -ENOENT;
113113
} else
114-
return -EINVAL;
114+
return -ENOENT;
115115

116116
if (copy_to_user(uaddr, reg_val, KVM_REG_SIZE(reg->id)))
117117
return -EFAULT;
@@ -141,7 +141,7 @@ int kvm_riscv_vcpu_set_reg_fp(struct kvm_vcpu *vcpu,
141141
reg_num <= KVM_REG_RISCV_FP_F_REG(f[31]))
142142
reg_val = &cntx->fp.f.f[reg_num];
143143
else
144-
return -EINVAL;
144+
return -ENOENT;
145145
} else if ((rtype == KVM_REG_RISCV_FP_D) &&
146146
riscv_isa_extension_available(vcpu->arch.isa, d)) {
147147
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,
154154
return -EINVAL;
155155
reg_val = &cntx->fp.d.f[reg_num];
156156
} else
157-
return -EINVAL;
157+
return -ENOENT;
158158
} else
159-
return -EINVAL;
159+
return -ENOENT;
160160

161161
if (copy_from_user(reg_val, uaddr, KVM_REG_SIZE(reg->id)))
162162
return -EFAULT;

arch/riscv/kvm/vcpu_onereg.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ static int kvm_riscv_vcpu_get_reg_config(struct kvm_vcpu *vcpu,
156156
reg_val = satp_mode >> SATP_MODE_SHIFT;
157157
break;
158158
default:
159-
return -EINVAL;
159+
return -ENOENT;
160160
}
161161

162162
if (copy_to_user(uaddr, &reg_val, KVM_REG_SIZE(reg->id)))
@@ -242,7 +242,7 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
242242
return -EINVAL;
243243
break;
244244
default:
245-
return -EINVAL;
245+
return -ENOENT;
246246
}
247247

248248
return 0;
@@ -262,7 +262,7 @@ static int kvm_riscv_vcpu_get_reg_core(struct kvm_vcpu *vcpu,
262262
if (KVM_REG_SIZE(reg->id) != sizeof(unsigned long))
263263
return -EINVAL;
264264
if (reg_num >= sizeof(struct kvm_riscv_core) / sizeof(unsigned long))
265-
return -EINVAL;
265+
return -ENOENT;
266266

267267
if (reg_num == KVM_REG_RISCV_CORE_REG(regs.pc))
268268
reg_val = cntx->sepc;
@@ -273,7 +273,7 @@ static int kvm_riscv_vcpu_get_reg_core(struct kvm_vcpu *vcpu,
273273
reg_val = (cntx->sstatus & SR_SPP) ?
274274
KVM_RISCV_MODE_S : KVM_RISCV_MODE_U;
275275
else
276-
return -EINVAL;
276+
return -ENOENT;
277277

278278
if (copy_to_user(uaddr, &reg_val, KVM_REG_SIZE(reg->id)))
279279
return -EFAULT;
@@ -295,7 +295,7 @@ static int kvm_riscv_vcpu_set_reg_core(struct kvm_vcpu *vcpu,
295295
if (KVM_REG_SIZE(reg->id) != sizeof(unsigned long))
296296
return -EINVAL;
297297
if (reg_num >= sizeof(struct kvm_riscv_core) / sizeof(unsigned long))
298-
return -EINVAL;
298+
return -ENOENT;
299299

300300
if (copy_from_user(&reg_val, uaddr, KVM_REG_SIZE(reg->id)))
301301
return -EFAULT;
@@ -311,7 +311,7 @@ static int kvm_riscv_vcpu_set_reg_core(struct kvm_vcpu *vcpu,
311311
else
312312
cntx->sstatus &= ~SR_SPP;
313313
} else
314-
return -EINVAL;
314+
return -ENOENT;
315315

316316
return 0;
317317
}
@@ -323,7 +323,7 @@ static int kvm_riscv_vcpu_general_get_csr(struct kvm_vcpu *vcpu,
323323
struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr;
324324

325325
if (reg_num >= sizeof(struct kvm_riscv_csr) / sizeof(unsigned long))
326-
return -EINVAL;
326+
return -ENOENT;
327327

328328
if (reg_num == KVM_REG_RISCV_CSR_REG(sip)) {
329329
kvm_riscv_vcpu_flush_interrupts(vcpu);
@@ -342,7 +342,7 @@ static int kvm_riscv_vcpu_general_set_csr(struct kvm_vcpu *vcpu,
342342
struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr;
343343

344344
if (reg_num >= sizeof(struct kvm_riscv_csr) / sizeof(unsigned long))
345-
return -EINVAL;
345+
return -ENOENT;
346346

347347
if (reg_num == KVM_REG_RISCV_CSR_REG(sip)) {
348348
reg_val &= VSIP_VALID_MASK;
@@ -381,7 +381,7 @@ static int kvm_riscv_vcpu_get_reg_csr(struct kvm_vcpu *vcpu,
381381
rc = kvm_riscv_vcpu_aia_get_csr(vcpu, reg_num, &reg_val);
382382
break;
383383
default:
384-
rc = -EINVAL;
384+
rc = -ENOENT;
385385
break;
386386
}
387387
if (rc)
@@ -420,7 +420,7 @@ static int kvm_riscv_vcpu_set_reg_csr(struct kvm_vcpu *vcpu,
420420
rc = kvm_riscv_vcpu_aia_set_csr(vcpu, reg_num, reg_val);
421421
break;
422422
default:
423-
rc = -EINVAL;
423+
rc = -ENOENT;
424424
break;
425425
}
426426
if (rc)
@@ -437,7 +437,7 @@ static int riscv_vcpu_get_isa_ext_single(struct kvm_vcpu *vcpu,
437437

438438
if (reg_num >= KVM_RISCV_ISA_EXT_MAX ||
439439
reg_num >= ARRAY_SIZE(kvm_isa_ext_arr))
440-
return -EINVAL;
440+
return -ENOENT;
441441

442442
*reg_val = 0;
443443
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,
455455

456456
if (reg_num >= KVM_RISCV_ISA_EXT_MAX ||
457457
reg_num >= ARRAY_SIZE(kvm_isa_ext_arr))
458-
return -EINVAL;
458+
return -ENOENT;
459459

460460
host_isa_ext = kvm_isa_ext_arr[reg_num];
461461
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,
489489
unsigned long i, ext_id, ext_val;
490490

491491
if (reg_num > KVM_REG_RISCV_ISA_MULTI_REG_LAST)
492-
return -EINVAL;
492+
return -ENOENT;
493493

494494
for (i = 0; i < BITS_PER_LONG; i++) {
495495
ext_id = i + reg_num * BITS_PER_LONG;
@@ -512,7 +512,7 @@ static int riscv_vcpu_set_isa_ext_multi(struct kvm_vcpu *vcpu,
512512
unsigned long i, ext_id;
513513

514514
if (reg_num > KVM_REG_RISCV_ISA_MULTI_REG_LAST)
515-
return -EINVAL;
515+
return -ENOENT;
516516

517517
for_each_set_bit(i, &reg_val, BITS_PER_LONG) {
518518
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,
554554
reg_val = ~reg_val;
555555
break;
556556
default:
557-
rc = -EINVAL;
557+
rc = -ENOENT;
558558
}
559559
if (rc)
560560
return rc;
@@ -592,7 +592,7 @@ static int kvm_riscv_vcpu_set_reg_isa_ext(struct kvm_vcpu *vcpu,
592592
case KVM_REG_RISCV_SBI_MULTI_DIS:
593593
return riscv_vcpu_set_isa_ext_multi(vcpu, reg_num, reg_val, false);
594594
default:
595-
return -EINVAL;
595+
return -ENOENT;
596596
}
597597

598598
return 0;
@@ -627,7 +627,7 @@ int kvm_riscv_vcpu_set_reg(struct kvm_vcpu *vcpu,
627627
break;
628628
}
629629

630-
return -EINVAL;
630+
return -ENOENT;
631631
}
632632

633633
int kvm_riscv_vcpu_get_reg(struct kvm_vcpu *vcpu,
@@ -659,5 +659,5 @@ int kvm_riscv_vcpu_get_reg(struct kvm_vcpu *vcpu,
659659
break;
660660
}
661661

662-
return -EINVAL;
662+
return -ENOENT;
663663
}

arch/riscv/kvm/vcpu_sbi.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,10 @@ static int riscv_vcpu_set_sbi_ext_single(struct kvm_vcpu *vcpu,
140140
const struct kvm_riscv_sbi_extension_entry *sext = NULL;
141141
struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context;
142142

143-
if (reg_num >= KVM_RISCV_SBI_EXT_MAX ||
144-
(reg_val != 1 && reg_val != 0))
143+
if (reg_num >= KVM_RISCV_SBI_EXT_MAX)
144+
return -ENOENT;
145+
146+
if (reg_val != 1 && reg_val != 0)
145147
return -EINVAL;
146148

147149
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,
175177
struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context;
176178

177179
if (reg_num >= KVM_RISCV_SBI_EXT_MAX)
178-
return -EINVAL;
180+
return -ENOENT;
179181

180182
for (i = 0; i < ARRAY_SIZE(sbi_ext); i++) {
181183
if (sbi_ext[i].ext_idx == reg_num) {
@@ -206,7 +208,7 @@ static int riscv_vcpu_set_sbi_ext_multi(struct kvm_vcpu *vcpu,
206208
unsigned long i, ext_id;
207209

208210
if (reg_num > KVM_REG_RISCV_SBI_MULTI_REG_LAST)
209-
return -EINVAL;
211+
return -ENOENT;
210212

211213
for_each_set_bit(i, &reg_val, BITS_PER_LONG) {
212214
ext_id = i + reg_num * BITS_PER_LONG;
@@ -226,7 +228,7 @@ static int riscv_vcpu_get_sbi_ext_multi(struct kvm_vcpu *vcpu,
226228
unsigned long i, ext_id, ext_val;
227229

228230
if (reg_num > KVM_REG_RISCV_SBI_MULTI_REG_LAST)
229-
return -EINVAL;
231+
return -ENOENT;
230232

231233
for (i = 0; i < BITS_PER_LONG; i++) {
232234
ext_id = i + reg_num * BITS_PER_LONG;
@@ -272,7 +274,7 @@ int kvm_riscv_vcpu_set_reg_sbi_ext(struct kvm_vcpu *vcpu,
272274
case KVM_REG_RISCV_SBI_MULTI_DIS:
273275
return riscv_vcpu_set_sbi_ext_multi(vcpu, reg_num, reg_val, false);
274276
default:
275-
return -EINVAL;
277+
return -ENOENT;
276278
}
277279

278280
return 0;
@@ -307,7 +309,7 @@ int kvm_riscv_vcpu_get_reg_sbi_ext(struct kvm_vcpu *vcpu,
307309
reg_val = ~reg_val;
308310
break;
309311
default:
310-
rc = -EINVAL;
312+
rc = -ENOENT;
311313
}
312314
if (rc)
313315
return rc;

arch/riscv/kvm/vcpu_timer.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ int kvm_riscv_vcpu_get_reg_timer(struct kvm_vcpu *vcpu,
170170
if (KVM_REG_SIZE(reg->id) != sizeof(u64))
171171
return -EINVAL;
172172
if (reg_num >= sizeof(struct kvm_riscv_timer) / sizeof(u64))
173-
return -EINVAL;
173+
return -ENOENT;
174174

175175
switch (reg_num) {
176176
case KVM_REG_RISCV_TIMER_REG(frequency):
@@ -187,7 +187,7 @@ int kvm_riscv_vcpu_get_reg_timer(struct kvm_vcpu *vcpu,
187187
KVM_RISCV_TIMER_STATE_OFF;
188188
break;
189189
default:
190-
return -EINVAL;
190+
return -ENOENT;
191191
}
192192

193193
if (copy_to_user(uaddr, &reg_val, KVM_REG_SIZE(reg->id)))
@@ -211,7 +211,7 @@ int kvm_riscv_vcpu_set_reg_timer(struct kvm_vcpu *vcpu,
211211
if (KVM_REG_SIZE(reg->id) != sizeof(u64))
212212
return -EINVAL;
213213
if (reg_num >= sizeof(struct kvm_riscv_timer) / sizeof(u64))
214-
return -EINVAL;
214+
return -ENOENT;
215215

216216
if (copy_from_user(&reg_val, uaddr, KVM_REG_SIZE(reg->id)))
217217
return -EFAULT;
@@ -233,7 +233,7 @@ int kvm_riscv_vcpu_set_reg_timer(struct kvm_vcpu *vcpu,
233233
ret = kvm_riscv_vcpu_timer_cancel(t);
234234
break;
235235
default:
236-
ret = -EINVAL;
236+
ret = -ENOENT;
237237
break;
238238
}
239239

0 commit comments

Comments
 (0)