* [Qemu-devel] pwrite64 error because of argument position
@ 2012-09-30 18:50 Alex Barcelo
2012-10-01 11:52 ` Alexander Graf
0 siblings, 1 reply; 4+ messages in thread
From: Alex Barcelo @ 2012-09-30 18:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Riku Voipio, Alexander Graf
This error may be a PPC specific problem, but I don't have another
environment where I can test it (i386 doesn't seem to use pwrite64),
so I ask for a bit of help/check.
I am in a 32bit linux testing the qemu-ppc.
My test program:
// -------------------------------
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main (void) {
int fd, len;
char* asd = "This is a random test";
char asd2[20];
fd = open ("./test.pwrite", O_RDWR | O_CREAT);
printf ( "fd: %d\n", fd);
pwrite ( fd, asd, 15, 0 );
pwrite ( fd, asd+5, 6, 10);
pwrite ( fd, asd, 4, 30);
len = pread ( fd, asd2, 5, 5);
asd2[len]='\0';
printf ( "Read %d bytes: %s", len, asd2);
// This is to force two int arguments for 64bit
//len = pread ( fd, asd2, -1, -1);
close(fd);
return 0;
}
// -------------------------------
Then I do
$ powerpc-linux-gnu-gcc -g --static -o pwrite-alien pwrite-test.c
and when I launch a qemu-ppc to test, it should be (on the file)
This is a is a rThis
instead I get:
This rs a randorThis
and if I print some debug information inside pwrite64 and pread64 I see:
syscall: pwrite arg_i: 3 268909324 15 0 0 0 0 0
syscall: pwrite arg_i: 3 268909329 6 0 0 10 0 0
syscall: pwrite arg_i: 3 268909324 4 0 0 30 0 0
syscall: pread arg_i: 3 1082133156 5 0 0 5 0 0
(those are arg1, arg2, arg3, arg4, arg5, arg6 and the unused arg7 and arg8)
As can be seen, arg4 is not used, and the line
ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
should be, in my case
ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg5, arg6)));
With this changes, the qemu "Works For Me (TM)".
So, anybody can confirm it or (if it is indeed my problem) can give me
some pointers? I will not post this as a patch until I understand the
problem... and first step is making sure that it really is a qemu
problem. And not my toolchain or something random.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] pwrite64 error because of argument position
2012-09-30 18:50 [Qemu-devel] pwrite64 error because of argument position Alex Barcelo
@ 2012-10-01 11:52 ` Alexander Graf
2012-10-01 16:57 ` Alex Barcelo
0 siblings, 1 reply; 4+ messages in thread
From: Alexander Graf @ 2012-10-01 11:52 UTC (permalink / raw)
To: Alex Barcelo; +Cc: Peter Maydell, Riku Voipio, qemu-devel qemu-devel
On 30.09.2012, at 20:50, Alex Barcelo wrote:
> This error may be a PPC specific problem, but I don't have another
> environment where I can test it (i386 doesn't seem to use pwrite64),
> so I ask for a bit of help/check.
>
> I am in a 32bit linux testing the qemu-ppc.
>
> My test program:
>
> // -------------------------------
> #include <unistd.h>
> #include <stdio.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <fcntl.h>
>
> int main (void) {
> int fd, len;
>
> char* asd = "This is a random test";
> char asd2[20];
>
> fd = open ("./test.pwrite", O_RDWR | O_CREAT);
>
> printf ( "fd: %d\n", fd);
> pwrite ( fd, asd, 15, 0 );
> pwrite ( fd, asd+5, 6, 10);
> pwrite ( fd, asd, 4, 30);
>
> len = pread ( fd, asd2, 5, 5);
> asd2[len]='\0';
> printf ( "Read %d bytes: %s", len, asd2);
>
> // This is to force two int arguments for 64bit
> //len = pread ( fd, asd2, -1, -1);
> close(fd);
> return 0;
> }
> // -------------------------------
>
> Then I do
> $ powerpc-linux-gnu-gcc -g --static -o pwrite-alien pwrite-test.c
>
> and when I launch a qemu-ppc to test, it should be (on the file)
> This is a is a rThis
>
> instead I get:
> This rs a randorThis
>
> and if I print some debug information inside pwrite64 and pread64 I see:
> syscall: pwrite arg_i: 3 268909324 15 0 0 0 0 0
> syscall: pwrite arg_i: 3 268909329 6 0 0 10 0 0
> syscall: pwrite arg_i: 3 268909324 4 0 0 30 0 0
> syscall: pread arg_i: 3 1082133156 5 0 0 5 0 0
> (those are arg1, arg2, arg3, arg4, arg5, arg6 and the unused arg7 and arg8)
>
> As can be seen, arg4 is not used, and the line
> ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
> should be, in my case
> ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg5, arg6)));
>
> With this changes, the qemu "Works For Me (TM)".
>
> So, anybody can confirm it or (if it is indeed my problem) can give me
> some pointers? I will not post this as a patch until I understand the
> problem... and first step is making sure that it really is a qemu
> problem. And not my toolchain or something random.
Running the above code on a real ppc machine (compiled with -m32, running a ppc64 kernel) I get:
00000000 54 68 69 73 20 69 73 20 61 20 69 73 20 61 20 72 |This is a is a r|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 54 68 |..............Th|
00000020 69 73 |is|
as output. Is this the expected result? Running it in qemu-ppc, I get:
00000000 54 68 69 73 20 72 73 20 61 20 72 61 6e 64 6f |This rs a rando|
0000000f
So yes, something looks broken here.
According to arch/powerpc/kernel/sys_ppc32.c, the ppc32 ABI carries 64bit parameters on odd/even pairs:
/*
* long long munging:
* The 32 bit ABI passes long longs in an odd even register pair.
*/
which is almost the same as what ARM or MIPS do and which explains why you see arg5/arg6 (r7/r8) used instead of arg4/arg5 (r6/r7).
Could you please try the below patch?
Alex
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1a38169..e03b3a8 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -587,12 +587,16 @@ extern int setfsgid(int);
extern int setgroups(int, gid_t *);
/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
-#ifdef TARGET_ARM
+#ifdef TARGET_ARM
static inline int regpairs_aligned(void *cpu_env) {
return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
}
#elif defined(TARGET_MIPS)
static inline int regpairs_aligned(void *cpu_env) { return 1; }
+#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
+/* PPC32 expects 64bit parameters to be passed on odd/even pairs of registers
+ which is the same as ARM/MIPS, because we start with r3 as arg1. */
+static inline int regpairs_aligned(void *cpu_env) { return 1; }
#else
static inline int regpairs_aligned(void *cpu_env) { return 0; }
#endif
@@ -7419,12 +7423,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#endif
#ifdef TARGET_NR_pread64
case TARGET_NR_pread64:
+ if (regpairs_aligned(cpu_env)) {
+ arg4 = arg5;
+ arg5 = arg6;
+ }
if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
goto efault;
ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
unlock_user(p, arg2, ret);
break;
case TARGET_NR_pwrite64:
+ if (regpairs_aligned(cpu_env)) {
+ arg4 = arg5;
+ arg5 = arg6;
+ }
if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
goto efault;
ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] pwrite64 error because of argument position
2012-10-01 11:52 ` Alexander Graf
@ 2012-10-01 16:57 ` Alex Barcelo
2012-10-01 16:59 ` Alexander Graf
0 siblings, 1 reply; 4+ messages in thread
From: Alex Barcelo @ 2012-10-01 16:57 UTC (permalink / raw)
To: Alexander Graf; +Cc: Peter Maydell, Riku Voipio, qemu-devel qemu-devel
ok, thank you very much. Now I understand the problem... and I see the
correct way of mending it.
Your patch works for me.
>On Mon, Oct 1, 2012 at 1:52 PM, Alexander Graf <agraf@suse.de> wrote:
>
> On 30.09.2012, at 20:50, Alex Barcelo wrote:
>
>> This error may be a PPC specific problem, but I don't have another
>> environment where I can test it (i386 doesn't seem to use pwrite64),
>> so I ask for a bit of help/check.
>>
>> I am in a 32bit linux testing the qemu-ppc.
>>
>> My test program:
>>
>> // -------------------------------
>> #include <unistd.h>
>> #include <stdio.h>
>> #include <sys/types.h>
>> #include <sys/stat.h>
>> #include <fcntl.h>
>>
>> int main (void) {
>> int fd, len;
>>
>> char* asd = "This is a random test";
>> char asd2[20];
>>
>> fd = open ("./test.pwrite", O_RDWR | O_CREAT);
>>
>> printf ( "fd: %d\n", fd);
>> pwrite ( fd, asd, 15, 0 );
>> pwrite ( fd, asd+5, 6, 10);
>> pwrite ( fd, asd, 4, 30);
>>
>> len = pread ( fd, asd2, 5, 5);
>> asd2[len]='\0';
>> printf ( "Read %d bytes: %s", len, asd2);
>>
>> // This is to force two int arguments for 64bit
>> //len = pread ( fd, asd2, -1, -1);
>> close(fd);
>> return 0;
>> }
>> // -------------------------------
>>
>> Then I do
>> $ powerpc-linux-gnu-gcc -g --static -o pwrite-alien pwrite-test.c
>>
>> and when I launch a qemu-ppc to test, it should be (on the file)
>> This is a is a rThis
>>
>> instead I get:
>> This rs a randorThis
>>
>> and if I print some debug information inside pwrite64 and pread64 I see:
>> syscall: pwrite arg_i: 3 268909324 15 0 0 0 0 0
>> syscall: pwrite arg_i: 3 268909329 6 0 0 10 0 0
>> syscall: pwrite arg_i: 3 268909324 4 0 0 30 0 0
>> syscall: pread arg_i: 3 1082133156 5 0 0 5 0 0
>> (those are arg1, arg2, arg3, arg4, arg5, arg6 and the unused arg7 and arg8)
>>
>> As can be seen, arg4 is not used, and the line
>> ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
>> should be, in my case
>> ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg5, arg6)));
>>
>> With this changes, the qemu "Works For Me (TM)".
>>
>> So, anybody can confirm it or (if it is indeed my problem) can give me
>> some pointers? I will not post this as a patch until I understand the
>> problem... and first step is making sure that it really is a qemu
>> problem. And not my toolchain or something random.
>
> Running the above code on a real ppc machine (compiled with -m32, running a ppc64 kernel) I get:
>
> 00000000 54 68 69 73 20 69 73 20 61 20 69 73 20 61 20 72 |This is a is a r|
> 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 54 68 |..............Th|
> 00000020 69 73 |is|
>
> as output. Is this the expected result? Running it in qemu-ppc, I get:
>
> 00000000 54 68 69 73 20 72 73 20 61 20 72 61 6e 64 6f |This rs a rando|
> 0000000f
>
> So yes, something looks broken here.
>
> According to arch/powerpc/kernel/sys_ppc32.c, the ppc32 ABI carries 64bit parameters on odd/even pairs:
>
> /*
> * long long munging:
> * The 32 bit ABI passes long longs in an odd even register pair.
> */
>
> which is almost the same as what ARM or MIPS do and which explains why you see arg5/arg6 (r7/r8) used instead of arg4/arg5 (r6/r7).
>
> Could you please try the below patch?
>
>
> Alex
>
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 1a38169..e03b3a8 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -587,12 +587,16 @@ extern int setfsgid(int);
> extern int setgroups(int, gid_t *);
>
> /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
> -#ifdef TARGET_ARM
> +#ifdef TARGET_ARM
> static inline int regpairs_aligned(void *cpu_env) {
> return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
> }
> #elif defined(TARGET_MIPS)
> static inline int regpairs_aligned(void *cpu_env) { return 1; }
> +#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
> +/* PPC32 expects 64bit parameters to be passed on odd/even pairs of registers
> + which is the same as ARM/MIPS, because we start with r3 as arg1. */
> +static inline int regpairs_aligned(void *cpu_env) { return 1; }
> #else
> static inline int regpairs_aligned(void *cpu_env) { return 0; }
> #endif
> @@ -7419,12 +7423,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
> #endif
> #ifdef TARGET_NR_pread64
> case TARGET_NR_pread64:
> + if (regpairs_aligned(cpu_env)) {
> + arg4 = arg5;
> + arg5 = arg6;
> + }
> if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
> goto efault;
> ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
> unlock_user(p, arg2, ret);
> break;
> case TARGET_NR_pwrite64:
> + if (regpairs_aligned(cpu_env)) {
> + arg4 = arg5;
> + arg5 = arg6;
> + }
> if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
> goto efault;
> ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] pwrite64 error because of argument position
2012-10-01 16:57 ` Alex Barcelo
@ 2012-10-01 16:59 ` Alexander Graf
0 siblings, 0 replies; 4+ messages in thread
From: Alexander Graf @ 2012-10-01 16:59 UTC (permalink / raw)
To: Alex Barcelo; +Cc: Peter Maydell, Riku Voipio, qemu-devel qemu-devel
On 01.10.2012, at 18:57, Alex Barcelo wrote:
> ok, thank you very much. Now I understand the problem... and I see the
> correct way of mending it.
>
> Your patch works for me.
Awesome. Could you please put your Tested-by tag below the patches I sent to the ML earlier to day then? :)
Alex
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-10-01 16:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-30 18:50 [Qemu-devel] pwrite64 error because of argument position Alex Barcelo
2012-10-01 11:52 ` Alexander Graf
2012-10-01 16:57 ` Alex Barcelo
2012-10-01 16:59 ` Alexander Graf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).