-
Notifications
You must be signed in to change notification settings - Fork 5.9k
8262894: [macos_aarch64] SIGBUS in Assembler::ld_st2 #3241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back akozlov! A progress list of the required criteria for merging this PR into |
@AntonKozlov The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Anton,
In so much as I understand the fact transitions are missing the introduction of those transitions seems fine - but can be simplified due to an existing code quirk (see comments below).
My main concern with this W^X stuff is that I don't see a clear way to know exactly where a transition needs to be placed. The missing cases here suggest it should be handled in the thread-state transition code, but you've previously written:
" when we execute JVM code (owned by libjvm.so, starting from JVM entry function), we switch to Write state. When we leave JVM to execute generated or JNI code, we switch to Executable state. I would like to highlight that JVM code does not mean the VM state of the java thread"
so I'm unclear exactly how we identify the points where these transitions must occur? What kind of "VM code" must be guarded this way? I don't see this documented in the code anywhere.
Thanks,
David
@@ -3731,6 +3735,7 @@ static jint JNICALL jni_DestroyJavaVM_inner(JavaVM *vm) { | |||
return res; | |||
} else { | |||
ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_native); | |||
MACOS_AARCH64_ONLY(thread->enable_wx(oldmode)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually unnecessary as Threads::destroy_vm never returns anything but true (we should change it to a void method and clean this up). If it were to fail you would have to know at what point it failed to determine whether you can actually touch the current thread any more.
@@ -3723,6 +3723,10 @@ static jint JNICALL jni_DestroyJavaVM_inner(JavaVM *vm) { | |||
|
|||
// Since this is not a JVM_ENTRY we have to set the thread state manually before entering. | |||
JavaThread* thread = JavaThread::current(); | |||
|
|||
// We are going to VM, change W^X state to the expected one. | |||
MACOS_AARCH64_ONLY(WXMode oldmode = thread->enable_wx(WXWrite)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to save old state - see below.
@AntonKozlov This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 30 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@dholmes-ora, @gerard-ziemski) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
Hi David, Thank you for the review.
For usual JNI function implementation we switch to WXWrite in JNI_ENTRY (JNI_ENTRY_NO_PRESERVE to be precise), so xxx_ENTRY style macro defines a border between JVM and the rest of the code. JNI Invocation functions are also called directly from native code, so they should have W^X transition. But since they are implementing something rather special, they don't use any special ENTRY macro, which makes them less evident to be JVM entry points. Here and in other cases, when we do W^X in an apparently random function, it is because the function is called directly from the interpreter or native or generated code, but the function is not defined with ENTRY macro. Hope it clarifies the logic a bit. I've checked |
Mailing list message from David Holmes on hotspot-dev: On 30/03/2021 5:18 am, Anton Kozlov wrote:
I get the gist of where you have placed the transitions around the
I'll clean this part up under JDK-8264372. Cheers, |
I assume any VM entry code should have W^X transitions. Now VM_LEAF_BASE transits to WXWrite, and the macro is used in various kinds of LEAF's. An initial W^X implementation had no transitions in LEAF functions, but now the code and W^X policy should be much more straightforward. If we still don't have the transition somewhere, there should be a reason and a comment in the code. Otherwise, it's a bug :) |
/contributor add mikael |
@AntonKozlov |
@AntonKozlov |
That sounds very extreme to me. I guess it all depends on the cost of doing the transition. I'm curious why the W^X transition isn't done only when accessing the code cache. |
It is made for simplicity and robustness. I did a few iterations fixing various issues until this scheme came up, which I pretty confident now in correctness. Yes, it depends on the transition to be fast enough. To get the sense of "fast" I did #2200 (comment). But this approach can be and probably should be optimized.
There are a lot of places where we need or potentially need the transition. Every deoptimization may want to write to codecache. Adding explicit transitions is rather tedious and error-prone. I've tried this and it takes significant time to get to Another approach is to do a lazy transition to WXWrite on segfault after we try to write to codecache in VM and to ensure WXExec during exit from VM. Is it beneficial or not depends on a ratio between entries into runtime and ones actually need WXWrite. This raises a question about a realistic workload to measure effects after various W^X approaches. I used the first iteration of macro benchmarks like Renaissance and SPECjvm2008 with zero warm-up, in the assumption that the most number of runtime calls and deoptimization happens there. Is there a better workload for this purpose? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, thank you for fixing it.
/sponsor |
@VladimirKempik @AntonKozlov Since your change was applied there have been 37 commits pushed to the
Your commit was automatically rebased without conflicts. Pushed as commit 8a4a911. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
Please review a fix for compiler/debug/VerifyAdapterSharing.java failure on macos/aarch64 platform. The root cause is in missing W^X switch in JNI DestroyJavaVM.
I reviewed the rest of the JNI Invoke Interface functions. DetachCurrentThread needs a similar change, although nothing fails immediately. So DetachCurrentThread is changed as a precaution.
Progress
Issue
Reviewers
Contributors
<[email protected]>
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/3241/head:pull/3241
$ git checkout pull/3241
Update a local copy of the PR:
$ git checkout pull/3241
$ git pull https://git.openjdk.java.net/jdk pull/3241/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 3241
View PR using the GUI difftool:
$ git pr show -t 3241
Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/3241.diff