Skip to content

Commit 5b4273e

Browse files
committed
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-5.0-20200417' into staging
ppc patch queue for 2020-04-17 Here are a few late bugfixes for qemu-5.0 in the ppc target code. Unless some really nasty last minute bug shows up, I expect this to be the last ppc pull request for qemu-5.0. # gpg: Signature made Fri 17 Apr 2020 06:02:13 BST # gpg: using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392 # gpg: Good signature from "David Gibson <[email protected]>" [full] # gpg: aka "David Gibson (Red Hat) <[email protected]>" [full] # gpg: aka "David Gibson (ozlabs.org) <[email protected]>" [full] # gpg: aka "David Gibson (kernel.org) <[email protected]>" [unknown] # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dgibson/tags/ppc-for-5.0-20200417: target/ppc: Fix mtmsr(d) L=1 variant that loses interrupts target/ppc: Fix wrong interpretation of the disposition flag. linux-user/ppc: Fix padding in mcontext_t for ppc64 Signed-off-by: Peter Maydell <[email protected]>
2 parents d5232d8 + 5ed1950 commit 5b4273e

File tree

3 files changed

+58
-61
lines changed

3 files changed

+58
-61
lines changed

linux-user/ppc/signal.c

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -35,45 +35,41 @@ struct target_mcontext {
3535
target_ulong mc_gregs[48];
3636
/* Includes fpscr. */
3737
uint64_t mc_fregs[33];
38+
3839
#if defined(TARGET_PPC64)
3940
/* Pointer to the vector regs */
4041
target_ulong v_regs;
42+
/*
43+
* On ppc64, this mcontext structure is naturally *unaligned*,
44+
* or rather it is aligned on a 8 bytes boundary but not on
45+
* a 16 byte boundary. This pad fixes it up. This is why we
46+
* cannot use ppc_avr_t, which would force alignment. This is
47+
* also why the vector regs are referenced in the ABI by the
48+
* v_regs pointer above so any amount of padding can be added here.
49+
*/
50+
target_ulong pad;
51+
/* VSCR and VRSAVE are saved separately. Also reserve space for VSX. */
52+
struct {
53+
uint64_t altivec[34 + 16][2];
54+
} mc_vregs;
4155
#else
4256
target_ulong mc_pad[2];
43-
#endif
57+
4458
/* We need to handle Altivec and SPE at the same time, which no
4559
kernel needs to do. Fortunately, the kernel defines this bit to
4660
be Altivec-register-large all the time, rather than trying to
4761
twiddle it based on the specific platform. */
4862
union {
4963
/* SPE vector registers. One extra for SPEFSCR. */
5064
uint32_t spe[33];
51-
/* Altivec vector registers. The packing of VSCR and VRSAVE
52-
varies depending on whether we're PPC64 or not: PPC64 splits
53-
them apart; PPC32 stuffs them together.
54-
We also need to account for the VSX registers on PPC64
55-
*/
56-
#if defined(TARGET_PPC64)
57-
#define QEMU_NVRREG (34 + 16)
58-
/* On ppc64, this mcontext structure is naturally *unaligned*,
59-
* or rather it is aligned on a 8 bytes boundary but not on
60-
* a 16 bytes one. This pad fixes it up. This is also why the
61-
* vector regs are referenced by the v_regs pointer above so
62-
* any amount of padding can be added here
63-
*/
64-
target_ulong pad;
65-
#else
66-
/* On ppc32, we are already aligned to 16 bytes */
67-
#define QEMU_NVRREG 33
68-
#endif
69-
/* We cannot use ppc_avr_t here as we do *not* want the implied
70-
* 16-bytes alignment that would result from it. This would have
71-
* the effect of making the whole struct target_mcontext aligned
72-
* which breaks the layout of struct target_ucontext on ppc64.
65+
/*
66+
* Altivec vector registers. One extra for VRSAVE.
67+
* On ppc32, we are already aligned to 16 bytes. We could
68+
* use ppc_avr_t, but choose to share the same type as ppc64.
7369
*/
74-
uint64_t altivec[QEMU_NVRREG][2];
75-
#undef QEMU_NVRREG
70+
uint64_t altivec[33][2];
7671
} mc_vregs;
72+
#endif
7773
};
7874

7975
/* See arch/powerpc/include/asm/sigcontext.h. */
@@ -278,6 +274,7 @@ static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame)
278274
__put_user((uint32_t)env->spr[SPR_VRSAVE], vrsave);
279275
}
280276

277+
#if defined(TARGET_PPC64)
281278
/* Save VSX second halves */
282279
if (env->insns_flags2 & PPC2_VSX) {
283280
uint64_t *vsregs = (uint64_t *)&frame->mc_vregs.altivec[34];
@@ -286,6 +283,7 @@ static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame)
286283
__put_user(*vsrl, &vsregs[i]);
287284
}
288285
}
286+
#endif
289287

290288
/* Save floating point registers. */
291289
if (env->insns_flags & PPC_FLOAT) {
@@ -296,22 +294,18 @@ static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame)
296294
__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]);
297295
}
298296

297+
#if !defined(TARGET_PPC64)
299298
/* Save SPE registers. The kernel only saves the high half. */
300299
if (env->insns_flags & PPC_SPE) {
301-
#if defined(TARGET_PPC64)
302-
for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
303-
__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i]);
304-
}
305-
#else
306300
for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
307301
__put_user(env->gprh[i], &frame->mc_vregs.spe[i]);
308302
}
309-
#endif
310303
/* Set MSR_SPE in the saved MSR value to indicate that
311304
frame->mc_vregs contains valid data. */
312305
msr |= MSR_SPE;
313306
__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]);
314307
}
308+
#endif
315309

316310
/* Store MSR. */
317311
__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]);
@@ -392,6 +386,7 @@ static void restore_user_regs(CPUPPCState *env,
392386
__get_user(env->spr[SPR_VRSAVE], vrsave);
393387
}
394388

389+
#if defined(TARGET_PPC64)
395390
/* Restore VSX second halves */
396391
if (env->insns_flags2 & PPC2_VSX) {
397392
uint64_t *vsregs = (uint64_t *)&frame->mc_vregs.altivec[34];
@@ -400,6 +395,7 @@ static void restore_user_regs(CPUPPCState *env,
400395
__get_user(*vsrl, &vsregs[i]);
401396
}
402397
}
398+
#endif
403399

404400
/* Restore floating point registers. */
405401
if (env->insns_flags & PPC_FLOAT) {
@@ -412,22 +408,15 @@ static void restore_user_regs(CPUPPCState *env,
412408
env->fpscr = (uint32_t) fpscr;
413409
}
414410

411+
#if !defined(TARGET_PPC64)
415412
/* Save SPE registers. The kernel only saves the high half. */
416413
if (env->insns_flags & PPC_SPE) {
417-
#if defined(TARGET_PPC64)
418-
for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
419-
uint32_t hi;
420-
421-
__get_user(hi, &frame->mc_vregs.spe[i]);
422-
env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
423-
}
424-
#else
425414
for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
426415
__get_user(env->gprh[i], &frame->mc_vregs.spe[i]);
427416
}
428-
#endif
429417
__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]);
430418
}
419+
#endif
431420
}
432421

433422
#if !defined(TARGET_PPC64)

target/ppc/kvm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2816,11 +2816,11 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
28162816
#if defined(TARGET_PPC64)
28172817
int kvm_handle_nmi(PowerPCCPU *cpu, struct kvm_run *run)
28182818
{
2819-
bool recovered = run->flags & KVM_RUN_PPC_NMI_DISP_FULLY_RECOV;
2819+
uint16_t flags = run->flags & KVM_RUN_PPC_NMI_DISP_MASK;
28202820

28212821
cpu_synchronize_state(CPU(cpu));
28222822

2823-
spapr_mce_req_event(cpu, recovered);
2823+
spapr_mce_req_event(cpu, flags == KVM_RUN_PPC_NMI_DISP_FULLY_RECOV);
28242824

28252825
return 0;
28262826
}

target/ppc/translate.c

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4361,30 +4361,34 @@ static void gen_mtmsrd(DisasContext *ctx)
43614361
CHK_SV;
43624362

43634363
#if !defined(CONFIG_USER_ONLY)
4364+
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4365+
gen_io_start();
4366+
}
43644367
if (ctx->opcode & 0x00010000) {
4365-
/* Special form that does not need any synchronisation */
4368+
/* L=1 form only updates EE and RI */
43664369
TCGv t0 = tcg_temp_new();
4370+
TCGv t1 = tcg_temp_new();
43674371
tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)],
43684372
(1 << MSR_RI) | (1 << MSR_EE));
4369-
tcg_gen_andi_tl(cpu_msr, cpu_msr,
4373+
tcg_gen_andi_tl(t1, cpu_msr,
43704374
~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
4371-
tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
4375+
tcg_gen_or_tl(t1, t1, t0);
4376+
4377+
gen_helper_store_msr(cpu_env, t1);
43724378
tcg_temp_free(t0);
4379+
tcg_temp_free(t1);
4380+
43734381
} else {
43744382
/*
43754383
* XXX: we need to update nip before the store if we enter
43764384
* power saving mode, we will exit the loop directly from
43774385
* ppc_store_msr
43784386
*/
4379-
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4380-
gen_io_start();
4381-
}
43824387
gen_update_nip(ctx, ctx->base.pc_next);
43834388
gen_helper_store_msr(cpu_env, cpu_gpr[rS(ctx->opcode)]);
4384-
/* Must stop the translation as machine state (may have) changed */
4385-
/* Note that mtmsr is not always defined as context-synchronizing */
4386-
gen_stop_exception(ctx);
43874389
}
4390+
/* Must stop the translation as machine state (may have) changed */
4391+
gen_stop_exception(ctx);
43884392
#endif /* !defined(CONFIG_USER_ONLY) */
43894393
}
43904394
#endif /* defined(TARGET_PPC64) */
@@ -4394,15 +4398,23 @@ static void gen_mtmsr(DisasContext *ctx)
43944398
CHK_SV;
43954399

43964400
#if !defined(CONFIG_USER_ONLY)
4397-
if (ctx->opcode & 0x00010000) {
4398-
/* Special form that does not need any synchronisation */
4401+
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4402+
gen_io_start();
4403+
}
4404+
if (ctx->opcode & 0x00010000) {
4405+
/* L=1 form only updates EE and RI */
43994406
TCGv t0 = tcg_temp_new();
4407+
TCGv t1 = tcg_temp_new();
44004408
tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)],
44014409
(1 << MSR_RI) | (1 << MSR_EE));
4402-
tcg_gen_andi_tl(cpu_msr, cpu_msr,
4410+
tcg_gen_andi_tl(t1, cpu_msr,
44034411
~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
4404-
tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
4412+
tcg_gen_or_tl(t1, t1, t0);
4413+
4414+
gen_helper_store_msr(cpu_env, t1);
44054415
tcg_temp_free(t0);
4416+
tcg_temp_free(t1);
4417+
44064418
} else {
44074419
TCGv msr = tcg_temp_new();
44084420

@@ -4411,9 +4423,6 @@ static void gen_mtmsr(DisasContext *ctx)
44114423
* power saving mode, we will exit the loop directly from
44124424
* ppc_store_msr
44134425
*/
4414-
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4415-
gen_io_start();
4416-
}
44174426
gen_update_nip(ctx, ctx->base.pc_next);
44184427
#if defined(TARGET_PPC64)
44194428
tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
@@ -4422,10 +4431,9 @@ static void gen_mtmsr(DisasContext *ctx)
44224431
#endif
44234432
gen_helper_store_msr(cpu_env, msr);
44244433
tcg_temp_free(msr);
4425-
/* Must stop the translation as machine state (may have) changed */
4426-
/* Note that mtmsr is not always defined as context-synchronizing */
4427-
gen_stop_exception(ctx);
44284434
}
4435+
/* Must stop the translation as machine state (may have) changed */
4436+
gen_stop_exception(ctx);
44294437
#endif
44304438
}
44314439

0 commit comments

Comments
 (0)