[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 4/5] ppc: spapr: cleanup spapr_exit_nested() with helper routines
From: |
Harsh Prateek Bora |
Subject: |
[PATCH 4/5] ppc: spapr: cleanup spapr_exit_nested() with helper routines. |
Date: |
Fri, 31 Mar 2023 12:23:43 +0530 |
Currently, in spapr_exit_nested(), it does a lot of register state
restoring from ptregs/hvstate after mapping each of those before
restoring the L1 host state. This patch breaks down those set of ops
to respective helper routines for better code readability/maintenance.
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
---
hw/ppc/spapr_hcall.c | 132 +++++++++++++++++++++++++------------------
1 file changed, 78 insertions(+), 54 deletions(-)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index a77b4c9076..ed3a21471d 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1701,36 +1701,23 @@ static target_ulong h_enter_nested(PowerPCCPU *cpu,
return env->gpr[3];
}
-void spapr_exit_nested(PowerPCCPU *cpu, int excp)
+static void restore_hvstate_from_env(struct kvmppc_hv_guest_state *hvstate,
+ CPUPPCState *env, int excp)
{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
- SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
- target_ulong r3_return = env->excp_vectors[excp]; /* hcall return value */
- target_ulong hv_ptr = spapr_cpu->nested_host_state->gpr[4];
- target_ulong regs_ptr = spapr_cpu->nested_host_state->gpr[5];
- struct kvmppc_hv_guest_state *hvstate;
- struct kvmppc_pt_regs *regs;
- hwaddr len;
-
- assert(spapr_cpu->in_nested);
-
- cpu_ppc_hdecr_exit(env);
-
- len = sizeof(*hvstate);
- hvstate = address_space_map(CPU(cpu)->as, hv_ptr, &len, true,
- MEMTXATTRS_UNSPECIFIED);
- if (len != sizeof(*hvstate)) {
- address_space_unmap(CPU(cpu)->as, hvstate, len, 0, true);
- r3_return = H_PARAMETER;
- goto out_restore_l1;
- }
-
- hvstate->cfar = env->cfar;
- hvstate->lpcr = env->spr[SPR_LPCR];
- hvstate->pcr = env->spr[SPR_PCR];
- hvstate->dpdes = env->spr[SPR_DPDES];
- hvstate->hfscr = env->spr[SPR_HFSCR];
+ hvstate->cfar = env->cfar;
+ hvstate->lpcr = env->spr[SPR_LPCR];
+ hvstate->pcr = env->spr[SPR_PCR];
+ hvstate->dpdes = env->spr[SPR_DPDES];
+ hvstate->hfscr = env->spr[SPR_HFSCR];
+ /* HEIR should be implemented for HV mode and saved here. */
+ hvstate->srr0 = env->spr[SPR_SRR0];
+ hvstate->srr1 = env->spr[SPR_SRR1];
+ hvstate->sprg[0] = env->spr[SPR_SPRG0];
+ hvstate->sprg[1] = env->spr[SPR_SPRG1];
+ hvstate->sprg[2] = env->spr[SPR_SPRG2];
+ hvstate->sprg[3] = env->spr[SPR_SPRG3];
+ hvstate->pidr = env->spr[SPR_BOOKS_PID];
+ hvstate->ppr = env->spr[SPR_PPR];
if (excp == POWERPC_EXCP_HDSI) {
hvstate->hdar = env->spr[SPR_HDAR];
@@ -1739,38 +1726,36 @@ void spapr_exit_nested(PowerPCCPU *cpu, int excp)
} else if (excp == POWERPC_EXCP_HISI) {
hvstate->asdr = env->spr[SPR_ASDR];
}
+}
- /* HEIR should be implemented for HV mode and saved here. */
- hvstate->srr0 = env->spr[SPR_SRR0];
- hvstate->srr1 = env->spr[SPR_SRR1];
- hvstate->sprg[0] = env->spr[SPR_SPRG0];
- hvstate->sprg[1] = env->spr[SPR_SPRG1];
- hvstate->sprg[2] = env->spr[SPR_SPRG2];
- hvstate->sprg[3] = env->spr[SPR_SPRG3];
- hvstate->pidr = env->spr[SPR_BOOKS_PID];
- hvstate->ppr = env->spr[SPR_PPR];
-
- /* Is it okay to specify write length larger than actual data written? */
- address_space_unmap(CPU(cpu)->as, hvstate, len, len, true);
+static int map_and_restore_hvstate(PowerPCCPU *cpu, int excp, target_ulong *r3)
+{
+ CPUPPCState *env = &cpu->env;
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+ target_ulong hv_ptr = spapr_cpu->nested_host_state->gpr[4];
+ struct kvmppc_hv_guest_state *hvstate;
+ hwaddr len = sizeof(*hvstate);
- len = sizeof(*regs);
- regs = address_space_map(CPU(cpu)->as, regs_ptr, &len, true,
+ hvstate = address_space_map(CPU(cpu)->as, hv_ptr, &len, true,
MEMTXATTRS_UNSPECIFIED);
- if (!regs || len != sizeof(*regs)) {
- address_space_unmap(CPU(cpu)->as, regs, len, 0, true);
- r3_return = H_P2;
- goto out_restore_l1;
+ if (len != sizeof(*hvstate)) {
+ address_space_unmap(CPU(cpu)->as, hvstate, len, 0, true);
+ *r3 = H_PARAMETER;
+ return -1;
}
+ restore_hvstate_from_env(hvstate, env, excp);
+ /* Is it okay to specify write length larger than actual data written? */
+ address_space_unmap(CPU(cpu)->as, hvstate, len, len, true);
+ return 0;
+}
+static void restore_ptregs_from_env(struct kvmppc_pt_regs *regs,
+ CPUPPCState *env, int excp)
+{
+ hwaddr len;
len = sizeof(env->gpr);
assert(len == sizeof(regs->gpr));
memcpy(regs->gpr, env->gpr, len);
-
- regs->link = env->lr;
- regs->ctr = env->ctr;
- regs->xer = cpu_read_xer(env);
- regs->ccr = ppc_get_cr(env);
-
if (excp == POWERPC_EXCP_MCHECK ||
excp == POWERPC_EXCP_RESET ||
excp == POWERPC_EXCP_SYSCALL) {
@@ -1780,11 +1765,50 @@ void spapr_exit_nested(PowerPCCPU *cpu, int excp)
regs->nip = env->spr[SPR_HSRR0];
regs->msr = env->spr[SPR_HSRR1] & env->msr_mask;
}
+ regs->link = env->lr;
+ regs->ctr = env->ctr;
+ regs->xer = cpu_read_xer(env);
+ regs->ccr = ppc_get_cr(env);
+}
+static int map_and_restore_ptregs(PowerPCCPU *cpu, int excp, target_ulong *r3)
+{
+ CPUPPCState *env = &cpu->env;
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+ target_ulong regs_ptr = spapr_cpu->nested_host_state->gpr[5];
+ hwaddr len;
+ struct kvmppc_pt_regs *regs = NULL;
+
+ len = sizeof(*regs);
+ regs = address_space_map(CPU(cpu)->as, regs_ptr, &len, true,
+ MEMTXATTRS_UNSPECIFIED);
+ if (!regs || len != sizeof(*regs)) {
+ address_space_unmap(CPU(cpu)->as, regs, len, 0, true);
+ *r3 = H_P2;
+ return -1;
+ }
+ restore_ptregs_from_env(regs, env, excp);
/* Is it okay to specify write length larger than actual data written? */
address_space_unmap(CPU(cpu)->as, regs, len, len, true);
+ return 0;
+}
+
+void spapr_exit_nested(PowerPCCPU *cpu, int excp)
+{
+ CPUState *cs = CPU(cpu);
+ CPUPPCState *env = &cpu->env;
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+ target_ulong r3_return = env->excp_vectors[excp]; /* hcall return value */
+
+ assert(spapr_cpu->in_nested);
+
+ cpu_ppc_hdecr_exit(env);
+
+ if (!map_and_restore_hvstate(cpu, excp, &r3_return)) {
+ map_and_restore_ptregs (cpu, excp, &r3_return);
+ }
-out_restore_l1:
+ /* out_restore_l1 */
memcpy(env->gpr, spapr_cpu->nested_host_state->gpr, sizeof(env->gpr));
env->lr = spapr_cpu->nested_host_state->lr;
env->ctr = spapr_cpu->nested_host_state->ctr;
--
2.31.1
- [PATCH 0/5] Cleanup [h_enter|spapr_exit]_nested routines, Harsh Prateek Bora, 2023/03/31
- [PATCH 1/5] ppc: spapr: cleanup cr get/store with helper routines., Harsh Prateek Bora, 2023/03/31
- [PATCH 2/5] ppc: spapr: cleanup h_enter_nested() with helper routines., Harsh Prateek Bora, 2023/03/31
- [PATCH 3/5] ppc: spapr: assert early rather late in h_enter_nested(), Harsh Prateek Bora, 2023/03/31
- [PATCH 5/5] MAINTAINERS: Adding myself in the list for ppc/spapr, Harsh Prateek Bora, 2023/03/31
- [PATCH 4/5] ppc: spapr: cleanup spapr_exit_nested() with helper routines.,
Harsh Prateek Bora <=
- Re: [PATCH 0/5] Cleanup [h_enter|spapr_exit]_nested routines, Cédric Le Goater, 2023/03/31