On 4/8/25 16:23, Mohamed Mediouni wrote:
Signed-off-by: Mohamed Mediouni <moha...@unpredictable.fr> --- accel/whpx/whpx-common.c | 1 + meson.build | 21 +- target/arm/meson.build | 1 + target/arm/whpx/meson.build | 3 + target/arm/whpx/whpx-all.c | 845 ++++++++++++++++++++++++++++++++++++ 5 files changed, 864 insertions(+), 7 deletions(-) create mode 100644 target/arm/whpx/meson.build create mode 100644 target/arm/whpx/whpx-all.c
+int whpx_init_vcpu(CPUState *cpu) +{ + HRESULT hr; + struct whpx_state *whpx = &whpx_global; + AccelCPUState *vcpu = NULL; + ARMCPU *arm_cpu = ARM_CPU(cpu); + CPUARMState *env = &arm_cpu->env; + int ret; + + uint32_t sregs_match_len = ARRAY_SIZE(whpx_sreg_match); + uint32_t sregs_cnt = 0; + WHV_REGISTER_VALUE val; + int i; + + vcpu = g_new0(AccelCPUState, 1); + + hr = whp_dispatch.WHvCreateVirtualProcessor( + whpx->partition, cpu->cpu_index, 0); + if (FAILED(hr)) { + error_report("WHPX: Failed to create a virtual processor," + " hr=%08lx", hr); + ret = -EINVAL; + goto error; + } + + /* Assumption that CNTFRQ_EL0 is the same between the VMM and the partition. */ + asm volatile("mrs %0, cntfrq_el0" : "=r"(arm_cpu->gt_cntfrq_hz)); + + cpu->vcpu_dirty = true; + cpu->accel = vcpu; + max_vcpu_index = max(max_vcpu_index, cpu->cpu_index); + qemu_add_vm_change_state_handler(whpx_cpu_update_state, env); + + env->aarch64 = true; + + /* Allocate enough space for our sysreg sync */ + arm_cpu->cpreg_indexes = g_renew(uint64_t, arm_cpu->cpreg_indexes, + sregs_match_len); + arm_cpu->cpreg_values = g_renew(uint64_t, arm_cpu->cpreg_values, + sregs_match_len); + arm_cpu->cpreg_vmstate_indexes = g_renew(uint64_t, + arm_cpu->cpreg_vmstate_indexes, + sregs_match_len); + arm_cpu->cpreg_vmstate_values = g_renew(uint64_t, + arm_cpu->cpreg_vmstate_values, + sregs_match_len); + + memset(arm_cpu->cpreg_values, 0, sregs_match_len * sizeof(uint64_t)); + + /* Populate cp list for all known sysregs */ + for (i = 0; i < sregs_match_len; i++) { + const ARMCPRegInfo *ri; + uint32_t key = whpx_sreg_match[i].key; + + ri = get_arm_cp_reginfo(arm_cpu->cp_regs, key); + if (ri) { + assert(!(ri->type & ARM_CP_NO_RAW)); + whpx_sreg_match[i].cp_idx = sregs_cnt; + arm_cpu->cpreg_indexes[sregs_cnt++] = cpreg_to_kvm_id(key); + } else { + whpx_sreg_match[i].cp_idx = -1; + } + } + arm_cpu->cpreg_array_len = sregs_cnt; + arm_cpu->cpreg_vmstate_array_len = sregs_cnt; + + assert(write_cpustate_to_list(arm_cpu, false)); + + /* Set CP_NO_RAW system registers on init */ + val.Reg64 = arm_cpu->midr; + whpx_set_reg(cpu, WHvArm64RegisterMidrEl1, + val); + + clean_whv_register_value(&val); + + /* bit 31 of MPIDR_EL1 is RES1, and this is enforced by WHPX */ + val.Reg64 = 0x80000000 + arm_cpu->mp_affinity;
Preferably: val.Reg64 = deposit64(arm_cpu->mp_affinity, 31, 1, 1 /* RES1 */);
+ whpx_set_reg(cpu, WHvArm64RegisterMpidrEl1, + val);
(note, your indentation is often off)
+ + return 0; + +error: + g_free(vcpu); + + return ret; + +}