diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 57d6e12744c5a9a424644510cbed490b422fb06d..44a326fddc5bd5d0fd261b68faa26dd5484a646e 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -1205,6 +1205,8 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_SEV_ES_GHCB 500 #define KVM_CAP_HYGON_COCO_EXT 501 + +#define KVM_CAP_ARM_IPIV_MODE 503 /* support userspace to request firmware to build CSV3 guest's memory space */ #define KVM_CAP_HYGON_COCO_EXT_CSV3_SET_PRIV_MEM (1 << 0) /* support request to update CSV3 guest's memory region multiple times */ diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 09d391bd348aaf9c7e59a58d35487a1e68b540e6..b0f70de01888e4b94a01299560b6eb2adf71faa3 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1324,9 +1324,25 @@ static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags) uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz) { - uint32_t Aff1 = idx / clustersz; - uint32_t Aff0 = idx % clustersz; - return (Aff1 << ARM_AFF1_SHIFT) | Aff0; + uint64_t Aff0 = 0, Aff1 = 0, Aff2 = 0, Aff3 = 0; + int mode; + + if (!kvm_enabled()) { + Aff1 = idx / clustersz; + Aff0 = idx % clustersz; + return (Aff1 << ARM_AFF1_SHIFT) | Aff0; + } + + mode = kvm_check_extension(kvm_state, KVM_CAP_ARM_IPIV_MODE); + if (mode) { + Aff1 = idx % 16; + Aff2 = idx / 16; + } else { + Aff1 = idx / clustersz; + Aff0 = idx % clustersz; + } + return (Aff3 << ARM_AFF3_SHIFT) | (Aff2 << ARM_AFF2_SHIFT) | + (Aff1 << ARM_AFF1_SHIFT) | Aff0; } static void arm_cpu_initfn(Object *obj)