Browse Source

Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-4.1-pull-request' into staging

Add /proc/hardware and /proc/cpuinfo,
update SIOCXXX ioctls,
fix shmat emulation,
add nanoseconds in stat,
init field fp_abi on mips

# gpg: Signature made Fri 24 May 2019 12:24:36 BST
# gpg:                using RSA key F30C38BD3F2FBE3C
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* remotes/vivier2/tags/linux-user-for-4.1-pull-request:
  linux-user: Pass through nanosecond timestamp components for stat syscalls
  linux-user: Align mmap_find_vma to host page size
  linux-user: Fix shmat emulation by honoring host SHMLBA
  linux-user: Sanitize interp_info and, for mips only, init field fp_abi
  linux-user: Add support for SIOC<G|S>IFPFLAGS ioctls for all targets
  linux-user: Add support for SIOCSPGRP ioctl for all targets
  linux-user: Fix support for SIOCATMARK and SIOCGPGRP ioctls for xtensa
  linux-user: add pseudo /proc/hardware for m68k
  linux-user: add pseudo /proc/cpuinfo for sparc

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
master
Peter Maydell 3 weeks ago
parent
commit
a7b21f6762
6 changed files with 143 additions and 62 deletions
  1. 15
    7
      linux-user/elfload.c
  2. 3
    0
      linux-user/ioctls.h
  3. 39
    33
      linux-user/mmap.c
  4. 1
    1
      linux-user/qemu.h
  5. 47
    2
      linux-user/syscall.c
  6. 38
    19
      linux-user/syscall_defs.h

+ 15
- 7
linux-user/elfload.c View File

@@ -3,6 +3,7 @@
3 3
 #include <sys/param.h>
4 4
 
5 5
 #include <sys/resource.h>
6
+#include <sys/shm.h>
6 7
 
7 8
 #include "qemu.h"
8 9
 #include "disas/disas.h"
@@ -2010,6 +2011,8 @@ unsigned long init_guest_space(unsigned long host_start,
2010 2011
                                unsigned long guest_start,
2011 2012
                                bool fixed)
2012 2013
 {
2014
+    /* In order to use host shmat, we must be able to honor SHMLBA.  */
2015
+    unsigned long align = MAX(SHMLBA, qemu_host_page_size);
2013 2016
     unsigned long current_start, aligned_start;
2014 2017
     int flags;
2015 2018
 
@@ -2027,7 +2030,7 @@ unsigned long init_guest_space(unsigned long host_start,
2027 2030
     }
2028 2031
 
2029 2032
     /* Setup the initial flags and start address.  */
2030
-    current_start = host_start & qemu_host_page_mask;
2033
+    current_start = host_start & -align;
2031 2034
     flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE;
2032 2035
     if (fixed) {
2033 2036
         flags |= MAP_FIXED;
@@ -2063,8 +2066,8 @@ unsigned long init_guest_space(unsigned long host_start,
2063 2066
             return (unsigned long)-1;
2064 2067
         }
2065 2068
         munmap((void *)real_start, host_full_size);
2066
-        if (real_start & ~qemu_host_page_mask) {
2067
-            /* The same thing again, but with an extra qemu_host_page_size
2069
+        if (real_start & (align - 1)) {
2070
+            /* The same thing again, but with extra
2068 2071
              * so that we can shift around alignment.
2069 2072
              */
2070 2073
             unsigned long real_size = host_full_size + qemu_host_page_size;
@@ -2077,7 +2080,7 @@ unsigned long init_guest_space(unsigned long host_start,
2077 2080
                 return (unsigned long)-1;
2078 2081
             }
2079 2082
             munmap((void *)real_start, real_size);
2080
-            real_start = HOST_PAGE_ALIGN(real_start);
2083
+            real_start = ROUND_UP(real_start, align);
2081 2084
         }
2082 2085
         current_start = real_start;
2083 2086
     }
@@ -2104,7 +2107,7 @@ unsigned long init_guest_space(unsigned long host_start,
2104 2107
         }
2105 2108
 
2106 2109
         /* Ensure the address is properly aligned.  */
2107
-        if (real_start & ~qemu_host_page_mask) {
2110
+        if (real_start & (align - 1)) {
2108 2111
             /* Ideally, we adjust like
2109 2112
              *
2110 2113
              *    pages: [  ][  ][  ][  ][  ]
@@ -2132,7 +2135,7 @@ unsigned long init_guest_space(unsigned long host_start,
2132 2135
             if (real_start == (unsigned long)-1) {
2133 2136
                 return (unsigned long)-1;
2134 2137
             }
2135
-            aligned_start = HOST_PAGE_ALIGN(real_start);
2138
+            aligned_start = ROUND_UP(real_start, align);
2136 2139
         } else {
2137 2140
             aligned_start = real_start;
2138 2141
         }
@@ -2169,7 +2172,7 @@ unsigned long init_guest_space(unsigned long host_start,
2169 2172
          * because of trouble with ARM commpage setup.
2170 2173
          */
2171 2174
         munmap((void *)real_start, real_size);
2172
-        current_start += qemu_host_page_size;
2175
+        current_start += align;
2173 2176
         if (host_start == current_start) {
2174 2177
             /* Theoretically possible if host doesn't have any suitably
2175 2178
              * aligned areas.  Normally the first mmap will fail.
@@ -2704,6 +2707,11 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
2704 2707
     char *elf_interpreter = NULL;
2705 2708
     char *scratch;
2706 2709
 
2710
+    memset(&interp_info, 0, sizeof(interp_info));
2711
+#ifdef TARGET_MIPS
2712
+    interp_info.fp_abi = MIPS_ABI_FP_UNKNOWN;
2713
+#endif
2714
+
2707 2715
     info->start_mmap = (abi_ulong)ELF_START_MMAP;
2708 2716
 
2709 2717
     load_elf_image(bprm->filename, bprm->fd, info,

+ 3
- 0
linux-user/ioctls.h View File

@@ -206,6 +206,8 @@
206 206
   IOCTL(SIOCADDMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
207 207
   IOCTL(SIOCDELMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
208 208
   IOCTL(SIOCGIFINDEX, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_int_ifreq)))
209
+  IOCTL(SIOCSIFPFLAGS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
210
+  IOCTL(SIOCGIFPFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
209 211
   IOCTL(SIOCSIFLINK, 0, TYPE_NULL)
210 212
   IOCTL_SPECIAL(SIOCGIFCONF, IOC_W | IOC_R, do_ioctl_ifconf,
211 213
                 MK_PTR(MK_STRUCT(STRUCT_ifconf)))
@@ -218,6 +220,7 @@
218 220
   IOCTL(SIOCSRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
219 221
   IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
220 222
   IOCTL(SIOCGIWNAME, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq)))
223
+  IOCTL(SIOCSPGRP, IOC_W, MK_PTR(TYPE_INT)) /* pid_t */
221 224
   IOCTL(SIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) /* pid_t */
222 225
   IOCTL(SIOCGSTAMP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timeval)))
223 226
   IOCTL(SIOCGSTAMPNS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timespec)))

+ 39
- 33
linux-user/mmap.c View File

@@ -202,49 +202,52 @@ unsigned long last_brk;
202 202
 
203 203
 /* Subroutine of mmap_find_vma, used when we have pre-allocated a chunk
204 204
    of guest address space.  */
205
-static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
205
+static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
206
+                                        abi_ulong align)
206 207
 {
207
-    abi_ulong addr;
208
-    abi_ulong end_addr;
208
+    abi_ulong addr, end_addr, incr = qemu_host_page_size;
209 209
     int prot;
210
-    int looped = 0;
210
+    bool looped = false;
211 211
 
212 212
     if (size > reserved_va) {
213 213
         return (abi_ulong)-1;
214 214
     }
215 215
 
216
-    size = HOST_PAGE_ALIGN(size);
216
+    /* Note that start and size have already been aligned by mmap_find_vma. */
217
+
217 218
     end_addr = start + size;
218
-    if (end_addr > reserved_va) {
219
-        end_addr = reserved_va;
219
+    if (start > reserved_va - size) {
220
+        /* Start at the top of the address space.  */
221
+        end_addr = ((reserved_va - size) & -align) + size;
222
+        looped = true;
220 223
     }
221
-    addr = end_addr - qemu_host_page_size;
222 224
 
225
+    /* Search downward from END_ADDR, checking to see if a page is in use.  */
226
+    addr = end_addr;
223 227
     while (1) {
228
+        addr -= incr;
224 229
         if (addr > end_addr) {
225 230
             if (looped) {
231
+                /* Failure.  The entire address space has been searched.  */
226 232
                 return (abi_ulong)-1;
227 233
             }
228
-            end_addr = reserved_va;
229
-            addr = end_addr - qemu_host_page_size;
230
-            looped = 1;
231
-            continue;
232
-        }
233
-        prot = page_get_flags(addr);
234
-        if (prot) {
235
-            end_addr = addr;
236
-        }
237
-        if (addr && addr + size == end_addr) {
238
-            break;
234
+            /* Re-start at the top of the address space.  */
235
+            addr = end_addr = ((reserved_va - size) & -align) + size;
236
+            looped = true;
237
+        } else {
238
+            prot = page_get_flags(addr);
239
+            if (prot) {
240
+                /* Page in use.  Restart below this page.  */
241
+                addr = end_addr = ((addr - size) & -align) + size;
242
+            } else if (addr && addr + size == end_addr) {
243
+                /* Success!  All pages between ADDR and END_ADDR are free.  */
244
+                if (start == mmap_next_start) {
245
+                    mmap_next_start = addr;
246
+                }
247
+                return addr;
248
+            }
239 249
         }
240
-        addr -= qemu_host_page_size;
241 250
     }
242
-
243
-    if (start == mmap_next_start) {
244
-        mmap_next_start = addr;
245
-    }
246
-
247
-    return addr;
248 251
 }
249 252
 
250 253
 /*
@@ -253,23 +256,26 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
253 256
  * It must be called with mmap_lock() held.
254 257
  * Return -1 if error.
255 258
  */
256
-abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
259
+abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
257 260
 {
258 261
     void *ptr, *prev;
259 262
     abi_ulong addr;
260 263
     int wrapped, repeat;
261 264
 
265
+    align = MAX(align, qemu_host_page_size);
266
+
262 267
     /* If 'start' == 0, then a default start address is used. */
263 268
     if (start == 0) {
264 269
         start = mmap_next_start;
265 270
     } else {
266 271
         start &= qemu_host_page_mask;
267 272
     }
273
+    start = ROUND_UP(start, align);
268 274
 
269 275
     size = HOST_PAGE_ALIGN(size);
270 276
 
271 277
     if (reserved_va) {
272
-        return mmap_find_vma_reserved(start, size);
278
+        return mmap_find_vma_reserved(start, size, align);
273 279
     }
274 280
 
275 281
     addr = start;
@@ -299,7 +305,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
299 305
         if (h2g_valid(ptr + size - 1)) {
300 306
             addr = h2g(ptr);
301 307
 
302
-            if ((addr & ~TARGET_PAGE_MASK) == 0) {
308
+            if ((addr & (align - 1)) == 0) {
303 309
                 /* Success.  */
304 310
                 if (start == mmap_next_start && addr >= TASK_UNMAPPED_BASE) {
305 311
                     mmap_next_start = addr + size;
@@ -313,12 +319,12 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
313 319
                 /* Assume the result that the kernel gave us is the
314 320
                    first with enough free space, so start again at the
315 321
                    next higher target page.  */
316
-                addr = TARGET_PAGE_ALIGN(addr);
322
+                addr = ROUND_UP(addr, align);
317 323
                 break;
318 324
             case 1:
319 325
                 /* Sometimes the kernel decides to perform the allocation
320 326
                    at the top end of memory instead.  */
321
-                addr &= TARGET_PAGE_MASK;
327
+                addr &= -align;
322 328
                 break;
323 329
             case 2:
324 330
                 /* Start over at low memory.  */
@@ -416,7 +422,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
416 422
     if (!(flags & MAP_FIXED)) {
417 423
         host_len = len + offset - host_offset;
418 424
         host_len = HOST_PAGE_ALIGN(host_len);
419
-        start = mmap_find_vma(real_start, host_len);
425
+        start = mmap_find_vma(real_start, host_len, TARGET_PAGE_SIZE);
420 426
         if (start == (abi_ulong)-1) {
421 427
             errno = ENOMEM;
422 428
             goto fail;
@@ -710,7 +716,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
710 716
     } else if (flags & MREMAP_MAYMOVE) {
711 717
         abi_ulong mmap_start;
712 718
 
713
-        mmap_start = mmap_find_vma(0, new_size);
719
+        mmap_start = mmap_find_vma(0, new_size, TARGET_PAGE_SIZE);
714 720
 
715 721
         if (mmap_start == -1) {
716 722
             errno = ENOMEM;

+ 1
- 1
linux-user/qemu.h View File

@@ -443,7 +443,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
443 443
                        abi_ulong new_addr);
444 444
 extern unsigned long last_brk;
445 445
 extern abi_ulong mmap_next_start;
446
-abi_ulong mmap_find_vma(abi_ulong, abi_ulong);
446
+abi_ulong mmap_find_vma(abi_ulong, abi_ulong, abi_ulong);
447 447
 void mmap_fork_start(void);
448 448
 void mmap_fork_end(int child);
449 449
 

+ 47
- 2
linux-user/syscall.c View File

@@ -3914,7 +3914,8 @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env,
3914 3914
     else {
3915 3915
         abi_ulong mmap_start;
3916 3916
 
3917
-        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
3917
+        /* In order to use the host shmat, we need to honor host SHMLBA.  */
3918
+        mmap_start = mmap_find_vma(0, shm_info.shm_segsz, MAX(SHMLBA, shmlba));
3918 3919
 
3919 3920
         if (mmap_start == -1) {
3920 3921
             errno = ENOMEM;
@@ -6412,6 +6413,11 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
6412 6413
         __put_user(host_st->st_atime, &target_st->target_st_atime);
6413 6414
         __put_user(host_st->st_mtime, &target_st->target_st_mtime);
6414 6415
         __put_user(host_st->st_ctime, &target_st->target_st_ctime);
6416
+#if _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
6417
+        __put_user(host_st->st_atim.tv_nsec, &target_st->target_st_atime_nsec);
6418
+        __put_user(host_st->st_mtim.tv_nsec, &target_st->target_st_mtime_nsec);
6419
+        __put_user(host_st->st_ctim.tv_nsec, &target_st->target_st_ctime_nsec);
6420
+#endif
6415 6421
         unlock_user_struct(target_st, target_addr, 1);
6416 6422
     } else
6417 6423
 #endif
@@ -6442,6 +6448,11 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
6442 6448
         __put_user(host_st->st_atime, &target_st->target_st_atime);
6443 6449
         __put_user(host_st->st_mtime, &target_st->target_st_mtime);
6444 6450
         __put_user(host_st->st_ctime, &target_st->target_st_ctime);
6451
+#if _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
6452
+        __put_user(host_st->st_atim.tv_nsec, &target_st->target_st_atime_nsec);
6453
+        __put_user(host_st->st_mtim.tv_nsec, &target_st->target_st_mtime_nsec);
6454
+        __put_user(host_st->st_ctim.tv_nsec, &target_st->target_st_ctime_nsec);
6455
+#endif
6445 6456
         unlock_user_struct(target_st, target_addr, 1);
6446 6457
     }
6447 6458
 
@@ -6790,12 +6801,15 @@ static int is_proc_myself(const char *filename, const char *entry)
6790 6801
     return 0;
6791 6802
 }
6792 6803
 
6793
-#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
6804
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) || \
6805
+    defined(TARGET_SPARC) || defined(TARGET_M68K)
6794 6806
 static int is_proc(const char *filename, const char *entry)
6795 6807
 {
6796 6808
     return strcmp(filename, entry) == 0;
6797 6809
 }
6810
+#endif
6798 6811
 
6812
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
6799 6813
 static int open_net_route(void *cpu_env, int fd)
6800 6814
 {
6801 6815
     FILE *fp;
@@ -6840,6 +6854,22 @@ static int open_net_route(void *cpu_env, int fd)
6840 6854
 }
6841 6855
 #endif
6842 6856
 
6857
+#if defined(TARGET_SPARC)
6858
+static int open_cpuinfo(void *cpu_env, int fd)
6859
+{
6860
+    dprintf(fd, "type\t\t: sun4u\n");
6861
+    return 0;
6862
+}
6863
+#endif
6864
+
6865
+#if defined(TARGET_M68K)
6866
+static int open_hardware(void *cpu_env, int fd)
6867
+{
6868
+    dprintf(fd, "Model:\t\tqemu-m68k\n");
6869
+    return 0;
6870
+}
6871
+#endif
6872
+
6843 6873
 static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, mode_t mode)
6844 6874
 {
6845 6875
     struct fake_open {
@@ -6855,6 +6885,12 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
6855 6885
         { "cmdline", open_self_cmdline, is_proc_myself },
6856 6886
 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
6857 6887
         { "/proc/net/route", open_net_route, is_proc },
6888
+#endif
6889
+#if defined(TARGET_SPARC)
6890
+        { "/proc/cpuinfo", open_cpuinfo, is_proc },
6891
+#endif
6892
+#if defined(TARGET_M68K)
6893
+        { "/proc/hardware", open_hardware, is_proc },
6858 6894
 #endif
6859 6895
         { NULL, NULL, NULL }
6860 6896
     };
@@ -8870,6 +8906,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
8870 8906
                 __put_user(st.st_atime, &target_st->target_st_atime);
8871 8907
                 __put_user(st.st_mtime, &target_st->target_st_mtime);
8872 8908
                 __put_user(st.st_ctime, &target_st->target_st_ctime);
8909
+#if (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700) && \
8910
+    defined(TARGET_STAT_HAVE_NSEC)
8911
+                __put_user(st.st_atim.tv_nsec,
8912
+                           &target_st->target_st_atime_nsec);
8913
+                __put_user(st.st_mtim.tv_nsec,
8914
+                           &target_st->target_st_mtime_nsec);
8915
+                __put_user(st.st_ctim.tv_nsec,
8916
+                           &target_st->target_st_ctime_nsec);
8917
+#endif
8873 8918
                 unlock_user_struct(target_st, arg2, 1);
8874 8919
             }
8875 8920
         }

+ 38
- 19
linux-user/syscall_defs.h View File

@@ -737,13 +737,17 @@ struct target_pollfd {
737 737
 #define TARGET_KDSETLED        0x4B32	/* set led state [lights, not flags] */
738 738
 #define TARGET_KDSIGACCEPT     0x4B4E
739 739
 
740
-#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SH4)
740
+#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SH4) ||    \
741
+       defined(TARGET_XTENSA)
741 742
 #define TARGET_SIOCATMARK      TARGET_IOR('s', 7, int)
743
+#define TARGET_SIOCSPGRP       TARGET_IOW('s', 8, pid_t)
742 744
 #define TARGET_SIOCGPGRP       TARGET_IOR('s', 9, pid_t)
743 745
 #else
744 746
 #define TARGET_SIOCATMARK      0x8905
747
+#define TARGET_SIOCSPGRP       0x8902
745 748
 #define TARGET_SIOCGPGRP       0x8904
746 749
 #endif
750
+
747 751
 #define TARGET_SIOCGSTAMP      0x8906          /* Get stamp (timeval) */
748 752
 #define TARGET_SIOCGSTAMPNS    0x8907          /* Get stamp (timespec) */
749 753
 
@@ -778,6 +782,8 @@ struct target_pollfd {
778 782
 #define TARGET_SIOCADDMULTI    0x8931          /* Multicast address lists      */
779 783
 #define TARGET_SIOCDELMULTI    0x8932
780 784
 #define TARGET_SIOCGIFINDEX    0x8933
785
+#define TARGET_SIOCSIFPFLAGS   0x8934          /* set extended flags          */
786
+#define TARGET_SIOCGIFPFLAGS   0x8935          /* get extended flags          */
781 787
 
782 788
 /* Bridging control calls */
783 789
 #define TARGET_SIOCGIFBR       0x8940          /* Bridging support             */
@@ -1179,6 +1185,7 @@ struct target_winsize {
1179 1185
 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) \
1180 1186
     || (defined(TARGET_ARM) && defined(TARGET_ABI32)) \
1181 1187
     || defined(TARGET_CRIS)
1188
+#define TARGET_STAT_HAVE_NSEC
1182 1189
 struct target_stat {
1183 1190
 	unsigned short st_dev;
1184 1191
 	unsigned short __pad1;
@@ -1193,11 +1200,11 @@ struct target_stat {
1193 1200
 	abi_ulong  st_blksize;
1194 1201
 	abi_ulong  st_blocks;
1195 1202
 	abi_ulong  target_st_atime;
1196
-	abi_ulong  __unused1;
1203
+	abi_ulong  target_st_atime_nsec;
1197 1204
 	abi_ulong  target_st_mtime;
1198
-	abi_ulong  __unused2;
1205
+	abi_ulong  target_st_mtime_nsec;
1199 1206
 	abi_ulong  target_st_ctime;
1200
-	abi_ulong  __unused3;
1207
+	abi_ulong  target_st_ctime_nsec;
1201 1208
 	abi_ulong  __unused4;
1202 1209
 	abi_ulong  __unused5;
1203 1210
 };
@@ -1229,13 +1236,13 @@ struct target_stat64 {
1229 1236
 	abi_ulong	__pad4;		/* future possible st_blocks high bits */
1230 1237
 
1231 1238
 	abi_ulong	target_st_atime;
1232
-	abi_ulong	__pad5;
1239
+	abi_ulong	target_st_atime_nsec;
1233 1240
 
1234 1241
 	abi_ulong	target_st_mtime;
1235
-	abi_ulong	__pad6;
1242
+	abi_ulong	target_st_mtime_nsec;
1236 1243
 
1237 1244
 	abi_ulong	target_st_ctime;
1238
-	abi_ulong	__pad7;		/* will be high 32 bits of ctime someday */
1245
+	abi_ulong	target_st_ctime_nsec;
1239 1246
 
1240 1247
 	unsigned long long	st_ino;
1241 1248
 } QEMU_PACKED;
@@ -1314,19 +1321,20 @@ struct target_stat64 {
1314 1321
 	unsigned int	st_blocks;
1315 1322
 
1316 1323
 	abi_ulong	target_st_atime;
1317
-	abi_ulong	__unused1;
1324
+	abi_ulong	target_st_atime_nsec;
1318 1325
 
1319 1326
 	abi_ulong	target_st_mtime;
1320
-	abi_ulong	__unused2;
1327
+	abi_ulong	target_st_mtime_nsec;
1321 1328
 
1322 1329
 	abi_ulong	target_st_ctime;
1323
-	abi_ulong	__unused3;
1330
+	abi_ulong	target_st_ctime_nsec;
1324 1331
 
1325 1332
 	abi_ulong	__unused4[3];
1326 1333
 };
1327 1334
 
1328 1335
 #elif defined(TARGET_SPARC)
1329 1336
 
1337
+#define TARGET_STAT_HAVE_NSEC
1330 1338
 struct target_stat {
1331 1339
 	unsigned short	st_dev;
1332 1340
 	abi_ulong	st_ino;
@@ -1337,14 +1345,14 @@ struct target_stat {
1337 1345
 	unsigned short	st_rdev;
1338 1346
 	abi_long	st_size;
1339 1347
 	abi_long	target_st_atime;
1340
-	abi_ulong	__unused1;
1348
+	abi_ulong	target_st_atime_nsec;
1341 1349
 	abi_long	target_st_mtime;
1342
-	abi_ulong	__unused2;
1350
+	abi_ulong	target_st_mtime_nsec;
1343 1351
 	abi_long	target_st_ctime;
1344
-	abi_ulong	__unused3;
1352
+	abi_ulong	target_st_ctime_nsec;
1345 1353
 	abi_long	st_blksize;
1346 1354
 	abi_long	st_blocks;
1347
-	abi_ulong	__unused4[2];
1355
+	abi_ulong	__unused1[2];
1348 1356
 };
1349 1357
 
1350 1358
 #define TARGET_HAS_STRUCT_STAT64
@@ -1372,20 +1380,21 @@ struct target_stat64 {
1372 1380
 	unsigned int	st_blocks;
1373 1381
 
1374 1382
 	unsigned int	target_st_atime;
1375
-	unsigned int	__unused1;
1383
+	unsigned int	target_st_atime_nsec;
1376 1384
 
1377 1385
 	unsigned int	target_st_mtime;
1378
-	unsigned int	__unused2;
1386
+	unsigned int	target_st_mtime_nsec;
1379 1387
 
1380 1388
 	unsigned int	target_st_ctime;
1381
-	unsigned int	__unused3;
1389
+	unsigned int	target_st_ctime_nsec;
1382 1390
 
1383
-	unsigned int	__unused4;
1384
-	unsigned int	__unused5;
1391
+	unsigned int	__unused1;
1392
+	unsigned int	__unused2;
1385 1393
 };
1386 1394
 
1387 1395
 #elif defined(TARGET_PPC)
1388 1396
 
1397
+#define TARGET_STAT_HAVE_NSEC
1389 1398
 struct target_stat {
1390 1399
 	abi_ulong st_dev;
1391 1400
 	abi_ulong st_ino;
@@ -1443,6 +1452,7 @@ struct QEMU_PACKED target_stat64 {
1443 1452
 
1444 1453
 #elif defined(TARGET_MICROBLAZE)
1445 1454
 
1455
+#define TARGET_STAT_HAVE_NSEC
1446 1456
 struct target_stat {
1447 1457
 	abi_ulong st_dev;
1448 1458
 	abi_ulong st_ino;
@@ -1558,6 +1568,7 @@ struct target_stat64 {
1558 1568
 
1559 1569
 #elif defined(TARGET_ABI_MIPSN64)
1560 1570
 
1571
+#define TARGET_STAT_HAVE_NSEC
1561 1572
 /* The memory layout is the same as of struct stat64 of the 32-bit kernel.  */
1562 1573
 struct target_stat {
1563 1574
 	unsigned int		st_dev;
@@ -1597,6 +1608,7 @@ struct target_stat {
1597 1608
 
1598 1609
 #elif defined(TARGET_ABI_MIPSN32)
1599 1610
 
1611
+#define TARGET_STAT_HAVE_NSEC
1600 1612
 struct target_stat {
1601 1613
         abi_ulong    st_dev;
1602 1614
         abi_ulong    st_pad0[3]; /* Reserved for st_dev expansion */
@@ -1621,6 +1633,7 @@ struct target_stat {
1621 1633
 
1622 1634
 #elif defined(TARGET_ABI_MIPSO32)
1623 1635
 
1636
+#define TARGET_STAT_HAVE_NSEC
1624 1637
 struct target_stat {
1625 1638
 	unsigned	st_dev;
1626 1639
 	abi_long	st_pad1[3];		/* Reserved for network id */
@@ -1737,6 +1750,7 @@ struct target_stat64 {
1737 1750
 
1738 1751
 #elif defined(TARGET_SH4)
1739 1752
 
1753
+#define TARGET_STAT_HAVE_NSEC
1740 1754
 struct target_stat {
1741 1755
 	abi_ulong  st_dev;
1742 1756
 	abi_ulong  st_ino;
@@ -1796,6 +1810,7 @@ struct QEMU_PACKED target_stat64 {
1796 1810
 };
1797 1811
 
1798 1812
 #elif defined(TARGET_I386) && !defined(TARGET_ABI32)
1813
+#define TARGET_STAT_HAVE_NSEC
1799 1814
 struct target_stat {
1800 1815
 	abi_ulong	st_dev;
1801 1816
 	abi_ulong	st_ino;
@@ -1841,6 +1856,7 @@ struct target_stat {
1841 1856
     abi_ulong  __unused[3];
1842 1857
 };
1843 1858
 #elif defined(TARGET_AARCH64)
1859
+#define TARGET_STAT_HAVE_NSEC
1844 1860
 struct target_stat {
1845 1861
     abi_ulong  st_dev;
1846 1862
     abi_ulong  st_ino;
@@ -1863,6 +1879,7 @@ struct target_stat {
1863 1879
     unsigned int __unused[2];
1864 1880
 };
1865 1881
 #elif defined(TARGET_XTENSA)
1882
+#define TARGET_STAT_HAVE_NSEC
1866 1883
 struct target_stat {
1867 1884
     abi_ulong       st_dev;
1868 1885
     abi_ulong       st_ino;
@@ -1912,6 +1929,7 @@ struct target_stat64  {
1912 1929
 
1913 1930
 /* These are the asm-generic versions of the stat and stat64 structures */
1914 1931
 
1932
+#define TARGET_STAT_HAVE_NSEC
1915 1933
 struct target_stat {
1916 1934
     abi_ulong st_dev;
1917 1935
     abi_ulong st_ino;
@@ -1963,6 +1981,7 @@ struct target_stat64 {
1963 1981
 
1964 1982
 #elif defined(TARGET_HPPA)
1965 1983
 
1984
+#define TARGET_STAT_HAVE_NSEC
1966 1985
 struct target_stat {
1967 1986
     abi_uint   st_dev;
1968 1987
     abi_uint   st_ino;

Loading…
Cancel
Save