target/arm: Introduce read_sys_reg32 for kvm32

Assert that the value to be written is the correct size.
No change in functionality here, just mirroring the same
function from kvm64.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20181113180154.17903-4-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2018-11-19 15:29:07 +00:00 committed by Peter Maydell
parent 9d60dea960
commit b653c55fa7
1 changed files with 16 additions and 25 deletions

View File

@ -28,6 +28,14 @@ static inline void set_feature(uint64_t *features, int feature)
*features |= 1ULL << feature; *features |= 1ULL << feature;
} }
static int read_sys_reg32(int fd, uint32_t *pret, uint64_t id)
{
struct kvm_one_reg idreg = { .id = id, .addr = (uintptr_t)pret };
assert((id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32);
return ioctl(fd, KVM_GET_ONE_REG, &idreg);
}
bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
{ {
/* Identify the feature bits corresponding to the host CPU, and /* Identify the feature bits corresponding to the host CPU, and
@ -35,9 +43,10 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* we have to create a scratch VM, create a single CPU inside it, * we have to create a scratch VM, create a single CPU inside it,
* and then query that CPU for the relevant ID registers. * and then query that CPU for the relevant ID registers.
*/ */
int i, ret, fdarray[3]; int err = 0, fdarray[3];
uint32_t midr, id_pfr0, mvfr1; uint32_t midr, id_pfr0, mvfr1;
uint64_t features = 0; uint64_t features = 0;
/* Old kernels may not know about the PREFERRED_TARGET ioctl: however /* Old kernels may not know about the PREFERRED_TARGET ioctl: however
* we know these will only support creating one kind of guest CPU, * we know these will only support creating one kind of guest CPU,
* which is its preferred CPU type. * which is its preferred CPU type.
@ -47,23 +56,6 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
QEMU_KVM_ARM_TARGET_NONE QEMU_KVM_ARM_TARGET_NONE
}; };
struct kvm_vcpu_init init; struct kvm_vcpu_init init;
struct kvm_one_reg idregs[] = {
{
.id = KVM_REG_ARM | KVM_REG_SIZE_U32
| ENCODE_CP_REG(15, 0, 0, 0, 0, 0, 0),
.addr = (uintptr_t)&midr,
},
{
.id = KVM_REG_ARM | KVM_REG_SIZE_U32
| ENCODE_CP_REG(15, 0, 0, 0, 1, 0, 0),
.addr = (uintptr_t)&id_pfr0,
},
{
.id = KVM_REG_ARM | KVM_REG_SIZE_U32
| KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR1,
.addr = (uintptr_t)&mvfr1,
},
};
if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) { if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
return false; return false;
@ -77,16 +69,15 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
*/ */
ahcf->dtb_compatible = "arm,arm-v7"; ahcf->dtb_compatible = "arm,arm-v7";
for (i = 0; i < ARRAY_SIZE(idregs); i++) { err |= read_sys_reg32(fdarray[2], &midr, ARM_CP15_REG32(0, 0, 0, 0));
ret = ioctl(fdarray[2], KVM_GET_ONE_REG, &idregs[i]); err |= read_sys_reg32(fdarray[2], &id_pfr0, ARM_CP15_REG32(0, 0, 1, 0));
if (ret) { err |= read_sys_reg32(fdarray[2], &mvfr1,
break; KVM_REG_ARM | KVM_REG_SIZE_U32 |
} KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR1);
}
kvm_arm_destroy_scratch_host_vcpu(fdarray); kvm_arm_destroy_scratch_host_vcpu(fdarray);
if (ret) { if (err < 0) {
return false; return false;
} }