qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

ppc: Fix signal delivery in ppc-user and ppc64-user

There were a number of bugs in the implementation:

- The structure alignment was wrong for 64-bit.

- Also 64-bit only does RT signals.

- On 64-bit, we need to put a pointer to the (aligned) vector registers
in the frame and use it for restoring

- We had endian bugs when saving/restoring vector registers

- My recent fixes for exception NIP broke sigreturn in user mode
causing us to resume one instruction too far.

- Add VSR second halves

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

authored by

Benjamin Herrenschmidt and committed by
David Gibson
95cda4c4 ab045436

+90 -38
+1 -1
linux-user/main.c
··· 1992 1992 if (ret == -TARGET_ERESTARTSYS) { 1993 1993 break; 1994 1994 } 1995 - env->nip += 4; 1996 1995 if (ret == (target_ulong)(-TARGET_QEMU_ESIGRETURN)) { 1997 1996 /* Returning from a successful sigreturn syscall. 1998 1997 Avoid corrupting register state. */ 1999 1998 break; 2000 1999 } 2000 + env->nip += 4; 2001 2001 if (ret > (target_ulong)(-515)) { 2002 2002 env->crf[0] |= 0x1; 2003 2003 ret = -ret;
+2
linux-user/ppc/syscall_nr.h
··· 120 120 #define TARGET_NR_sysinfo 116 121 121 #define TARGET_NR_ipc 117 122 122 #define TARGET_NR_fsync 118 123 + #if !defined(TARGET_PPC64) 123 124 #define TARGET_NR_sigreturn 119 125 + #endif 124 126 #define TARGET_NR_clone 120 125 127 #define TARGET_NR_setdomainname 121 126 128 #define TARGET_NR_uname 122
+87 -37
linux-user/signal.c
··· 4454 4454 target_ulong mc_gregs[48]; 4455 4455 /* Includes fpscr. */ 4456 4456 uint64_t mc_fregs[33]; 4457 + #if defined(TARGET_PPC64) 4458 + /* Pointer to the vector regs */ 4459 + target_ulong v_regs; 4460 + #else 4457 4461 target_ulong mc_pad[2]; 4462 + #endif 4458 4463 /* We need to handle Altivec and SPE at the same time, which no 4459 4464 kernel needs to do. Fortunately, the kernel defines this bit to 4460 4465 be Altivec-register-large all the time, rather than trying to ··· 4464 4469 uint32_t spe[33]; 4465 4470 /* Altivec vector registers. The packing of VSCR and VRSAVE 4466 4471 varies depending on whether we're PPC64 or not: PPC64 splits 4467 - them apart; PPC32 stuffs them together. */ 4472 + them apart; PPC32 stuffs them together. 4473 + We also need to account for the VSX registers on PPC64 4474 + */ 4468 4475 #if defined(TARGET_PPC64) 4469 - #define QEMU_NVRREG 34 4476 + #define QEMU_NVRREG (34 + 16) 4477 + /* On ppc64, this mcontext structure is naturally *unaligned*, 4478 + * or rather it is aligned on a 8 bytes boundary but not on 4479 + * a 16 bytes one. This pad fixes it up. This is also why the 4480 + * vector regs are referenced by the v_regs pointer above so 4481 + * any amount of padding can be added here 4482 + */ 4483 + target_ulong pad; 4470 4484 #else 4485 + /* On ppc32, we are already aligned to 16 bytes */ 4471 4486 #define QEMU_NVRREG 33 4472 4487 #endif 4473 - ppc_avr_t altivec[QEMU_NVRREG]; 4488 + /* We cannot use ppc_avr_t here as we do *not* want the implied 4489 + * 16-bytes alignment that would result from it. This would have 4490 + * the effect of making the whole struct target_mcontext aligned 4491 + * which breaks the layout of struct target_ucontext on ppc64. 4492 + */ 4493 + uint64_t altivec[QEMU_NVRREG][2]; 4474 4494 #undef QEMU_NVRREG 4475 - } mc_vregs __attribute__((__aligned__(16))); 4495 + } mc_vregs; 4476 4496 }; 4477 4497 4478 4498 /* See arch/powerpc/include/asm/sigcontext.h. */ ··· 4626 4646 return (oldsp - frame_size) & ~0xFUL; 4627 4647 } 4628 4648 4649 + #if ((defined(TARGET_WORDS_BIGENDIAN) && defined(HOST_WORDS_BIGENDIAN)) || \ 4650 + (!defined(HOST_WORDS_BIGENDIAN) && !defined(TARGET_WORDS_BIGENDIAN))) 4651 + #define PPC_VEC_HI 0 4652 + #define PPC_VEC_LO 1 4653 + #else 4654 + #define PPC_VEC_HI 1 4655 + #define PPC_VEC_LO 0 4656 + #endif 4657 + 4658 + 4629 4659 static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame) 4630 4660 { 4631 4661 target_ulong msr = env->msr; ··· 4652 4682 4653 4683 /* Save Altivec registers if necessary. */ 4654 4684 if (env->insns_flags & PPC_ALTIVEC) { 4685 + uint32_t *vrsave; 4655 4686 for (i = 0; i < ARRAY_SIZE(env->avr); i++) { 4656 4687 ppc_avr_t *avr = &env->avr[i]; 4657 - ppc_avr_t *vreg = &frame->mc_vregs.altivec[i]; 4688 + ppc_avr_t *vreg = (ppc_avr_t *)&frame->mc_vregs.altivec[i]; 4658 4689 4659 - __put_user(avr->u64[0], &vreg->u64[0]); 4660 - __put_user(avr->u64[1], &vreg->u64[1]); 4690 + __put_user(avr->u64[PPC_VEC_HI], &vreg->u64[0]); 4691 + __put_user(avr->u64[PPC_VEC_LO], &vreg->u64[1]); 4661 4692 } 4662 4693 /* Set MSR_VR in the saved MSR value to indicate that 4663 4694 frame->mc_vregs contains valid data. */ 4664 4695 msr |= MSR_VR; 4665 - __put_user((uint32_t)env->spr[SPR_VRSAVE], 4666 - &frame->mc_vregs.altivec[32].u32[3]); 4696 + #if defined(TARGET_PPC64) 4697 + vrsave = (uint32_t *)&frame->mc_vregs.altivec[33]; 4698 + /* 64-bit needs to put a pointer to the vectors in the frame */ 4699 + __put_user(h2g(frame->mc_vregs.altivec), &frame->v_regs); 4700 + #else 4701 + vrsave = (uint32_t *)&frame->mc_vregs.altivec[32]; 4702 + #endif 4703 + __put_user((uint32_t)env->spr[SPR_VRSAVE], vrsave); 4704 + } 4705 + 4706 + /* Save VSX second halves */ 4707 + if (env->insns_flags2 & PPC2_VSX) { 4708 + uint64_t *vsregs = (uint64_t *)&frame->mc_vregs.altivec[34]; 4709 + for (i = 0; i < ARRAY_SIZE(env->vsr); i++) { 4710 + __put_user(env->vsr[i], &vsregs[i]); 4711 + } 4667 4712 } 4668 4713 4669 4714 /* Save floating point registers. */ ··· 4743 4788 4744 4789 /* Restore Altivec registers if necessary. */ 4745 4790 if (env->insns_flags & PPC_ALTIVEC) { 4791 + ppc_avr_t *v_regs; 4792 + uint32_t *vrsave; 4793 + #if defined(TARGET_PPC64) 4794 + uint64_t v_addr; 4795 + /* 64-bit needs to recover the pointer to the vectors from the frame */ 4796 + __get_user(v_addr, &frame->v_regs); 4797 + v_regs = g2h(v_addr); 4798 + #else 4799 + v_regs = (ppc_avr_t *)frame->mc_vregs.altivec; 4800 + #endif 4746 4801 for (i = 0; i < ARRAY_SIZE(env->avr); i++) { 4747 4802 ppc_avr_t *avr = &env->avr[i]; 4748 - ppc_avr_t *vreg = &frame->mc_vregs.altivec[i]; 4803 + ppc_avr_t *vreg = &v_regs[i]; 4749 4804 4750 - __get_user(avr->u64[0], &vreg->u64[0]); 4751 - __get_user(avr->u64[1], &vreg->u64[1]); 4805 + __get_user(avr->u64[PPC_VEC_HI], &vreg->u64[0]); 4806 + __get_user(avr->u64[PPC_VEC_LO], &vreg->u64[1]); 4752 4807 } 4753 4808 /* Set MSR_VEC in the saved MSR value to indicate that 4754 4809 frame->mc_vregs contains valid data. */ 4755 - __get_user(env->spr[SPR_VRSAVE], 4756 - (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3])); 4810 + #if defined(TARGET_PPC64) 4811 + vrsave = (uint32_t *)&v_regs[33]; 4812 + #else 4813 + vrsave = (uint32_t *)&v_regs[32]; 4814 + #endif 4815 + __get_user(env->spr[SPR_VRSAVE], vrsave); 4816 + } 4817 + 4818 + /* Restore VSX second halves */ 4819 + if (env->insns_flags2 & PPC2_VSX) { 4820 + uint64_t *vsregs = (uint64_t *)&frame->mc_vregs.altivec[34]; 4821 + for (i = 0; i < ARRAY_SIZE(env->vsr); i++) { 4822 + __get_user(env->vsr[i], &vsregs[i]); 4823 + } 4757 4824 } 4758 4825 4759 4826 /* Restore floating point registers. */ ··· 4784 4851 } 4785 4852 } 4786 4853 4854 + #if !defined(TARGET_PPC64) 4787 4855 static void setup_frame(int sig, struct target_sigaction *ka, 4788 4856 target_sigset_t *set, CPUPPCState *env) 4789 4857 { ··· 4791 4859 struct target_sigcontext *sc; 4792 4860 target_ulong frame_addr, newsp; 4793 4861 int err = 0; 4794 - #if defined(TARGET_PPC64) 4795 - struct image_info *image = ((TaskState *)thread_cpu->opaque)->info; 4796 - #endif 4797 4862 4798 4863 frame_addr = get_sigframe(ka, env, sizeof(*frame)); 4799 4864 trace_user_setup_frame(env, frame_addr); ··· 4803 4868 4804 4869 __put_user(ka->_sa_handler, &sc->handler); 4805 4870 __put_user(set->sig[0], &sc->oldmask); 4806 - #if TARGET_ABI_BITS == 64 4807 - __put_user(set->sig[0] >> 32, &sc->_unused[3]); 4808 - #else 4809 4871 __put_user(set->sig[1], &sc->_unused[3]); 4810 - #endif 4811 4872 __put_user(h2g(&frame->mctx), &sc->regs); 4812 4873 __put_user(sig, &sc->signal); 4813 4874 ··· 4836 4897 env->gpr[3] = sig; 4837 4898 env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx); 4838 4899 4839 - #if defined(TARGET_PPC64) 4840 - if (get_ppc64_abi(image) < 2) { 4841 - /* ELFv1 PPC64 function pointers are pointers to OPD entries. */ 4842 - struct target_func_ptr *handler = 4843 - (struct target_func_ptr *)g2h(ka->_sa_handler); 4844 - env->nip = tswapl(handler->entry); 4845 - env->gpr[2] = tswapl(handler->toc); 4846 - } else { 4847 - /* ELFv2 PPC64 function pointers are entry points, but R12 4848 - * must also be set */ 4849 - env->nip = tswapl((target_ulong) ka->_sa_handler); 4850 - env->gpr[12] = env->nip; 4851 - } 4852 - #else 4853 4900 env->nip = (target_ulong) ka->_sa_handler; 4854 - #endif 4855 4901 4856 4902 /* Signal handlers are entered in big-endian mode. */ 4857 4903 env->msr &= ~(1ull << MSR_LE); ··· 4863 4909 unlock_user_struct(frame, frame_addr, 1); 4864 4910 force_sigsegv(sig); 4865 4911 } 4912 + #endif /* !defined(TARGET_PPC64) */ 4866 4913 4867 4914 static void setup_rt_frame(int sig, struct target_sigaction *ka, 4868 4915 target_siginfo_t *info, ··· 4960 5007 4961 5008 } 4962 5009 5010 + #if !defined(TARGET_PPC64) 4963 5011 long do_sigreturn(CPUPPCState *env) 4964 5012 { 4965 5013 struct target_sigcontext *sc = NULL; ··· 4996 5044 force_sig(TARGET_SIGSEGV); 4997 5045 return -TARGET_QEMU_ESIGRETURN; 4998 5046 } 5047 + #endif /* !defined(TARGET_PPC64) */ 4999 5048 5000 5049 /* See arch/powerpc/kernel/signal_32.c. */ 5001 5050 static int do_setcontext(struct target_ucontext *ucp, CPUPPCState *env, int sig) ··· 5939 5988 #endif 5940 5989 /* prepare the stack frame of the virtual CPU */ 5941 5990 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) \ 5942 - || defined(TARGET_OPENRISC) || defined(TARGET_TILEGX) 5991 + || defined(TARGET_OPENRISC) || defined(TARGET_TILEGX) \ 5992 + || defined(TARGET_PPC64) 5943 5993 /* These targets do not have traditional signals. */ 5944 5994 setup_rt_frame(sig, sa, &k->info, &target_old_set, cpu_env); 5945 5995 #else