qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] x86: only allow real mode to access 32bit without LMA
@ 2013-12-06 12:52 Alexander Graf
  2013-12-06 17:46 ` Richard Henderson
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Alexander Graf @ 2013-12-06 12:52 UTC (permalink / raw)
  To: QEMU Developers; +Cc: Michael Tokarev

When we're running in non-64bit mode with qemu-system-x86_64 we can
still end up with virtual addresses that are above the 32bit boundary
if a segment offset is set up.

GNU Hurd does exactly that. It sets the segment offset to 0x80000000 and
puts its EIP value to 0x8xxxxxxx to access low memory.

This doesn't hit us when we enable paging, as there we just mask away the
unused bits. But with real mode, we assume that vaddr == paddr which is
wrong in this case. Real hardware wraps the virtual address around at the
32bit boundary. So let's do the same.

This fixes booting GNU Hurd in qemu-system-x86_64 for me.

Reported-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-i386/helper.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index 7c196ff..ed965d6 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -531,6 +531,12 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
 
     if (!(env->cr[0] & CR0_PG_MASK)) {
         pte = addr;
+#ifdef TARGET_X86_64
+        if (!(env->hflags & HF_LMA_MASK)) {
+            /* Without long mode we can only address 32bits in real mode */
+            pte = (uint32_t)pte;
+        }
+#endif
         virt_addr = addr & TARGET_PAGE_MASK;
         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
         page_size = 4096;
-- 
1.8.1.4

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

* Re: [Qemu-devel] [PATCH] x86: only allow real mode to access 32bit without LMA
  2013-12-06 12:52 [Qemu-devel] [PATCH] x86: only allow real mode to access 32bit without LMA Alexander Graf
@ 2013-12-06 17:46 ` Richard Henderson
  2013-12-06 18:48 ` Michael Tokarev
  2013-12-07 18:49 ` Michael Tokarev
  2 siblings, 0 replies; 5+ messages in thread
From: Richard Henderson @ 2013-12-06 17:46 UTC (permalink / raw)
  To: Alexander Graf, QEMU Developers; +Cc: Michael Tokarev

On 12/07/2013 01:52 AM, Alexander Graf wrote:
> When we're running in non-64bit mode with qemu-system-x86_64 we can
> still end up with virtual addresses that are above the 32bit boundary
> if a segment offset is set up.
> 
> GNU Hurd does exactly that. It sets the segment offset to 0x80000000 and
> puts its EIP value to 0x8xxxxxxx to access low memory.
> 
> This doesn't hit us when we enable paging, as there we just mask away the
> unused bits. But with real mode, we assume that vaddr == paddr which is
> wrong in this case. Real hardware wraps the virtual address around at the
> 32bit boundary. So let's do the same.
> 
> This fixes booting GNU Hurd in qemu-system-x86_64 for me.
> 
> Reported-by: Michael Tokarev <mjt@tls.msk.ru>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
>  target-i386/helper.c | 6 ++++++
>  1 file changed, 6 insertions(+)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

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

* Re: [Qemu-devel] [PATCH] x86: only allow real mode to access 32bit without LMA
  2013-12-06 12:52 [Qemu-devel] [PATCH] x86: only allow real mode to access 32bit without LMA Alexander Graf
  2013-12-06 17:46 ` Richard Henderson
@ 2013-12-06 18:48 ` Michael Tokarev
  2013-12-06 18:57   ` Stefan Weil
  2013-12-07 18:49 ` Michael Tokarev
  2 siblings, 1 reply; 5+ messages in thread
From: Michael Tokarev @ 2013-12-06 18:48 UTC (permalink / raw)
  To: Alexander Graf; +Cc: QEMU Developers

06.12.2013 16:52, Alexander Graf wrote:
> When we're running in non-64bit mode with qemu-system-x86_64 we can
> still end up with virtual addresses that are above the 32bit boundary
> if a segment offset is set up.
> 
> GNU Hurd does exactly that. It sets the segment offset to 0x80000000 and
> puts its EIP value to 0x8xxxxxxx to access low memory.
> 
> This doesn't hit us when we enable paging, as there we just mask away the
> unused bits. But with real mode, we assume that vaddr == paddr which is
> wrong in this case. Real hardware wraps the virtual address around at the
> 32bit boundary. So let's do the same.
> 
> This fixes booting GNU Hurd in qemu-system-x86_64 for me.
> 
> Reported-by: Michael Tokarev <mjt@tls.msk.ru>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
>  target-i386/helper.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 7c196ff..ed965d6 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -531,6 +531,12 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
>  
>      if (!(env->cr[0] & CR0_PG_MASK)) {
>          pte = addr;
> +#ifdef TARGET_X86_64
> +        if (!(env->hflags & HF_LMA_MASK)) {
> +            /* Without long mode we can only address 32bits in real mode */
> +            pte = (uint32_t)pte;
> +        }
> +#endif
>          virt_addr = addr & TARGET_PAGE_MASK;
>          prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
>          page_size = 4096;


Tested-by: Michael Tokarev <mjt@tls.msk.ru>

Well, it isn't much of testing, I too just run hurd image and see that
it can work in qemu-x86_64 tcg mode, while without this patch it
segfaults.

Should I apply this to trivial queue? :)

Thanks,

/mjt

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

* Re: [Qemu-devel] [PATCH] x86: only allow real mode to access 32bit without LMA
  2013-12-06 18:48 ` Michael Tokarev
@ 2013-12-06 18:57   ` Stefan Weil
  0 siblings, 0 replies; 5+ messages in thread
From: Stefan Weil @ 2013-12-06 18:57 UTC (permalink / raw)
  To: Michael Tokarev, Alexander Graf; +Cc: QEMU Developers, qemu-stable

Am 06.12.2013 19:48, schrieb Michael Tokarev:
> 06.12.2013 16:52, Alexander Graf wrote:
>> When we're running in non-64bit mode with qemu-system-x86_64 we can
>> still end up with virtual addresses that are above the 32bit boundary
>> if a segment offset is set up.
>>
>> GNU Hurd does exactly that. It sets the segment offset to 0x80000000 and
>> puts its EIP value to 0x8xxxxxxx to access low memory.
>>
>> This doesn't hit us when we enable paging, as there we just mask away the
>> unused bits. But with real mode, we assume that vaddr == paddr which is
>> wrong in this case. Real hardware wraps the virtual address around at the
>> 32bit boundary. So let's do the same.
>>
>> This fixes booting GNU Hurd in qemu-system-x86_64 for me.
>>
>> Reported-by: Michael Tokarev <mjt@tls.msk.ru>
>> Signed-off-by: Alexander Graf <agraf@suse.de>
>> ---
>>  target-i386/helper.c | 6 ++++++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/target-i386/helper.c b/target-i386/helper.c
>> index 7c196ff..ed965d6 100644
>> --- a/target-i386/helper.c
>> +++ b/target-i386/helper.c
>> @@ -531,6 +531,12 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
>>  
>>      if (!(env->cr[0] & CR0_PG_MASK)) {
>>          pte = addr;
>> +#ifdef TARGET_X86_64
>> +        if (!(env->hflags & HF_LMA_MASK)) {
>> +            /* Without long mode we can only address 32bits in real mode */
>> +            pte = (uint32_t)pte;
>> +        }
>> +#endif
>>          virt_addr = addr & TARGET_PAGE_MASK;
>>          prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
>>          page_size = 4096;
>
> Tested-by: Michael Tokarev <mjt@tls.msk.ru>
>
> Well, it isn't much of testing, I too just run hurd image and see that
> it can work in qemu-x86_64 tcg mode, while without this patch it
> segfaults.
>
> Should I apply this to trivial queue? :)
>
> Thanks,
>
> /mjt

Maybe your trivial queue would be the fasted way to get it into the
official repository. :-)

I added qemu-stable to the addressees, because this is useful for the
stable branches as well.

Regards,

Stefan

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

* Re: [Qemu-devel] [PATCH] x86: only allow real mode to access 32bit without LMA
  2013-12-06 12:52 [Qemu-devel] [PATCH] x86: only allow real mode to access 32bit without LMA Alexander Graf
  2013-12-06 17:46 ` Richard Henderson
  2013-12-06 18:48 ` Michael Tokarev
@ 2013-12-07 18:49 ` Michael Tokarev
  2 siblings, 0 replies; 5+ messages in thread
From: Michael Tokarev @ 2013-12-07 18:49 UTC (permalink / raw)
  To: Alexander Graf; +Cc: qemu-trivial, QEMU Developers

06.12.2013 16:52, Alexander Graf wrote:
> When we're running in non-64bit mode with qemu-system-x86_64 we can
> still end up with virtual addresses that are above the 32bit boundary
> if a segment offset is set up.
> 
> GNU Hurd does exactly that. It sets the segment offset to 0x80000000 and
> puts its EIP value to 0x8xxxxxxx to access low memory.
> 
> This doesn't hit us when we enable paging, as there we just mask away the
> unused bits. But with real mode, we assume that vaddr == paddr which is
> wrong in this case. Real hardware wraps the virtual address around at the
> 32bit boundary. So let's do the same.
> 
> This fixes booting GNU Hurd in qemu-system-x86_64 for me.

Since i386 tcg code has no active maintainer and since this is a rather
simple change, I'll queue it up to trivial-patches.

Thank you!

/mjt

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

end of thread, other threads:[~2013-12-07 18:49 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-06 12:52 [Qemu-devel] [PATCH] x86: only allow real mode to access 32bit without LMA Alexander Graf
2013-12-06 17:46 ` Richard Henderson
2013-12-06 18:48 ` Michael Tokarev
2013-12-06 18:57   ` Stefan Weil
2013-12-07 18:49 ` Michael Tokarev

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