1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2020 Linaro Limited. All rights reserved. 4 * Author: Viresh Kumar <viresh.kumar@linaro.org> 5 */ 6 7#ifndef LAPI_SEMBUF_H__ 8#define LAPI_SEMBUF_H__ 9 10#include "lapi/posix_types.h" 11#include <sys/sem.h> 12#include "tst_timer.h" 13#include "ipcbuf.h" 14 15#ifndef HAVE_SEMID64_DS 16 17#if defined(__mips__) 18#define HAVE_SEMID64_DS 19/* 20 * The semid64_ds structure for the MIPS architecture. 21 * Note extra padding because this structure is passed back and forth 22 * between kernel and user space. 23 * 24 * Pad space is left for 2 miscellaneous 64-bit values on mips64, 25 * but used for the upper 32 bit of the time values on mips32. 26 */ 27#if __BITS_PER_LONG == 64 28struct semid64_ds { 29 struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ 30 long sem_otime; /* last semop time */ 31 long sem_ctime; /* last change time */ 32 unsigned long sem_nsems; /* no. of semaphores in array */ 33 unsigned long __unused1; 34 unsigned long __unused2; 35}; 36#else 37#define HAVE_SEMID64_DS_TIME_HIGH 38struct semid64_ds { 39 struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ 40 unsigned long sem_otime; /* last semop time */ 41 unsigned long sem_ctime; /* last change time */ 42 unsigned long sem_nsems; /* no. of semaphores in array */ 43 unsigned long sem_otime_high; 44 unsigned long sem_ctime_high; 45}; 46#endif 47#endif /* __mips__ */ 48 49#if defined(__hppa__) 50#define HAVE_SEMID64_DS 51/* 52 * The semid64_ds structure for parisc architecture. 53 * Note extra padding because this structure is passed back and forth 54 * between kernel and user space. 55 * 56 * Pad space is left for: 57 * - 2 miscellaneous 32-bit values 58 */ 59struct semid64_ds { 60 struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ 61#if __BITS_PER_LONG == 64 62 long sem_otime; /* last semop time */ 63 long sem_ctime; /* last change time */ 64#else 65#define HAVE_SEMID64_DS_TIME_HIGH 66 unsigned long sem_otime_high; 67 unsigned long sem_otime; /* last semop time */ 68 unsigned long sem_ctime_high; 69 unsigned long sem_ctime; /* last change time */ 70#endif 71 unsigned long sem_nsems; /* no. of semaphores in array */ 72 unsigned long __unused1; 73 unsigned long __unused2; 74}; 75#endif /* __hppa__ */ 76 77#if defined(__powerpc__) || defined(__powerpc64__) 78#define HAVE_SEMID64_DS 79/* 80 * The semid64_ds structure for PPC architecture. 81 * Note extra padding because this structure is passed back and forth 82 * between kernel and user space. 83 * 84 * Pad space is left for: 85 * - 2 miscellaneous 32/64-bit values 86 */ 87 88struct semid64_ds { 89 struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ 90#ifndef __powerpc64__ 91#define HAVE_SEMID64_DS_TIME_HIGH 92 unsigned long sem_otime_high; 93 unsigned long sem_otime; /* last semop time */ 94 unsigned long sem_ctime_high; 95 unsigned long sem_ctime; /* last change time */ 96#else 97 long sem_otime; /* last semop time */ 98 long sem_ctime; /* last change time */ 99#endif 100 unsigned long sem_nsems; /* no. of semaphores in array */ 101 unsigned long __unused3; 102 unsigned long __unused4; 103}; 104#endif /* defined(__powerpc__) || defined(__powerpc64__) */ 105 106#if defined(__sparc__) 107#define HAVE_SEMID64_DS 108/* 109 * The semid64_ds structure for sparc architecture. 110 * Note extra padding because this structure is passed back and forth 111 * between kernel and user space. 112 * 113 * Pad space is left for: 114 * - 2 miscellaneous 32-bit values 115 */ 116 117struct semid64_ds { 118 struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ 119#if defined(__arch64__) 120 long sem_otime; /* last semop time */ 121 long sem_ctime; /* last change time */ 122#else 123#define HAVE_SEMID64_DS_TIME_HIGH 124 unsigned long sem_otime_high; 125 unsigned long sem_otime; /* last semop time */ 126 unsigned long sem_ctime_high; 127 unsigned long sem_ctime; /* last change time */ 128#endif 129 unsigned long sem_nsems; /* no. of semaphores in array */ 130 unsigned long __unused1; 131 unsigned long __unused2; 132}; 133#endif /* __sparc__ */ 134 135#if defined(__x86_64__) 136#define HAVE_SEMID64_DS 137/* 138 * The semid64_ds structure for x86 architecture. 139 * Note extra padding because this structure is passed back and forth 140 * between kernel and user space. 141 * 142 * Pad space is left for: 143 * - 2 miscellaneous 32-bit values 144 * 145 * x86_64 and x32 incorrectly added padding here, so the structures 146 * are still incompatible with the padding on x86. 147 */ 148struct semid64_ds { 149 struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ 150#ifdef __i386__ 151#define HAVE_SEMID64_DS_TIME_HIGH 152 unsigned long sem_otime; /* last semop time */ 153 unsigned long sem_otime_high; 154 unsigned long sem_ctime; /* last change time */ 155 unsigned long sem_ctime_high; 156#else 157 __kernel_long_t sem_otime; /* last semop time */ 158 __kernel_ulong_t __unused1; 159 __kernel_long_t sem_ctime; /* last change time */ 160 __kernel_ulong_t __unused2; 161#endif 162 __kernel_ulong_t sem_nsems; /* no. of semaphores in array */ 163 __kernel_ulong_t __unused3; 164 __kernel_ulong_t __unused4; 165}; 166#endif /* defined(__x86_64__) */ 167 168#if defined(__xtensa__) 169#define HAVE_SEMID64_DS 170#define HAVE_SEMID64_DS_TIME_HIGH 171 172struct semid64_ds { 173 struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ 174#ifdef __XTENSA_EL__ 175 unsigned long sem_otime; /* last semop time */ 176 unsigned long sem_otime_high; 177 unsigned long sem_ctime; /* last change time */ 178 unsigned long sem_ctime_high; 179#else 180 unsigned long sem_otime_high; 181 unsigned long sem_otime; /* last semop time */ 182 unsigned long sem_ctime_high; 183 unsigned long sem_ctime; /* last change time */ 184#endif 185 unsigned long sem_nsems; /* no. of semaphores in array */ 186 unsigned long __unused3; 187 unsigned long __unused4; 188}; 189 190#endif /* __xtensa__ */ 191 192#ifndef HAVE_SEMID64_DS 193/* 194 * The semid64_ds structure for most architectures (though it came 195 * from x86_32 originally). Note extra padding because this structure 196 * is passed back and forth between kernel and user space. 197 * 198 * semid64_ds was originally meant to be architecture specific, but 199 * everyone just ended up making identical copies without specific 200 * optimizations, so we may just as well all use the same one. 201 * 202 * 64 bit architectures use a 64-bit long time field here, while 203 * 32 bit architectures have a pair of unsigned long values. 204 * 205 * On big-endian systems, the padding is in the wrong place for 206 * historic reasons, so user space has to reconstruct a time_t 207 * value using 208 * 209 * user_semid_ds.sem_otime = kernel_semid64_ds.sem_otime + 210 * ((long long)kernel_semid64_ds.sem_otime_high << 32) 211 * 212 * Pad space is left for 2 miscellaneous 32-bit values 213 */ 214struct semid64_ds { 215 struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ 216#if __BITS_PER_LONG == 64 217 long sem_otime; /* last semop time */ 218 long sem_ctime; /* last change time */ 219#else 220#define HAVE_SEMID64_DS_TIME_HIGH 221 unsigned long sem_otime; /* last semop time */ 222 unsigned long sem_otime_high; 223 unsigned long sem_ctime; /* last change time */ 224 unsigned long sem_ctime_high; 225#endif 226 unsigned long sem_nsems; /* no. of semaphores in array */ 227 unsigned long __unused3; 228 unsigned long __unused4; 229}; 230#endif /* semid64_ds */ 231 232#endif /* HAVE_SEMID64_DS */ 233 234#endif /* LAPI_SEMBUF_H__ */ 235