forked from gentoo/gentoo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
app-emulation/qemu: maintenacne patches, revbump
* patch for linux-headers-5.2 * apply upstream patch for pc-q35 regression with windows guests Closes: https://bugs.gentoo.org/690418 Closes: https://bugs.gentoo.org/690280 Package-Manager: Portage-2.3.69, Repoman-2.3.16 Signed-off-by: Matthias Maier <[email protected]>
- Loading branch information
Showing
3 changed files
with
1,282 additions
and
0 deletions.
There are no files selected for viewing
334 changes: 334 additions & 0 deletions
334
app-emulation/qemu/files/qemu-4.0.0-linux-headers-5.2.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,334 @@ | ||
From 6d5d5dde9adb5acb32e6b8e3dfbf47fff0f308d2 Mon Sep 17 00:00:00 2001 | ||
From: =?utf8?q?Daniel=20P=2E=20Berrang=C3=A9?= <[email protected]> | ||
Date: Thu, 18 Jul 2019 15:06:41 +0200 | ||
Subject: [PATCH] linux-user: fix to handle variably sized SIOCGSTAMP with new | ||
kernels | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain; charset=utf8 | ||
Content-Transfer-Encoding: 8bit | ||
|
||
The SIOCGSTAMP symbol was previously defined in the | ||
asm-generic/sockios.h header file. QEMU sees that header | ||
indirectly via sys/socket.h | ||
|
||
In linux kernel commit 0768e17073dc527ccd18ed5f96ce85f9985e9115 | ||
the asm-generic/sockios.h header no longer defines SIOCGSTAMP. | ||
Instead it provides only SIOCGSTAMP_OLD, which only uses a | ||
32-bit time_t on 32-bit architectures. | ||
|
||
The linux/sockios.h header then defines SIOCGSTAMP using | ||
either SIOCGSTAMP_OLD or SIOCGSTAMP_NEW as appropriate. If | ||
SIOCGSTAMP_NEW is used, then the tv_sec field is 64-bit even | ||
on 32-bit architectures | ||
|
||
To cope with this we must now convert the old and new type from | ||
the target to the host one. | ||
|
||
Signed-off-by: Daniel P. Berrangé <[email protected]> | ||
Signed-off-by: Laurent Vivier <[email protected]> | ||
Reviewed-by: Arnd Bergmann <[email protected]> | ||
Message-Id: <[email protected]> | ||
Signed-off-by: Laurent Vivier <[email protected]> | ||
--- | ||
linux-user/ioctls.h | 21 ++++++- | ||
linux-user/syscall.c | 140 ++++++++++++++++++++++++++++++++++++--------- | ||
linux-user/syscall_defs.h | 30 +++++++++- | ||
linux-user/syscall_types.h | 6 -- | ||
4 files changed, 159 insertions(+), 38 deletions(-) | ||
|
||
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h | ||
index ae895162..e6a27ad9 100644 | ||
--- a/linux-user/ioctls.h | ||
+++ b/linux-user/ioctls.h | ||
@@ -219,8 +219,25 @@ | ||
IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq))) | ||
IOCTL(SIOCGIWNAME, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq))) | ||
IOCTL(SIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) /* pid_t */ | ||
- IOCTL(SIOCGSTAMP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timeval))) | ||
- IOCTL(SIOCGSTAMPNS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timespec))) | ||
+ | ||
+ /* | ||
+ * We can't use IOCTL_SPECIAL() because it will set | ||
+ * host_cmd to XXX_OLD and XXX_NEW and these macros | ||
+ * are not defined with kernel prior to 5.2. | ||
+ * We must set host_cmd to the same value as in target_cmd | ||
+ * otherwise the consistency check in syscall_init() | ||
+ * will trigger an error. | ||
+ * host_cmd is ignored by the do_ioctl_XXX() helpers. | ||
+ * FIXME: create a macro to define this kind of entry | ||
+ */ | ||
+ { TARGET_SIOCGSTAMP_OLD, TARGET_SIOCGSTAMP_OLD, | ||
+ "SIOCGSTAMP_OLD", IOC_R, do_ioctl_SIOCGSTAMP }, | ||
+ { TARGET_SIOCGSTAMPNS_OLD, TARGET_SIOCGSTAMPNS_OLD, | ||
+ "SIOCGSTAMPNS_OLD", IOC_R, do_ioctl_SIOCGSTAMPNS }, | ||
+ { TARGET_SIOCGSTAMP_NEW, TARGET_SIOCGSTAMP_NEW, | ||
+ "SIOCGSTAMP_NEW", IOC_R, do_ioctl_SIOCGSTAMP }, | ||
+ { TARGET_SIOCGSTAMPNS_NEW, TARGET_SIOCGSTAMPNS_NEW, | ||
+ "SIOCGSTAMPNS_NEW", IOC_R, do_ioctl_SIOCGSTAMPNS }, | ||
|
||
IOCTL(RNDGETENTCNT, IOC_R, MK_PTR(TYPE_INT)) | ||
IOCTL(RNDADDTOENTCNT, IOC_W, MK_PTR(TYPE_INT)) | ||
diff --git a/linux-user/syscall.c b/linux-user/syscall.c | ||
index 96cd4bf8..6df480e1 100644 | ||
--- a/linux-user/syscall.c | ||
+++ b/linux-user/syscall.c | ||
@@ -37,6 +37,7 @@ | ||
#include <sched.h> | ||
#include <sys/timex.h> | ||
#include <sys/socket.h> | ||
+#include <linux/sockios.h> | ||
#include <sys/un.h> | ||
#include <sys/uio.h> | ||
#include <poll.h> | ||
@@ -1139,8 +1140,9 @@ static inline abi_long copy_from_user_timeval(struct timeval *tv, | ||
{ | ||
struct target_timeval *target_tv; | ||
|
||
- if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) | ||
+ if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) { | ||
return -TARGET_EFAULT; | ||
+ } | ||
|
||
__get_user(tv->tv_sec, &target_tv->tv_sec); | ||
__get_user(tv->tv_usec, &target_tv->tv_usec); | ||
@@ -1155,8 +1157,26 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr, | ||
{ | ||
struct target_timeval *target_tv; | ||
|
||
- if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) | ||
+ if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) { | ||
+ return -TARGET_EFAULT; | ||
+ } | ||
+ | ||
+ __put_user(tv->tv_sec, &target_tv->tv_sec); | ||
+ __put_user(tv->tv_usec, &target_tv->tv_usec); | ||
+ | ||
+ unlock_user_struct(target_tv, target_tv_addr, 1); | ||
+ | ||
+ return 0; | ||
+} | ||
+ | ||
+static inline abi_long copy_to_user_timeval64(abi_ulong target_tv_addr, | ||
+ const struct timeval *tv) | ||
+{ | ||
+ struct target__kernel_sock_timeval *target_tv; | ||
+ | ||
+ if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) { | ||
return -TARGET_EFAULT; | ||
+ } | ||
|
||
__put_user(tv->tv_sec, &target_tv->tv_sec); | ||
__put_user(tv->tv_usec, &target_tv->tv_usec); | ||
@@ -1166,6 +1186,48 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr, | ||
return 0; | ||
} | ||
|
||
+static inline abi_long target_to_host_timespec(struct timespec *host_ts, | ||
+ abi_ulong target_addr) | ||
+{ | ||
+ struct target_timespec *target_ts; | ||
+ | ||
+ if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) { | ||
+ return -TARGET_EFAULT; | ||
+ } | ||
+ __get_user(host_ts->tv_sec, &target_ts->tv_sec); | ||
+ __get_user(host_ts->tv_nsec, &target_ts->tv_nsec); | ||
+ unlock_user_struct(target_ts, target_addr, 0); | ||
+ return 0; | ||
+} | ||
+ | ||
+static inline abi_long host_to_target_timespec(abi_ulong target_addr, | ||
+ struct timespec *host_ts) | ||
+{ | ||
+ struct target_timespec *target_ts; | ||
+ | ||
+ if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) { | ||
+ return -TARGET_EFAULT; | ||
+ } | ||
+ __put_user(host_ts->tv_sec, &target_ts->tv_sec); | ||
+ __put_user(host_ts->tv_nsec, &target_ts->tv_nsec); | ||
+ unlock_user_struct(target_ts, target_addr, 1); | ||
+ return 0; | ||
+} | ||
+ | ||
+static inline abi_long host_to_target_timespec64(abi_ulong target_addr, | ||
+ struct timespec *host_ts) | ||
+{ | ||
+ struct target__kernel_timespec *target_ts; | ||
+ | ||
+ if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) { | ||
+ return -TARGET_EFAULT; | ||
+ } | ||
+ __put_user(host_ts->tv_sec, &target_ts->tv_sec); | ||
+ __put_user(host_ts->tv_nsec, &target_ts->tv_nsec); | ||
+ unlock_user_struct(target_ts, target_addr, 1); | ||
+ return 0; | ||
+} | ||
+ | ||
static inline abi_long copy_from_user_timezone(struct timezone *tz, | ||
abi_ulong target_tz_addr) | ||
{ | ||
@@ -4790,6 +4852,54 @@ static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp, | ||
return get_errno(safe_ioctl(fd, ie->host_cmd, sig)); | ||
} | ||
|
||
+static abi_long do_ioctl_SIOCGSTAMP(const IOCTLEntry *ie, uint8_t *buf_temp, | ||
+ int fd, int cmd, abi_long arg) | ||
+{ | ||
+ struct timeval tv; | ||
+ abi_long ret; | ||
+ | ||
+ ret = get_errno(safe_ioctl(fd, SIOCGSTAMP, &tv)); | ||
+ if (is_error(ret)) { | ||
+ return ret; | ||
+ } | ||
+ | ||
+ if (cmd == (int)TARGET_SIOCGSTAMP_OLD) { | ||
+ if (copy_to_user_timeval(arg, &tv)) { | ||
+ return -TARGET_EFAULT; | ||
+ } | ||
+ } else { | ||
+ if (copy_to_user_timeval64(arg, &tv)) { | ||
+ return -TARGET_EFAULT; | ||
+ } | ||
+ } | ||
+ | ||
+ return ret; | ||
+} | ||
+ | ||
+static abi_long do_ioctl_SIOCGSTAMPNS(const IOCTLEntry *ie, uint8_t *buf_temp, | ||
+ int fd, int cmd, abi_long arg) | ||
+{ | ||
+ struct timespec ts; | ||
+ abi_long ret; | ||
+ | ||
+ ret = get_errno(safe_ioctl(fd, SIOCGSTAMPNS, &ts)); | ||
+ if (is_error(ret)) { | ||
+ return ret; | ||
+ } | ||
+ | ||
+ if (cmd == (int)TARGET_SIOCGSTAMPNS_OLD) { | ||
+ if (host_to_target_timespec(arg, &ts)) { | ||
+ return -TARGET_EFAULT; | ||
+ } | ||
+ } else{ | ||
+ if (host_to_target_timespec64(arg, &ts)) { | ||
+ return -TARGET_EFAULT; | ||
+ } | ||
+ } | ||
+ | ||
+ return ret; | ||
+} | ||
+ | ||
#ifdef TIOCGPTPEER | ||
static abi_long do_ioctl_tiocgptpeer(const IOCTLEntry *ie, uint8_t *buf_temp, | ||
int fd, int cmd, abi_long arg) | ||
@@ -6160,32 +6270,6 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1, | ||
} | ||
#endif | ||
|
||
-static inline abi_long target_to_host_timespec(struct timespec *host_ts, | ||
- abi_ulong target_addr) | ||
-{ | ||
- struct target_timespec *target_ts; | ||
- | ||
- if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) | ||
- return -TARGET_EFAULT; | ||
- __get_user(host_ts->tv_sec, &target_ts->tv_sec); | ||
- __get_user(host_ts->tv_nsec, &target_ts->tv_nsec); | ||
- unlock_user_struct(target_ts, target_addr, 0); | ||
- return 0; | ||
-} | ||
- | ||
-static inline abi_long host_to_target_timespec(abi_ulong target_addr, | ||
- struct timespec *host_ts) | ||
-{ | ||
- struct target_timespec *target_ts; | ||
- | ||
- if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) | ||
- return -TARGET_EFAULT; | ||
- __put_user(host_ts->tv_sec, &target_ts->tv_sec); | ||
- __put_user(host_ts->tv_nsec, &target_ts->tv_nsec); | ||
- unlock_user_struct(target_ts, target_addr, 1); | ||
- return 0; | ||
-} | ||
- | ||
static inline abi_long target_to_host_itimerspec(struct itimerspec *host_itspec, | ||
abi_ulong target_addr) | ||
{ | ||
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h | ||
index 12c84071..cfb3eeec 100644 | ||
--- a/linux-user/syscall_defs.h | ||
+++ b/linux-user/syscall_defs.h | ||
@@ -208,16 +208,34 @@ struct target_linger { | ||
abi_int l_linger; /* How long to linger for */ | ||
}; | ||
|
||
+#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) | ||
+struct target_timeval { | ||
+ abi_long tv_sec; | ||
+ abi_int tv_usec; | ||
+}; | ||
+#define target__kernel_sock_timeval target_timeval | ||
+#else | ||
struct target_timeval { | ||
abi_long tv_sec; | ||
abi_long tv_usec; | ||
}; | ||
|
||
+struct target__kernel_sock_timeval { | ||
+ abi_llong tv_sec; | ||
+ abi_llong tv_usec; | ||
+}; | ||
+#endif | ||
+ | ||
struct target_timespec { | ||
abi_long tv_sec; | ||
abi_long tv_nsec; | ||
}; | ||
|
||
+struct target__kernel_timespec { | ||
+ abi_llong tv_sec; | ||
+ abi_llong tv_nsec; | ||
+}; | ||
+ | ||
struct target_timezone { | ||
abi_int tz_minuteswest; | ||
abi_int tz_dsttime; | ||
@@ -743,8 +761,17 @@ struct target_pollfd { | ||
#define TARGET_SIOCATMARK 0x8905 | ||
#define TARGET_SIOCGPGRP 0x8904 | ||
#endif | ||
-#define TARGET_SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ | ||
-#define TARGET_SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ | ||
+ | ||
+#if defined(TARGET_SH4) | ||
+#define TARGET_SIOCGSTAMP_OLD TARGET_IOR('s', 100, struct target_timeval) | ||
+#define TARGET_SIOCGSTAMPNS_OLD TARGET_IOR('s', 101, struct target_timespec) | ||
+#else | ||
+#define TARGET_SIOCGSTAMP_OLD 0x8906 | ||
+#define TARGET_SIOCGSTAMPNS_OLD 0x8907 | ||
+#endif | ||
+ | ||
+#define TARGET_SIOCGSTAMP_NEW TARGET_IOR(0x89, 0x06, abi_llong[2]) | ||
+#define TARGET_SIOCGSTAMPNS_NEW TARGET_IOR(0x89, 0x07, abi_llong[2]) | ||
|
||
/* Networking ioctls */ | ||
#define TARGET_SIOCADDRT 0x890B /* add routing table entry */ | ||
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h | ||
index b98a23b0..4e369838 100644 | ||
--- a/linux-user/syscall_types.h | ||
+++ b/linux-user/syscall_types.h | ||
@@ -14,12 +14,6 @@ STRUCT(serial_icounter_struct, | ||
STRUCT(sockaddr, | ||
TYPE_SHORT, MK_ARRAY(TYPE_CHAR, 14)) | ||
|
||
-STRUCT(timeval, | ||
- MK_ARRAY(TYPE_LONG, 2)) | ||
- | ||
-STRUCT(timespec, | ||
- MK_ARRAY(TYPE_LONG, 2)) | ||
- | ||
STRUCT(rtentry, | ||
TYPE_ULONG, MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), | ||
TYPE_SHORT, TYPE_SHORT, TYPE_ULONG, TYPE_PTRVOID, TYPE_SHORT, TYPE_PTRVOID, |
Oops, something went wrong.