RFR: JDK-8158502: aarch32: detect QEMU user-mode emulation

Alex Kashchenko akashche at redhat.com
Thu Jun 2 17:48:57 UTC 2016


Hi Andrey,

On 06/02/2016 05:51 PM, Andrey Petushkov wrote:
> Hi Alex,
>
> Sorry but I’m a bit hesitant to follow the approach you presented. I’m not sure that the solution is stable enough, specifically around removing of assertions in the relocation support. As the result you actually get into the situation when the code cannot be patched correctly and will end up executing the wrong version (in best case) or executing mere garbage. So I’d rather understand why at all such situation can happen.

Fair enough, as far as I can see relocation code doesn't work with 
user-mode emulation. It is a bit complicated to investigate as I don't 
know how to debug jvm running in user-mode emu. I'll try to find out the 
differences in treatment of this part in native, full-emu, and 
user-mode-emu cases. Hopefully that will clarify the situation.

> Given the explanation you’re provided I can assume that the real reason for the problem is absence of indication of the cpu version in the /proc/cpuinfo, since java sees the host’s version, which has nothing to do with instruction set being emulated. As such we fall into lowest armv6 mode, which is actually not supported by the code (currently the lowest supported cpu is armv6t2). The support of the armv6 (non t2) in aarch32 port has problem of emitting code which cannot be patched later (it’s just not implemented). Although it might happen that actual relocation of the code is not needed for interpreter only build, it becomes extremely important when C1 implementation is integrated
>
> So in order to have this problem addressed I’d rather go in a different way. Assuming that your emulator can do armv6t2 or v7 I’d better add an command line option (much like those UseAES etc) to override the information obtained from /proc/cpuinfo (and avoid calling getauxv, since it likely to return host’s capabilities). This way java should function fully in accordance to the capabilities of the emulator (assuming the passed values are correct, of course). The same time the problem of yours should go away.

So we basically need to make platform detection (from /proc/cpuinfo) 
clever enough not only to detect the user-mode emulation but also to 
detect correct supported instruction set (and other emulated cpu 
features). And support more command line args for enabling/disabling 
detected features directly.

> Well, another way can be is to hardcode the value of the ProcessorFeatures, once emulation is detected. However such solution is too much inflexible so I’d better abstain from it
>
> In the meanwhile I’ve tried to reproduce the situation but failed to install necessary environment (I’m using Ubuntu and there’s no armhf libc.so available in the stock repos, I’ve tried to install from debian manually, but failed on missing the package multiarch-support-armhf-cross. Both google and myself have no idea where to get it :( ).

I wrote down details of cross-compilation env setup some time ago here - 
https://github.com/akashche/wiki/wiki/AArch32CrossCompile . It is a bit 
over the top as the initial version has been written for IcedTea7-arm32 
that runs freshly built vm during the build. It is for Ubuntu 15.10, but 
also works for 16.04 (changing only version numbers and "wily" -> 
"xenial" for repos). Also VM can be used instead of Docker.

> So I can only hope that emu-user-static is capable of emulating at least armv6t2, otherwise the problem is much bigger than just the asserts..

I see the whole use-case as a very minor nuisance, as it is unlikely 
that jdk will be used in user-mode emu with any meaningful workloads 
(the only example I can imagine is a requirement to use some 
closed-source arm32-only JNI library on x86_64). But it is really 
convenient to use with cross-compilation during the development.

>
> Regards,
> Andrey
>
>> On 02 Jun 2016, at 14:21, Alex Kashchenko <akashche at redhat.com> wrote:
>>
>> Hi,
>>
>> This patch detects that jvm runs on x86_64 hardware using QEMU user-mode emulation and prevents (ignores) assertions that currently happen in that environment:
>>
>> - issue: https://bugs.openjdk.java.net/browse/JDK-8158502
>> - webrev: http://cr.openjdk.java.net/~akasko/aarch32/jdk8u/8158502/webrev.00/
>>
>> QEMU allows to run arm32 programs on x86_64 hardware with user-mode emulation tools (qemu-arm-static). Along with binfmt_misc setup it allows to run aarch32 jvm on x86_64 hardware transparently like a native binary (albeit at the much slower speed). That may be useful during the cross-compilation for smoke testing aarch32 changes.
>>
>> Currently jvm asserts on startup in that environment. Proposed change is to detect QEMU user-mode emulation and prevent (ignore) assertions in that case.
>>
>> Detection is done looking into "lm" (64-bit) or "tm" (32-bit) entry in "flags" field in /proc/cpuinfo. It is assumed that if we can see x86(_64) CPU from aarch32 JVM - we are running in user-mode emulation as QEMU+kernel emulation reports its own /proc/cpuinfo. Detection result is saved as FT_UMEmu (User Mode Emulation) flag in VMVersion.
>>
>> Actual changes are in relocInfo_aarch32.cpp , they are deliberately non-intrusive to mainline execution code - effectively just assertions are ignored. It may (or may not) be better to implement proper support for user-mode emulation in that code in future.
>>
>> Checks before printing warnings have been required, because these warnings (all 4 of them) being printed in release builds - that breaks jdk version detection.
>>
>> Running in user-mode emulation aarch32 vm is stable - during testing I bootstrapped slowdebug aarch32-jdk8u using fastdebug aarch32-jdk8u as a boot jdk on x86_64 hardware.
>>
>> Webrev is done against the current state of jdk8u forest. Changes to vm_version part may conflict with other patches. After the review I'll rebase this patch onto the new state and will create committed webrevs for jdk8u and jdk9.
>>
>> --
>> -Alex
>


-- 
-Alex


More information about the aarch32-port-dev mailing list