diff mbox

arm64: Add config to limit user space to 47bits

Message ID 1468424567-15925-1-git-send-email-agraf@suse.de (mailing list archive)
State New, archived
Headers show

Commit Message

Alexander Graf July 13, 2016, 3:42 p.m. UTC
Some user space applications are known to break with 48 bits virtual
address space. As interim step until the world is healed and everyone
embraces correct code, this patch allows to only expose 47 bits of
virtual address space to user space.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 arch/arm64/Kconfig              | 9 +++++++++
 arch/arm64/include/asm/memory.h | 4 ++++
 2 files changed, 13 insertions(+)

Comments

Ard Biesheuvel July 13, 2016, 3:59 p.m. UTC | #1
On 13 July 2016 at 17:42, Alexander Graf <agraf@suse.de> wrote:
> Some user space applications are known to break with 48 bits virtual

known by whom? At least I wasn't aware of it, so could you please
share some examples?

> address space. As interim step until the world is healed and everyone
> embraces correct code, this patch allows to only expose 47 bits of
> virtual address space to user space.
>

Is this a code generation/toolchain issue?

> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
>  arch/arm64/Kconfig              | 9 +++++++++
>  arch/arm64/include/asm/memory.h | 4 ++++
>  2 files changed, 13 insertions(+)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 5a0a691..9ff5a74 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -538,6 +538,15 @@ config ARM64_VA_BITS
>         default 47 if ARM64_VA_BITS_47
>         default 48 if ARM64_VA_BITS_48
>
> +config ARM64_USER_VA_BITS_47
> +       bool "Limit user space to 47 bits address space"
> +       depends on ARM64_VA_BITS_48
> +       help
> +         Some user space applications are known to break with 48 bits virtual
> +         address space. As interim step until the world is healed and everyone
> +         embraces correct code, this option allows to only expose 47 bits of
> +         virtual address space to user space. If unsure say N here.
> +
>  config CPU_BIG_ENDIAN
>         bool "Build big-endian kernel"
>         help
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index 31b7322..ef268c6 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -74,7 +74,11 @@
>  #define PCI_IO_END             (VMEMMAP_START - SZ_2M)
>  #define PCI_IO_START           (PCI_IO_END - PCI_IO_SIZE)
>  #define FIXADDR_TOP            (PCI_IO_START - SZ_2M)
> +#ifdef CONFIG_ARM64_USER_VA_BITS_47
> +#define TASK_SIZE_64           (UL(1) << (VA_BITS - 1))
> +#else
>  #define TASK_SIZE_64           (UL(1) << VA_BITS)
> +#endif
>
>  #ifdef CONFIG_COMPAT
>  #define TASK_SIZE_32           UL(0x100000000)
> --
> 1.8.5.6
>
Mark Rutland July 13, 2016, 4:10 p.m. UTC | #2
On Wed, Jul 13, 2016 at 05:42:47PM +0200, Alexander Graf wrote:
> Some user space applications are known to break with 48 bits virtual
> address space. As interim step until the world is healed and everyone
> embraces correct code, this patch allows to only expose 47 bits of
> virtual address space to user space.

These applications have *always* been broken with 48-bit VA.

Per Documentation/arm64/tagged-pointers.txt, the *only* upper bits that
an application can assume will be zero (and therefore use for tags) are
bits 63:56.

The clear architectural intent here is that bits 55:0 can be valid
pointer bits, and it seems likely that the kernel will expand to use
bits 55:48 in future, e.g. with 52-bit VAs as part of ARMv8.2 [1]. I
hope those applications are being fixed to leave bits 55:48 well alone
also.

For this as a config option, NAK. It removes any incentive to actually
fix the problem, and perpetuates the idea that it's the kernel's
responsibility to bodge around things that never worked in the first
place. It works directly against the goal of a single kernel Image.

[1] https://community.arm.com/groups/processors/blog/2016/01/05/armv8-a-architecture-evolution

Thanks,
Mark.

> 
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
>  arch/arm64/Kconfig              | 9 +++++++++
>  arch/arm64/include/asm/memory.h | 4 ++++
>  2 files changed, 13 insertions(+)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 5a0a691..9ff5a74 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -538,6 +538,15 @@ config ARM64_VA_BITS
>  	default 47 if ARM64_VA_BITS_47
>  	default 48 if ARM64_VA_BITS_48
>  
> +config ARM64_USER_VA_BITS_47
> +	bool "Limit user space to 47 bits address space"
> +	depends on ARM64_VA_BITS_48
> +	help
> +	  Some user space applications are known to break with 48 bits virtual
> +	  address space. As interim step until the world is healed and everyone
> +	  embraces correct code, this option allows to only expose 47 bits of
> +	  virtual address space to user space. If unsure say N here.
> +
>  config CPU_BIG_ENDIAN
>         bool "Build big-endian kernel"
>         help
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index 31b7322..ef268c6 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -74,7 +74,11 @@
>  #define PCI_IO_END		(VMEMMAP_START - SZ_2M)
>  #define PCI_IO_START		(PCI_IO_END - PCI_IO_SIZE)
>  #define FIXADDR_TOP		(PCI_IO_START - SZ_2M)
> +#ifdef CONFIG_ARM64_USER_VA_BITS_47
> +#define TASK_SIZE_64		(UL(1) << (VA_BITS - 1))
> +#else
>  #define TASK_SIZE_64		(UL(1) << VA_BITS)
> +#endif
>  
>  #ifdef CONFIG_COMPAT
>  #define TASK_SIZE_32		UL(0x100000000)
> -- 
> 1.8.5.6
>
Alexander Graf July 13, 2016, 4:14 p.m. UTC | #3
On 07/13/2016 05:59 PM, Ard Biesheuvel wrote:
> On 13 July 2016 at 17:42, Alexander Graf <agraf@suse.de> wrote:
>> Some user space applications are known to break with 48 bits virtual
> known by whom? At least I wasn't aware of it, so could you please
> share some examples?

Sure! Known to me so far are:

   * mozjs17
   * mozjs24
   * mozjs38
   * js-1.8.5
   * java-1.7 (older JITs, fixed in newer ones)

I'm not sure if there are more, but the fact that I've run into this 
problem more than once doesn't make me incredibly happy :).

>
>> address space. As interim step until the world is healed and everyone
>> embraces correct code, this patch allows to only expose 47 bits of
>> virtual address space to user space.
>>
> Is this a code generation/toolchain issue?

mozjs uses a single 64bit value to combine doubles, ints and pointers 
into a single variable. It is very smart and uses the upper 17 bits for 
metadata such as "which type of variable is this". Coincidentally those 
bits happen to overlap the "double is an infinite number" bits, so that 
you can also express a NaN with it. When using such a value, the upper 
17 bits get masked out.

That one was fixed upstream by force allocating the javascript heap 
starting at a fixed location which is below 47 bits.

js-1.8.5 has the same as above, but also uses pointers to .rodata as 
javascript pointers, so it doesn't only use the heap, it also uses 
pointers to the library itself, which gets mapped high up the address 
space. I don't have a solution for that one yet.

IcedTea for java-1.7 had a bug where it incorrectly caused an overflow 
when trying to calculating a relative adrp offset from <address high up> 
to <address really low>, so that the resulting pointer had the upper 
bits set as 1s. That one is long fixed upstream, we only ran into it 
because we used an ancient IcedTea snapshot.

My main concern however is with code that I do not know is broken today.


Alex
Steve Capper July 14, 2016, 1:08 a.m. UTC | #4
Hi Alex,

Thanks for posting this.

On Wed, Jul 13, 2016 at 06:14:11PM +0200, Alexander Graf wrote:
> On 07/13/2016 05:59 PM, Ard Biesheuvel wrote:
> >On 13 July 2016 at 17:42, Alexander Graf <agraf@suse.de> wrote:
> >>Some user space applications are known to break with 48 bits virtual
> >known by whom? At least I wasn't aware of it, so could you please
> >share some examples?
> 
> Sure! Known to me so far are:
> 
>   * mozjs17
>   * mozjs24
>   * mozjs38
>   * js-1.8.5
>   * java-1.7 (older JITs, fixed in newer ones)
> 
> I'm not sure if there are more, but the fact that I've run into this
> problem more than once doesn't make me incredibly happy :).
> 

I came across this too: on bootup via polkitd (which pulled in mozJS) :-(.

> >
> >>address space. As interim step until the world is healed and everyone
> >>embraces correct code, this patch allows to only expose 47 bits of
> >>virtual address space to user space.
> >>
> >Is this a code generation/toolchain issue?
> 
> mozjs uses a single 64bit value to combine doubles, ints and
> pointers into a single variable. It is very smart and uses the upper
> 17 bits for metadata such as "which type of variable is this".
> Coincidentally those bits happen to overlap the "double is an
> infinite number" bits, so that you can also express a NaN with it.
> When using such a value, the upper 17 bits get masked out.
> 
> That one was fixed upstream by force allocating the javascript heap
> starting at a fixed location which is below 47 bits.
> 
> js-1.8.5 has the same as above, but also uses pointers to .rodata as
> javascript pointers, so it doesn't only use the heap, it also uses
> pointers to the library itself, which gets mapped high up the
> address space. I don't have a solution for that one yet.

Is this Spidermonkey 1.8.5? I wasn't aware of this issue.

> 
> IcedTea for java-1.7 had a bug where it incorrectly caused an
> overflow when trying to calculating a relative adrp offset from
> <address high up> to <address really low>, so that the resulting
> pointer had the upper bits set as 1s. That one is long fixed
> upstream, we only ran into it because we used an ancient IcedTea
> snapshot.

I would recommend updating the sources used for OpenJDK anyway as there
have been a few other stability and performance fixes put in over the
last year to my knowledge.

> 
> My main concern however is with code that I do not know is broken today.
> 

I think if we set the 47-bit VA we are just ignoring the fundamental
problem and even allowing the problem to get worse (as future code may
adopt unsafe pointer tagging); thus I agree with Mark Rutland's NAK.

Personally, I would only ever tag bits in the VA space that I control
(i.e. at the bottom of the pointer if I enforce alignment).

Cheers,
Alexander Graf July 14, 2016, 6:38 a.m. UTC | #5
> On 14 Jul 2016, at 03:08, Steve Capper <steve.capper@arm.com> wrote:
> 
> Hi Alex,
> 
> Thanks for posting this.
> 
> On Wed, Jul 13, 2016 at 06:14:11PM +0200, Alexander Graf wrote:
>> On 07/13/2016 05:59 PM, Ard Biesheuvel wrote:
>>> On 13 July 2016 at 17:42, Alexander Graf <agraf@suse.de> wrote:
>>>> Some user space applications are known to break with 48 bits virtual
>>> known by whom? At least I wasn't aware of it, so could you please
>>> share some examples?
>> 
>> Sure! Known to me so far are:
>> 
>>  * mozjs17
>>  * mozjs24
>>  * mozjs38
>>  * js-1.8.5
>>  * java-1.7 (older JITs, fixed in newer ones)
>> 
>> I'm not sure if there are more, but the fact that I've run into this
>> problem more than once doesn't make me incredibly happy :).
>> 
> 
> I came across this too: on bootup via polkitd (which pulled in mozJS) :-(.

Yup, that’s where I stumbled over it first. Gnome uses mozjs too, as do Firefox and Thunderbird obviously.

> 
>>> 
>>>> address space. As interim step until the world is healed and everyone
>>>> embraces correct code, this patch allows to only expose 47 bits of
>>>> virtual address space to user space.
>>>> 
>>> Is this a code generation/toolchain issue?
>> 
>> mozjs uses a single 64bit value to combine doubles, ints and
>> pointers into a single variable. It is very smart and uses the upper
>> 17 bits for metadata such as "which type of variable is this".
>> Coincidentally those bits happen to overlap the "double is an
>> infinite number" bits, so that you can also express a NaN with it.
>> When using such a value, the upper 17 bits get masked out.
>> 
>> That one was fixed upstream by force allocating the javascript heap
>> starting at a fixed location which is below 47 bits.
>> 
>> js-1.8.5 has the same as above, but also uses pointers to .rodata as
>> javascript pointers, so it doesn't only use the heap, it also uses
>> pointers to the library itself, which gets mapped high up the
>> address space. I don't have a solution for that one yet.
> 
> Is this Spidermonkey 1.8.5? I wasn't aware of this issue.

Exactly. If you’re interested in fixing it, be my guest :).

> 
>> 
>> IcedTea for java-1.7 had a bug where it incorrectly caused an
>> overflow when trying to calculating a relative adrp offset from
>> <address high up> to <address really low>, so that the resulting
>> pointer had the upper bits set as 1s. That one is long fixed
>> upstream, we only ran into it because we used an ancient IcedTea
>> snapshot.
> 
> I would recommend updating the sources used for OpenJDK anyway as there
> have been a few other stability and performance fixes put in over the
> last year to my knowledge.

Sure, that’s what we’ve done of course. I mostly mentioned it to answer the question where I had seen problems with 48 bits VA.

> 
>> 
>> My main concern however is with code that I do not know is broken today.
>> 
> 
> I think if we set the 47-bit VA we are just ignoring the fundamental
> problem and even allowing the problem to get worse (as future code may
> adopt unsafe pointer tagging); thus I agree with Mark Rutland's NAK.

Yeah, I’m torn on that one. I agree that we do allow broken code to work. However, going above 47 bits means we’re different from x86_64. And that *may* be a compatibility problem. Unfortunately we won’t know until at least a few hundred ISVs started to port their crufty user space code to ARM and things fell apart from time to time ;).

> Personally, I would only ever tag bits in the VA space that I control
> (i.e. at the bottom of the pointer if I enforce alignment).

Don’t blame the messenger :). For code that I write I tend to agree, but we’re talking about software that is a core dependency of other code (CouchDB uses Spidermonkey, polkit uses mozjs, etc) and that has been unmaintained for almost a decade by now, written in times when 47 bits of VA was more than the contents of the whole internet ;).


Alex
Zheng Xu July 14, 2016, 7:03 a.m. UTC | #6
LuaJIT also fix the 48VA issue by allocating heap memory below 47 bits.

For mozjs issue, if there are pointers to .rodata, it can be a problem. Does it happen on master and do we have any case to reproduce the issue so that I can take a look?

Thanks,
Zheng

-----Original Message-----
From: Alexander Graf [mailto:agraf@suse.de]

Sent: 14 July 2016 14:39
To: Steve Capper
Cc: Ard Biesheuvel; Mark Rutland; mbrugger@suse.com; Catalin Marinas; Will Deacon; linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Stuart Monteith; Zheng Xu
Subject: Re: [PATCH] arm64: Add config to limit user space to 47bits


> On 14 Jul 2016, at 03:08, Steve Capper <steve.capper@arm.com> wrote:

>

> Hi Alex,

>

> Thanks for posting this.

>

> On Wed, Jul 13, 2016 at 06:14:11PM +0200, Alexander Graf wrote:

>> On 07/13/2016 05:59 PM, Ard Biesheuvel wrote:

>>> On 13 July 2016 at 17:42, Alexander Graf <agraf@suse.de> wrote:

>>>> Some user space applications are known to break with 48 bits

>>>> virtual

>>> known by whom? At least I wasn't aware of it, so could you please

>>> share some examples?

>>

>> Sure! Known to me so far are:

>>

>>  * mozjs17

>>  * mozjs24

>>  * mozjs38

>>  * js-1.8.5

>>  * java-1.7 (older JITs, fixed in newer ones)

>>

>> I'm not sure if there are more, but the fact that I've run into this

>> problem more than once doesn't make me incredibly happy :).

>>

>

> I came across this too: on bootup via polkitd (which pulled in mozJS) :-(.


Yup, that’s where I stumbled over it first. Gnome uses mozjs too, as do Firefox and Thunderbird obviously.

>

>>>

>>>> address space. As interim step until the world is healed and

>>>> everyone embraces correct code, this patch allows to only expose 47

>>>> bits of virtual address space to user space.

>>>>

>>> Is this a code generation/toolchain issue?

>>

>> mozjs uses a single 64bit value to combine doubles, ints and pointers

>> into a single variable. It is very smart and uses the upper

>> 17 bits for metadata such as "which type of variable is this".

>> Coincidentally those bits happen to overlap the "double is an

>> infinite number" bits, so that you can also express a NaN with it.

>> When using such a value, the upper 17 bits get masked out.

>>

>> That one was fixed upstream by force allocating the javascript heap

>> starting at a fixed location which is below 47 bits.

>>

>> js-1.8.5 has the same as above, but also uses pointers to .rodata as

>> javascript pointers, so it doesn't only use the heap, it also uses

>> pointers to the library itself, which gets mapped high up the address

>> space. I don't have a solution for that one yet.

>

> Is this Spidermonkey 1.8.5? I wasn't aware of this issue.


Exactly. If you’re interested in fixing it, be my guest :).

>

>>

>> IcedTea for java-1.7 had a bug where it incorrectly caused an

>> overflow when trying to calculating a relative adrp offset from

>> <address high up> to <address really low>, so that the resulting

>> pointer had the upper bits set as 1s. That one is long fixed

>> upstream, we only ran into it because we used an ancient IcedTea

>> snapshot.

>

> I would recommend updating the sources used for OpenJDK anyway as

> there have been a few other stability and performance fixes put in

> over the last year to my knowledge.


Sure, that’s what we’ve done of course. I mostly mentioned it to answer the question where I had seen problems with 48 bits VA.

>

>>

>> My main concern however is with code that I do not know is broken today.

>>

>

> I think if we set the 47-bit VA we are just ignoring the fundamental

> problem and even allowing the problem to get worse (as future code may

> adopt unsafe pointer tagging); thus I agree with Mark Rutland's NAK.


Yeah, I’m torn on that one. I agree that we do allow broken code to work. However, going above 47 bits means we’re different from x86_64. And that *may* be a compatibility problem. Unfortunately we won’t know until at least a few hundred ISVs started to port their crufty user space code to ARM and things fell apart from time to time ;).

> Personally, I would only ever tag bits in the VA space that I control

> (i.e. at the bottom of the pointer if I enforce alignment).


Don’t blame the messenger :). For code that I write I tend to agree, but we’re talking about software that is a core dependency of other code (CouchDB uses Spidermonkey, polkit uses mozjs, etc) and that has been unmaintained for almost a decade by now, written in times when 47 bits of VA was more than the contents of the whole internet ;).


Alex

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Alexander Graf July 14, 2016, 7:14 a.m. UTC | #7
On 14.07.16 09:03, Zheng Xu wrote:
> LuaJIT also fix the 48VA issue by allocating heap memory below 47 bits.
> 
> For mozjs issue, if there are pointers to .rodata, it can be a problem. Does it happen on master and do we have any case to reproduce the issue so that I can take a look?

mozjs is fixed with your patch. I backported it to all of the ancient
versions of mozjs, so we're probably good there. Though every distro
will have to redo that work in their own trees, because older versions
of mozjs are no longer maintained upstream. If you want to be a hero,
you can try to port polkitd and gnome to use more recent versions of
mozjs ;). Or maybe they can already and we just messed up packaging.

The issue I mentioned with "js 1.8.5" is this gem:


https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Releases/1.8.5

I don't know the exact history, but I think it predates mozjs. With a
bit of sledge hammering your heap allocation patch applies there too,
but we still get the rodata references.


Alex
Zheng Xu July 14, 2016, 7:49 a.m. UTC | #8
Sorry, I might misunderstand the issue. I thought there are still issues with master.

I saw that you've mentioned there are pointers to .rodata. And I only fixed the heap. So I am just worried if there can be issues with .rodata. If pointers to .rodata are not tagged and used as js objects, it should be fine.

Thanks,
Zheng

-----Original Message-----
From: Alexander Graf [mailto:agraf@suse.de]
Sent: 14 July 2016 15:14
To: Zheng Xu; Steve Capper
Cc: Ard Biesheuvel; Mark Rutland; mbrugger@suse.com; Catalin Marinas; Will Deacon; linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Stuart Monteith
Subject: Re: [PATCH] arm64: Add config to limit user space to 47bits


On 14.07.16 09:03, Zheng Xu wrote:
> LuaJIT also fix the 48VA issue by allocating heap memory below 47 bits.
>
> For mozjs issue, if there are pointers to .rodata, it can be a problem. Does it happen on master and do we have any case to reproduce the issue so that I can take a look?

mozjs is fixed with your patch. I backported it to all of the ancient versions of mozjs, so we're probably good there. Though every distro will have to redo that work in their own trees, because older versions of mozjs are no longer maintained upstream. If you want to be a hero, you can try to port polkitd and gnome to use more recent versions of mozjs ;). Or maybe they can already and we just messed up packaging.

The issue I mentioned with "js 1.8.5" is this gem:


https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Releases/1.8.5

I don't know the exact history, but I think it predates mozjs. With a bit of sledge hammering your heap allocation patch applies there too, but we still get the rodata references.


Alex

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Alexander Graf July 14, 2016, 8:01 a.m. UTC | #9
> Am 14.07.2016 um 09:49 schrieb Zheng Xu <Zheng.Xu@arm.com>:
> 
> Sorry, I might misunderstand the issue. I thought there are still issues with master.
> 
> I saw that you've mentioned there are pointers to .rodata. And I only fixed the heap. So I am just worried if there can be issues with .rodata. If pointers to .rodata are not tagged and used as js objects, it should be fine.

Please don't top post on kernel mailing lists.

The old Spidermonkey (which is used by couchdb) has some string allocation optimization in jsstr.cpp that directly pregenerates js strings in .rodata at compile time. Just try to run couchdb on a 48bit va aarch64 system and it will fall apart.

Fixing mozjs master doesn't really help here, since couchdb requires the ancient spidermonkey 1.8.5. An alternative to fixing that old js implementation would obviously also be to move couchdb to mozjs master.


Alex
Ard Biesheuvel July 14, 2016, 3:17 p.m. UTC | #10
On 13 July 2016 at 18:14, Alexander Graf <agraf@suse.de> wrote:
> On 07/13/2016 05:59 PM, Ard Biesheuvel wrote:
>>
>> On 13 July 2016 at 17:42, Alexander Graf <agraf@suse.de> wrote:
>>>
>>> Some user space applications are known to break with 48 bits virtual
>>
>> known by whom? At least I wasn't aware of it, so could you please
>> share some examples?
>
>
> Sure! Known to me so far are:
>
>   * mozjs17
>   * mozjs24
>   * mozjs38
>   * js-1.8.5
>   * java-1.7 (older JITs, fixed in newer ones)
>

Ah, right. The JIT stuff ... I did read about that before, but thanks
for refreshing my memory

> I'm not sure if there are more, but the fact that I've run into this problem
> more than once doesn't make me incredibly happy :).
>

There is little point in reiterating over all the opinions that have
been shared, but for the record, I agree that we should *not* cater
for horrible hacks in JIT code. The only thing we should attempt to
deal with on the kernel side is VA space size related differences
between architectures that have some base in language or ABI specs,
and this is clearly not the case here.

It does bring up another interesting point, though. The size of the
userland VA space simply follows the size of the kernel VA space, and
the latter is chosen to be 48 bits on recent defconfig kernels to
accommodate platforms that have a 512 GB hole in the middle of their
physical address space. If the userland address space is populated
very sparsely, this may have a measurable performance impact
(especially under virt, due to the way each level of translation at
stage 1 triggers a full page table walk at stage 2), and so there may
be a case to be made for lowering TASK_SIZE for other reasons than the
one given in this patch. Or at least be able to interrogate the OS for
the size of the VA space ...

>>
>>> address space. As interim step until the world is healed and everyone
>>> embraces correct code, this patch allows to only expose 47 bits of
>>> virtual address space to user space.
>>>
>> Is this a code generation/toolchain issue?
>
>
> mozjs uses a single 64bit value to combine doubles, ints and pointers into a
> single variable. It is very smart and uses the upper 17 bits for metadata
> such as "which type of variable is this". Coincidentally those bits happen
> to overlap the "double is an infinite number" bits, so that you can also
> express a NaN with it. When using such a value, the upper 17 bits get masked
> out.
>
> That one was fixed upstream by force allocating the javascript heap starting
> at a fixed location which is below 47 bits.
>
> js-1.8.5 has the same as above, but also uses pointers to .rodata as
> javascript pointers, so it doesn't only use the heap, it also uses pointers
> to the library itself, which gets mapped high up the address space. I don't
> have a solution for that one yet.
>
> IcedTea for java-1.7 had a bug where it incorrectly caused an overflow when
> trying to calculating a relative adrp offset from <address high up> to
> <address really low>, so that the resulting pointer had the upper bits set
> as 1s. That one is long fixed upstream, we only ran into it because we used
> an ancient IcedTea snapshot.
>
> My main concern however is with code that I do not know is broken today.
>

I really think papering over it like this is not the way to go.

Thanks,
Ard.
Jeremy Linton July 14, 2016, 6:07 p.m. UTC | #11
On 07/14/2016 02:14 AM, Alexander Graf wrote:
>
> On 14.07.16 09:03, Zheng Xu wrote:
>> LuaJIT also fix the 48VA issue by allocating heap memory below 47 bits.
>>
>> For mozjs issue, if there are pointers to .rodata, it can be a problem. Does it happen on master and do we have any case to reproduce the issue so that I can take a look?
>
> mozjs is fixed with your patch. I backported it to all of the ancient
> versions of mozjs, so we're probably good there. Though every distro
> will have to redo that work in their own trees, because older versions
> of mozjs are no longer maintained upstream. If you want to be a hero,
> you can try to port polkitd and gnome to use more recent versions of
> mozjs ;). Or maybe they can already and we just messed up packaging.


I have a polkit built against mozjs45, getting it to work on the other 
hand is the yak of the day...
diff mbox

Patch

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 5a0a691..9ff5a74 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -538,6 +538,15 @@  config ARM64_VA_BITS
 	default 47 if ARM64_VA_BITS_47
 	default 48 if ARM64_VA_BITS_48
 
+config ARM64_USER_VA_BITS_47
+	bool "Limit user space to 47 bits address space"
+	depends on ARM64_VA_BITS_48
+	help
+	  Some user space applications are known to break with 48 bits virtual
+	  address space. As interim step until the world is healed and everyone
+	  embraces correct code, this option allows to only expose 47 bits of
+	  virtual address space to user space. If unsure say N here.
+
 config CPU_BIG_ENDIAN
        bool "Build big-endian kernel"
        help
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 31b7322..ef268c6 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -74,7 +74,11 @@ 
 #define PCI_IO_END		(VMEMMAP_START - SZ_2M)
 #define PCI_IO_START		(PCI_IO_END - PCI_IO_SIZE)
 #define FIXADDR_TOP		(PCI_IO_START - SZ_2M)
+#ifdef CONFIG_ARM64_USER_VA_BITS_47
+#define TASK_SIZE_64		(UL(1) << (VA_BITS - 1))
+#else
 #define TASK_SIZE_64		(UL(1) << VA_BITS)
+#endif
 
 #ifdef CONFIG_COMPAT
 #define TASK_SIZE_32		UL(0x100000000)