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

linux-user: Fix target_semid_ds structure definition

The target_semid_ds structure is not correct for all
architectures: the padding fields should only exist for:
* 32-bit ABIs
* x86

It is also misnamed, since it is following the kernel
semid64_ds structure (QEMU doesn't support the legacy
semid_ds structure at all). Rename the struct, provide
a correct generic definition and allow the oddball x86
architecture to provide its own version.

This fixes broken SYSV semaphores for all our 64-bit
architectures except x86 and ppc.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>

authored by

Peter Maydell and committed by
Riku Voipio
005eb2ae 332c9781

+25 -7
+10 -7
linux-user/syscall.c
··· 3754 3754 bool in_use; 3755 3755 } shm_regions[N_SHM_REGIONS]; 3756 3756 3757 - struct target_semid_ds 3757 + #ifndef TARGET_SEMID64_DS 3758 + /* asm-generic version of this struct */ 3759 + struct target_semid64_ds 3758 3760 { 3759 3761 struct target_ipc_perm sem_perm; 3760 3762 abi_ulong sem_otime; 3761 - #if !defined(TARGET_PPC64) 3763 + #if TARGET_ABI_BITS == 32 3762 3764 abi_ulong __unused1; 3763 3765 #endif 3764 3766 abi_ulong sem_ctime; 3765 - #if !defined(TARGET_PPC64) 3767 + #if TARGET_ABI_BITS == 32 3766 3768 abi_ulong __unused2; 3767 3769 #endif 3768 3770 abi_ulong sem_nsems; 3769 3771 abi_ulong __unused3; 3770 3772 abi_ulong __unused4; 3771 3773 }; 3774 + #endif 3772 3775 3773 3776 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip, 3774 3777 abi_ulong target_addr) 3775 3778 { 3776 3779 struct target_ipc_perm *target_ip; 3777 - struct target_semid_ds *target_sd; 3780 + struct target_semid64_ds *target_sd; 3778 3781 3779 3782 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) 3780 3783 return -TARGET_EFAULT; ··· 3802 3805 struct ipc_perm *host_ip) 3803 3806 { 3804 3807 struct target_ipc_perm *target_ip; 3805 - struct target_semid_ds *target_sd; 3808 + struct target_semid64_ds *target_sd; 3806 3809 3807 3810 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) 3808 3811 return -TARGET_EFAULT; ··· 3829 3832 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd, 3830 3833 abi_ulong target_addr) 3831 3834 { 3832 - struct target_semid_ds *target_sd; 3835 + struct target_semid64_ds *target_sd; 3833 3836 3834 3837 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) 3835 3838 return -TARGET_EFAULT; ··· 3845 3848 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr, 3846 3849 struct semid_ds *host_sd) 3847 3850 { 3848 - struct target_semid_ds *target_sd; 3851 + struct target_semid64_ds *target_sd; 3849 3852 3850 3853 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) 3851 3854 return -TARGET_EFAULT;
+15
linux-user/x86_64/target_structs.h
··· 55 55 abi_ulong __unused5; 56 56 }; 57 57 58 + /* The x86 definition differs from the generic one in that the 59 + * two padding fields exist whether the ABI is 32 bits or 64 bits. 60 + */ 61 + #define TARGET_SEMID64_DS 62 + struct target_semid64_ds { 63 + struct target_ipc_perm sem_perm; 64 + abi_ulong sem_otime; 65 + abi_ulong __unused1; 66 + abi_ulong sem_ctime; 67 + abi_ulong __unused2; 68 + abi_ulong sem_nsems; 69 + abi_ulong __unused3; 70 + abi_ulong __unused4; 71 + }; 72 + 58 73 #endif