target-arm: Use the kernel's idea of MPIDR if we're using KVM

When we're using KVM, the kernel's internal idea of the MPIDR
affinity fields must match the values we tell it for the guest
vcpu cluster configuration in the device tree. Since at the moment
the kernel doesn't support letting userspace tell it the correct
affinity fields to use, we must read the kernel's view and
reflect that back in the device tree.

Backports commit eb5e1d3c85dffe677da2550d211f9304a7d5ba3b from qemu
This commit is contained in:
Pavel Fedin 2018-02-13 14:31:09 -05:00 committed by Lioncash
parent 614ecb2bf2
commit caed2f123d
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7
3 changed files with 16 additions and 6 deletions

View File

@ -159,6 +159,7 @@ typedef struct ARMCPU {
uint64_t id_aa64mmfr1;
uint32_t dbgdidr;
uint32_t clidr;
uint64_t mp_affinity; /* MP ID without feature bits */
/* The elements of this array are the CCSIDR values for each cache,
* in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.
*/

View File

@ -325,16 +325,28 @@ static inline void unset_feature(CPUARMState *env, int feature)
env->features &= ~(1ULL << feature);
}
#define ARM_CPUS_PER_CLUSTER 8
static void arm_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)
{
CPUState *cs = CPU(obj);
ARMCPU *cpu = ARM_CPU(uc, obj);
uint32_t Aff1, Aff0;
cs->env_ptr = &cpu->env;
cpu_exec_init(&cpu->env, opaque);
cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
g_free, g_free);
/* This cpu-id-to-MPIDR affinity is used only for TCG; KVM will override it.
* We don't support setting cluster ID ([16..23]) (known as Aff2
* in later ARM ARM versions), or any of the higher affinity level fields,
* so these bits always RAZ.
*/
Aff1 = cs->cpu_index / ARM_CPUS_PER_CLUSTER;
Aff0 = cs->cpu_index % ARM_CPUS_PER_CLUSTER;
cpu->mp_affinity = (Aff1 << 8) | Aff0;
#if 0
#ifndef CONFIG_USER_ONLY
/* Our inbound IRQ and FIQ lines */

View File

@ -1783,12 +1783,9 @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = {
static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
CPUState *cs = CPU(arm_env_get_cpu(env));
uint32_t mpidr = cs->cpu_index;
/* We don't support setting cluster ID ([8..11]) (known as Aff1
* in later ARM ARM versions), or any of the higher affinity level fields,
* so these bits always RAZ.
*/
ARMCPU *cpu = ARM_CPU(env->uc, arm_env_get_cpu(env));
uint64_t mpidr = cpu->mp_affinity;
if (arm_feature(env, ARM_FEATURE_V7MP)) {
mpidr |= (1U << 31);
/* Cores which are uniprocessor (non-coherent)