Skip to content

Commit 179af57

Browse files
xen0nchenhuacai
authored andcommitted
LoongArch: KVM: Fix input validation of _kvm_get_cpucfg() & kvm_check_cpucfg()
The range check for the CPUCFG ID is wrong (should have been a || instead of &&) and useless in effect, so fix the obvious mistake. Furthermore, the juggling of the temp return value is unnecessary, because it is semantically equivalent and more readable to just return at every switch case's end. This is done too to avoid potential bugs in the future related to the unwanted complexity. Also, the return value of _kvm_get_cpucfg is meant to be checked, but this was not done, so bad CPUCFG IDs wrongly fall back to the default case and 0 is incorrectly returned; check the return value to fix the UAPI behavior. While at it, also remove the redundant range check in kvm_check_cpucfg, because out-of-range CPUCFG IDs are already rejected by the -EINVAL as returned by _kvm_get_cpucfg(). Fixes: db1ecca ("LoongArch: KVM: Add LSX (128bit SIMD) support") Fixes: 118e10c ("LoongArch: KVM: Add LASX (256bit SIMD) support") Reviewed-by: Bibo Mao <maobibo@loongson.cn> Signed-off-by: WANG Xuerui <git@xen0n.name> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent f661ca4 commit 179af57

File tree

1 file changed

+18
-17
lines changed

1 file changed

+18
-17
lines changed

arch/loongarch/kvm/vcpu.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,7 @@ static int _kvm_setcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 val)
300300

301301
static int _kvm_get_cpucfg(int id, u64 *v)
302302
{
303-
int ret = 0;
304-
305-
if (id < 0 && id >= KVM_MAX_CPUCFG_REGS)
303+
if (id < 0 || id >= KVM_MAX_CPUCFG_REGS)
306304
return -EINVAL;
307305

308306
switch (id) {
@@ -324,32 +322,35 @@ static int _kvm_get_cpucfg(int id, u64 *v)
324322
if (cpu_has_lasx)
325323
*v |= CPUCFG2_LASX;
326324

327-
break;
325+
return 0;
328326
default:
329-
ret = -EINVAL;
330-
break;
327+
/*
328+
* No restrictions on other valid CPUCFG IDs' values, but
329+
* CPUCFG data is limited to 32 bits as the LoongArch ISA
330+
* manual says (Volume 1, Section 2.2.10.5 "CPUCFG").
331+
*/
332+
*v = U32_MAX;
333+
return 0;
331334
}
332-
return ret;
333335
}
334336

335337
static int kvm_check_cpucfg(int id, u64 val)
336338
{
337-
u64 mask;
338-
int ret = 0;
339-
340-
if (id < 0 && id >= KVM_MAX_CPUCFG_REGS)
341-
return -EINVAL;
339+
int ret;
340+
u64 mask = 0;
342341

343-
if (_kvm_get_cpucfg(id, &mask))
342+
ret = _kvm_get_cpucfg(id, &mask);
343+
if (ret)
344344
return ret;
345345

346+
if (val & ~mask)
347+
/* Unsupported features and/or the higher 32 bits should not be set */
348+
return -EINVAL;
349+
346350
switch (id) {
347351
case 2:
348352
/* CPUCFG2 features checking */
349-
if (val & ~mask)
350-
/* The unsupported features should not be set */
351-
ret = -EINVAL;
352-
else if (!(val & CPUCFG2_LLFTP))
353+
if (!(val & CPUCFG2_LLFTP))
353354
/* The LLFTP must be set, as guest must has a constant timer */
354355
ret = -EINVAL;
355356
else if ((val & CPUCFG2_FP) && (!(val & CPUCFG2_FPSP) || !(val & CPUCFG2_FPDP)))

0 commit comments

Comments
 (0)