qemu/0047-linux-user-add-struct-old_dev_t-compat.patch

137 lines
4.2 KiB
Diff

From 79df307311156580da72aff94e73ad54c73bc4e7 Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Tue, 31 Jan 2012 19:44:41 +0100
Subject: [PATCH] linux-user: add struct old_dev_t compat
The compat LOOP_SET_STATUS ioctl uses struct old_dev_t in its passed
struct. That variable type is vastly different between different
architectures. Implement wrapping around it so we can use it.
This fixes running arm kpartx on an x86_64 host for me.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
linux-user/syscall_types.h | 4 ++--
thunk.c | 28 ++++++++++++++++++++++++++++
thunk.h | 28 ++++++++++++++++++++++++++++
3 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index dea520e..ad2ee7e 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -88,9 +88,9 @@ STRUCT(mixer_info,
/* loop device ioctls */
STRUCT(loop_info,
TYPE_INT, /* lo_number */
- TYPE_SHORT, /* lo_device */
+ TYPE_OLDDEVT, /* lo_device */
TYPE_ULONG, /* lo_inode */
- TYPE_SHORT, /* lo_rdevice */
+ TYPE_OLDDEVT, /* lo_rdevice */
TYPE_INT, /* lo_offset */
TYPE_INT, /* lo_encrypt_type */
TYPE_INT, /* lo_encrypt_key_size */
diff --git a/thunk.c b/thunk.c
index 34bc7d1..bf43985 100644
--- a/thunk.c
+++ b/thunk.c
@@ -47,6 +47,7 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr)
case TYPE_LONG:
case TYPE_ULONG:
case TYPE_PTRVOID:
+ case TYPE_OLDDEVT:
return type_ptr;
case TYPE_PTR:
return thunk_type_next_ptr(type_ptr);
@@ -209,6 +210,33 @@ const argtype *thunk_convert(void *dst, const void *src,
#else
#warning unsupported conversion
#endif
+ case TYPE_OLDDEVT:
+ {
+ uint64_t val = 0;
+ switch (thunk_type_size(type_ptr - 1, !to_host)) {
+ case 2:
+ val = *(uint16_t *)src;
+ break;
+ case 4:
+ val = *(uint32_t *)src;
+ break;
+ case 8:
+ val = *(uint64_t *)src;
+ break;
+ }
+ switch (thunk_type_size(type_ptr - 1, to_host)) {
+ case 2:
+ *(uint16_t *)dst = tswap16(val);
+ break;
+ case 4:
+ *(uint32_t *)dst = tswap32(val);
+ break;
+ case 8:
+ *(uint64_t *)dst = tswap64(val);
+ break;
+ }
+ break;
+ }
case TYPE_ARRAY:
{
int array_length, i, dst_size, src_size;
diff --git a/thunk.h b/thunk.h
index 55890f3..ed65121 100644
--- a/thunk.h
+++ b/thunk.h
@@ -38,6 +38,7 @@ typedef enum argtype {
TYPE_ARRAY,
TYPE_STRUCT,
TYPE_INTBITFIELD,
+ TYPE_OLDDEVT,
} argtype;
#define MK_PTR(type) TYPE_PTR, type
@@ -106,6 +107,31 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host)
return TARGET_ABI_BITS / 8;
}
break;
+ case TYPE_OLDDEVT:
+ if (is_host) {
+#if defined(HOST_X86_64)
+ return 8;
+#elif defined(HOST_ALPHA) || defined(HOST_IA64) || defined(HOST_MIPS) || \
+ defined(HOST_PARISC) || defined(HOST_SPARC64)
+ return 4;
+#elif defined(HOST_PPC)
+ return HOST_LONG_SIZE;
+#else
+ return 2;
+#endif
+ } else {
+#if defined(TARGET_X86_64)
+ return 8;
+#elif defined(TARGET_ALPHA) || defined(TARGET_IA64) || defined(TARGET_MIPS) || \
+ defined(TARGET_PARISC) || defined(TARGET_SPARC64)
+ return 4;
+#elif defined(TARGET_PPC)
+ return TARGET_ABI_BITS / 8;
+#else
+ return 2;
+#endif
+ }
+ break;
case TYPE_ARRAY:
size = type_ptr[1];
return size * thunk_type_size_array(type_ptr + 2, is_host);
@@ -144,6 +170,8 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host)
return TARGET_ABI_BITS / 8;
}
break;
+ case TYPE_OLDDEVT:
+ return thunk_type_size(type_ptr, is_host);
case TYPE_ARRAY:
return thunk_type_align_array(type_ptr + 2, is_host);
case TYPE_STRUCT:
--
1.6.0.2