xics maintains an array of ICPState structures which is indexed by cpu_index. Change this to index the ICPState array by migration_id for pseries-2.7 onwards. This allows migration of guest to suceed when there are holes in cpu_index range due to CPU hot removal.
NOTE: In rtas_set_xive() and h_ipi(), cpu_dt_id is implicitly assume to be equivalent to migration_id. Signed-off-by: Bharata B Rao <bhar...@linux.vnet.ibm.com> --- hw/intc/xics.c | 12 ++++++++---- hw/intc/xics_kvm.c | 11 +++++------ hw/intc/xics_spapr.c | 28 +++++++++++++++++++++------- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index cd48f42..ce7571e 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -50,9 +50,11 @@ int xics_get_cpu_index_by_dt_id(int cpu_dt_id) void xics_cpu_destroy(XICSState *xics, PowerPCCPU *cpu) { CPUState *cs = CPU(cpu); - ICPState *ss = &xics->ss[cs->cpu_index]; + CPUClass *cc = CPU_GET_CLASS(cs); + int server = cc->get_migration_id(cs); + ICPState *ss = &xics->ss[server]; - assert(cs->cpu_index < xics->nr_servers); + assert(server < xics->nr_servers); assert(cs == ss->cs); ss->output = NULL; @@ -63,10 +65,12 @@ void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; - ICPState *ss = &xics->ss[cs->cpu_index]; + CPUClass *cc = CPU_GET_CLASS(cs); + int server = cc->get_migration_id(cs); + ICPState *ss = &xics->ss[server]; XICSStateClass *info = XICS_COMMON_GET_CLASS(xics); - assert(cs->cpu_index < xics->nr_servers); + assert(server < xics->nr_servers); ss->cs = cs; diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index edbd62f..2c087a4 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -326,14 +326,13 @@ static const TypeInfo ics_kvm_info = { */ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu) { - CPUState *cs; - ICPState *ss; + CPUState *cs = CPU(cpu); KVMXICSState *xicskvm = XICS_SPAPR_KVM(xics); + CPUClass *cc = CPU_GET_CLASS(cs); + int server = cc->get_migration_id(cs); + ICPState *ss = ss = &xics->ss[server]; - cs = CPU(cpu); - ss = &xics->ss[cs->cpu_index]; - - assert(cs->cpu_index < xics->nr_servers); + assert(server < xics->nr_servers); if (xicskvm->kernel_xics_fd == -1) { abort(); } diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 618826d..281ba76 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -43,16 +43,20 @@ static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); + CPUClass *cc = CPU_GET_CLASS(cs); + int server = cc->get_migration_id(cs); target_ulong cppr = args[0]; - icp_set_cppr(spapr->xics, cs->cpu_index, cppr); + icp_set_cppr(spapr->xics, server, cppr); return H_SUCCESS; } static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { - target_ulong server = xics_get_cpu_index_by_dt_id(args[0]); + CPUState *cs = CPU(cpu); + target_ulong server = cs->use_migration_id ? args[0] : + xics_get_cpu_index_by_dt_id(args[0]); target_ulong mfrr = args[1]; if (server >= spapr->xics->nr_servers) { @@ -67,7 +71,9 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); - uint32_t xirr = icp_accept(spapr->xics->ss + cs->cpu_index); + CPUClass *cc = CPU_GET_CLASS(cs); + int server = cc->get_migration_id(cs); + uint32_t xirr = icp_accept(spapr->xics->ss + server); args[0] = xirr; return H_SUCCESS; @@ -77,7 +83,9 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); - ICPState *ss = &spapr->xics->ss[cs->cpu_index]; + CPUClass *cc = CPU_GET_CLASS(cs); + int server = cc->get_migration_id(cs); + ICPState *ss = &spapr->xics->ss[server]; uint32_t xirr = icp_accept(ss); args[0] = xirr; @@ -89,9 +97,11 @@ static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); + CPUClass *cc = CPU_GET_CLASS(cs); + int server = cc->get_migration_id(cs); target_ulong xirr = args[0]; - icp_eoi(spapr->xics, cs->cpu_index, xirr); + icp_eoi(spapr->xics, server, xirr); return H_SUCCESS; } @@ -99,8 +109,10 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); + CPUClass *cc = CPU_GET_CLASS(cs); + int server = cc->get_migration_id(cs); uint32_t mfrr; - uint32_t xirr = icp_ipoll(spapr->xics->ss + cs->cpu_index, &mfrr); + uint32_t xirr = icp_ipoll(spapr->xics->ss + server, &mfrr); args[0] = xirr; args[1] = mfrr; @@ -113,6 +125,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { + CPUState *cs = CPU(cpu); ICSState *ics = spapr->xics->ics; uint32_t nr, server, priority; @@ -122,7 +135,8 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, } nr = rtas_ld(args, 0); - server = xics_get_cpu_index_by_dt_id(rtas_ld(args, 1)); + server = cs->use_migration_id ? rtas_ld(args, 1) : + xics_get_cpu_index_by_dt_id(rtas_ld(args, 1)); priority = rtas_ld(args, 2); if (!ics_valid_irq(ics, nr) || (server >= ics->xics->nr_servers) -- 2.7.4