qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/2] target-arm: Fix SYS_HEAPINFO for 64-bit guests
@ 2016-06-24 15:49 Peter Maydell
  2016-06-24 15:49 ` [Qemu-devel] [PATCH 1/2] linux-user: Make semihosting heap/stack fields abi_ulongs Peter Maydell
  2016-06-24 15:49 ` [Qemu-devel] [PATCH 2/2] target-arm/arm-semi.c: Fix SYS_HEAPINFO for 64-bit guests Peter Maydell
  0 siblings, 2 replies; 6+ messages in thread
From: Peter Maydell @ 2016-06-24 15:49 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Tsung-Han Lin, Laurent Desnogues

These patches fix bugs in the ARM semihosting SYS_HEAPINFO
syscall for 64-bit guests:
 * the fields in linux-user's TaskState should be abi_ulong,
   not uint32_t, since they're guest addresses
 * the SYS_HEAPINFO implementation needs to write its return
   data struct using fields of the right width

The recent patch from Tsung-Han Lin ("target-arm: fix semihosting ram
base issue") addressed this issue in passing, but these patches
take a slightly different approach:
 * factor out the "write fields back" code to reduce duplication
   between the various (32,64) x (user,system) cases
 * use put_user*() rather than tswap and direct write, to
   avoid potential issues with the guest handing us a
   misaligned pointer

thanks
-- PMM


Peter Maydell (2):
  linux-user: Make semihosting heap/stack fields abi_ulongs
  target-arm/arm-semi.c: Fix SYS_HEAPINFO for 64-bit guests

 linux-user/qemu.h     |  6 +++---
 target-arm/arm-semi.c | 47 ++++++++++++++++++++++++++---------------------
 2 files changed, 29 insertions(+), 24 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH 1/2] linux-user: Make semihosting heap/stack fields abi_ulongs
  2016-06-24 15:49 [Qemu-devel] [PATCH 0/2] target-arm: Fix SYS_HEAPINFO for 64-bit guests Peter Maydell
@ 2016-06-24 15:49 ` Peter Maydell
  2016-06-24 15:58   ` Laurent Desnogues
  2016-06-24 15:49 ` [Qemu-devel] [PATCH 2/2] target-arm/arm-semi.c: Fix SYS_HEAPINFO for 64-bit guests Peter Maydell
  1 sibling, 1 reply; 6+ messages in thread
From: Peter Maydell @ 2016-06-24 15:49 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Tsung-Han Lin, Laurent Desnogues

The fields in the TaskState heap_base, heap_limit and stack_base
are all guest addresses (representing the locations of the heap
and stack for the guest binary), so they should be abi_ulong
rather than uint32_t. (This only in practice affects ARM AArch64
since all the other semihosting implementations are 32-bit.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 linux-user/qemu.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 56f29c3..1b3b03b 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -111,10 +111,10 @@ typedef struct TaskState {
 #endif
 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
     /* Extra fields for semihosted binaries.  */
-    uint32_t heap_base;
-    uint32_t heap_limit;
+    abi_ulong heap_base;
+    abi_ulong heap_limit;
 #endif
-    uint32_t stack_base;
+    abi_ulong stack_base;
     int used; /* non zero if used */
     struct image_info *info;
     struct linux_binprm *bprm;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH 2/2] target-arm/arm-semi.c: Fix SYS_HEAPINFO for 64-bit guests
  2016-06-24 15:49 [Qemu-devel] [PATCH 0/2] target-arm: Fix SYS_HEAPINFO for 64-bit guests Peter Maydell
  2016-06-24 15:49 ` [Qemu-devel] [PATCH 1/2] linux-user: Make semihosting heap/stack fields abi_ulongs Peter Maydell
@ 2016-06-24 15:49 ` Peter Maydell
  2016-06-24 16:09   ` Laurent Desnogues
  1 sibling, 1 reply; 6+ messages in thread
From: Peter Maydell @ 2016-06-24 15:49 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: patches, Tsung-Han Lin, Laurent Desnogues

SYS_HEAPINFO is one of the few semihosting calls which has to write
values back into a parameter block in memory.  When we added
support for 64-bit semihosting we updated the code which reads from
the parameter block to read 64-bit words but forgot to change the
code that writes back into the block. Update it to treat the
block as a set of words of the appropriate width for the guest.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/arm-semi.c | 47 ++++++++++++++++++++++++++---------------------
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index 8be0645..d50726f 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -564,8 +564,10 @@ target_ulong do_arm_semihosting(CPUARMState *env)
         }
     case TARGET_SYS_HEAPINFO:
         {
-            uint32_t *ptr;
+            target_ulong retvals[4];
             uint32_t limit;
+            int i;
+
             GET_ARG(0);
 
 #ifdef CONFIG_USER_ONLY
@@ -587,30 +589,33 @@ target_ulong do_arm_semihosting(CPUARMState *env)
                 ts->heap_limit = limit;
             }
 
-            ptr = lock_user(VERIFY_WRITE, arg0, 16, 0);
-            if (!ptr) {
-                /* FIXME - should this error code be -TARGET_EFAULT ? */
-                return (uint32_t)-1;
-            }
-            ptr[0] = tswap32(ts->heap_base);
-            ptr[1] = tswap32(ts->heap_limit);
-            ptr[2] = tswap32(ts->stack_base);
-            ptr[3] = tswap32(0); /* Stack limit.  */
-            unlock_user(ptr, arg0, 16);
+            retvals[0] = ts->heap_base;
+            retvals[1] = ts->heap_limit;
+            retvals[2] = ts->stack_base;
+            retvals[3] = 0; /* Stack limit.  */
 #else
             limit = ram_size;
-            ptr = lock_user(VERIFY_WRITE, arg0, 16, 0);
-            if (!ptr) {
-                /* FIXME - should this error code be -TARGET_EFAULT ? */
-                return (uint32_t)-1;
-            }
             /* TODO: Make this use the limit of the loaded application.  */
-            ptr[0] = tswap32(limit / 2);
-            ptr[1] = tswap32(limit);
-            ptr[2] = tswap32(limit); /* Stack base */
-            ptr[3] = tswap32(0); /* Stack limit.  */
-            unlock_user(ptr, arg0, 16);
+            retvals[0] = limit / 2;
+            retvals[1] = limit;
+            retvals[2] = limit; /* Stack base */
+            retvals[3] = 0; /* Stack limit.  */
 #endif
+
+            for (i = 0; i < ARRAY_SIZE(retvals); i++) {
+                bool fail;
+
+                if (is_a64(env)) {
+                    fail = put_user_u64(retvals[i], arg0 + i * 8);
+                } else {
+                    fail = put_user_u32(retvals[i], arg0 + i * 4);
+                }
+
+                if (fail) {
+                    /* Couldn't write back to argument block */
+                    return -1;
+                }
+            }
             return 0;
         }
     case TARGET_SYS_EXIT:
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH 1/2] linux-user: Make semihosting heap/stack fields abi_ulongs
  2016-06-24 15:49 ` [Qemu-devel] [PATCH 1/2] linux-user: Make semihosting heap/stack fields abi_ulongs Peter Maydell
@ 2016-06-24 15:58   ` Laurent Desnogues
  0 siblings, 0 replies; 6+ messages in thread
From: Laurent Desnogues @ 2016-06-24 15:58 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-arm, qemu-devel@nongnu.org, Patch Tracking, Tsung-Han Lin

On Fri, Jun 24, 2016 at 5:49 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> The fields in the TaskState heap_base, heap_limit and stack_base
> are all guest addresses (representing the locations of the heap
> and stack for the guest binary), so they should be abi_ulong
> rather than uint32_t. (This only in practice affects ARM AArch64
> since all the other semihosting implementations are 32-bit.)
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>

Thanks,

Laurent

> ---
>  linux-user/qemu.h | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index 56f29c3..1b3b03b 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -111,10 +111,10 @@ typedef struct TaskState {
>  #endif
>  #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
>      /* Extra fields for semihosted binaries.  */
> -    uint32_t heap_base;
> -    uint32_t heap_limit;
> +    abi_ulong heap_base;
> +    abi_ulong heap_limit;
>  #endif
> -    uint32_t stack_base;
> +    abi_ulong stack_base;
>      int used; /* non zero if used */
>      struct image_info *info;
>      struct linux_binprm *bprm;
> --
> 1.9.1
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH 2/2] target-arm/arm-semi.c: Fix SYS_HEAPINFO for 64-bit guests
  2016-06-24 15:49 ` [Qemu-devel] [PATCH 2/2] target-arm/arm-semi.c: Fix SYS_HEAPINFO for 64-bit guests Peter Maydell
@ 2016-06-24 16:09   ` Laurent Desnogues
  2016-06-24 16:39     ` Peter Maydell
  0 siblings, 1 reply; 6+ messages in thread
From: Laurent Desnogues @ 2016-06-24 16:09 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-arm, qemu-devel@nongnu.org, Patch Tracking, Tsung-Han Lin

On Fri, Jun 24, 2016 at 5:49 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> SYS_HEAPINFO is one of the few semihosting calls which has to write
> values back into a parameter block in memory.  When we added
> support for 64-bit semihosting we updated the code which reads from
> the parameter block to read 64-bit words but forgot to change the
> code that writes back into the block. Update it to treat the
> block as a set of words of the appropriate width for the guest.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/arm-semi.c | 47 ++++++++++++++++++++++++++---------------------
>  1 file changed, 26 insertions(+), 21 deletions(-)
>
> diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
> index 8be0645..d50726f 100644
> --- a/target-arm/arm-semi.c
> +++ b/target-arm/arm-semi.c
> @@ -564,8 +564,10 @@ target_ulong do_arm_semihosting(CPUARMState *env)
>          }
>      case TARGET_SYS_HEAPINFO:
>          {
> -            uint32_t *ptr;
> +            target_ulong retvals[4];
>              uint32_t limit;

I think limit should also be converted to target_ulong.

Thanks,

Laurent

> +            int i;
> +
>              GET_ARG(0);
>
>  #ifdef CONFIG_USER_ONLY
> @@ -587,30 +589,33 @@ target_ulong do_arm_semihosting(CPUARMState *env)
>                  ts->heap_limit = limit;
>              }
>
> -            ptr = lock_user(VERIFY_WRITE, arg0, 16, 0);
> -            if (!ptr) {
> -                /* FIXME - should this error code be -TARGET_EFAULT ? */
> -                return (uint32_t)-1;
> -            }
> -            ptr[0] = tswap32(ts->heap_base);
> -            ptr[1] = tswap32(ts->heap_limit);
> -            ptr[2] = tswap32(ts->stack_base);
> -            ptr[3] = tswap32(0); /* Stack limit.  */
> -            unlock_user(ptr, arg0, 16);
> +            retvals[0] = ts->heap_base;
> +            retvals[1] = ts->heap_limit;
> +            retvals[2] = ts->stack_base;
> +            retvals[3] = 0; /* Stack limit.  */
>  #else
>              limit = ram_size;
> -            ptr = lock_user(VERIFY_WRITE, arg0, 16, 0);
> -            if (!ptr) {
> -                /* FIXME - should this error code be -TARGET_EFAULT ? */
> -                return (uint32_t)-1;
> -            }
>              /* TODO: Make this use the limit of the loaded application.  */
> -            ptr[0] = tswap32(limit / 2);
> -            ptr[1] = tswap32(limit);
> -            ptr[2] = tswap32(limit); /* Stack base */
> -            ptr[3] = tswap32(0); /* Stack limit.  */
> -            unlock_user(ptr, arg0, 16);
> +            retvals[0] = limit / 2;
> +            retvals[1] = limit;
> +            retvals[2] = limit; /* Stack base */
> +            retvals[3] = 0; /* Stack limit.  */
>  #endif
> +
> +            for (i = 0; i < ARRAY_SIZE(retvals); i++) {
> +                bool fail;
> +
> +                if (is_a64(env)) {
> +                    fail = put_user_u64(retvals[i], arg0 + i * 8);
> +                } else {
> +                    fail = put_user_u32(retvals[i], arg0 + i * 4);
> +                }
> +
> +                if (fail) {
> +                    /* Couldn't write back to argument block */
> +                    return -1;
> +                }
> +            }
>              return 0;
>          }
>      case TARGET_SYS_EXIT:
> --
> 1.9.1
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH 2/2] target-arm/arm-semi.c: Fix SYS_HEAPINFO for 64-bit guests
  2016-06-24 16:09   ` Laurent Desnogues
@ 2016-06-24 16:39     ` Peter Maydell
  0 siblings, 0 replies; 6+ messages in thread
From: Peter Maydell @ 2016-06-24 16:39 UTC (permalink / raw)
  To: Laurent Desnogues
  Cc: qemu-arm, qemu-devel@nongnu.org, Patch Tracking, Tsung-Han Lin

On 24 June 2016 at 17:09, Laurent Desnogues <laurent.desnogues@gmail.com> wrote:
> On Fri, Jun 24, 2016 at 5:49 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> SYS_HEAPINFO is one of the few semihosting calls which has to write
>> values back into a parameter block in memory.  When we added
>> support for 64-bit semihosting we updated the code which reads from
>> the parameter block to read 64-bit words but forgot to change the
>> code that writes back into the block. Update it to treat the
>> block as a set of words of the appropriate width for the guest.
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>  target-arm/arm-semi.c | 47 ++++++++++++++++++++++++++---------------------
>>  1 file changed, 26 insertions(+), 21 deletions(-)
>>
>> diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
>> index 8be0645..d50726f 100644
>> --- a/target-arm/arm-semi.c
>> +++ b/target-arm/arm-semi.c
>> @@ -564,8 +564,10 @@ target_ulong do_arm_semihosting(CPUARMState *env)
>>          }
>>      case TARGET_SYS_HEAPINFO:
>>          {
>> -            uint32_t *ptr;
>> +            target_ulong retvals[4];
>>              uint32_t limit;
>
> I think limit should also be converted to target_ulong.

Yes, it should.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-06-24 16:40 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-24 15:49 [Qemu-devel] [PATCH 0/2] target-arm: Fix SYS_HEAPINFO for 64-bit guests Peter Maydell
2016-06-24 15:49 ` [Qemu-devel] [PATCH 1/2] linux-user: Make semihosting heap/stack fields abi_ulongs Peter Maydell
2016-06-24 15:58   ` Laurent Desnogues
2016-06-24 15:49 ` [Qemu-devel] [PATCH 2/2] target-arm/arm-semi.c: Fix SYS_HEAPINFO for 64-bit guests Peter Maydell
2016-06-24 16:09   ` Laurent Desnogues
2016-06-24 16:39     ` Peter Maydell

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).