137 lines
4.2 KiB
Diff
137 lines
4.2 KiB
Diff
|
From 2cca53754fbaf3902399ab5a96e8790d0bd27040 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..a49552b 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
|
|||
|
|