8286711: AArch64: serviceability agent tests fail with PAC enabled

Reviewed-by: dholmes, cjplummer
This commit is contained in:
Nick Gasson 2022-05-30 08:12:05 +00:00
parent 19fb8ab8b9
commit d8331737ad
5 changed files with 41 additions and 8 deletions
src
hotspot/cpu/aarch64
jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/aarch64

@ -25,6 +25,10 @@
#ifndef CPU_AARCH64_PAUTH_AARCH64_HPP
#define CPU_AARCH64_PAUTH_AARCH64_HPP
#include "runtime/vm_version.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
#include OS_CPU_HEADER_INLINE(pauth)
// Support for ROP Protection in VM code.

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -31,9 +31,12 @@
// referenced by vmStructs.cpp.
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*)
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) \
static_field(VM_Version, _rop_protection, bool) \
static_field(VM_Version, _pac_mask, uintptr_t)
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
declare_toplevel_type(VM_Version)
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)

@ -24,6 +24,7 @@
*/
#include "precompiled.hpp"
#include "pauth_aarch64.hpp"
#include "runtime/arguments.hpp"
#include "runtime/globals_extension.hpp"
#include "runtime/java.hpp"
@ -46,6 +47,7 @@ int VM_Version::_dcache_line_size;
int VM_Version::_icache_line_size;
int VM_Version::_initial_sve_vector_length;
bool VM_Version::_rop_protection;
uintptr_t VM_Version::_pac_mask;
SpinWait VM_Version::_spin_wait;
@ -444,8 +446,12 @@ void VM_Version::initialize() {
vm_exit_during_initialization(err_msg("Unsupported UseBranchProtection: %s", UseBranchProtection));
}
// The frame pointer must be preserved for ROP protection.
if (_rop_protection == true) {
// Determine the mask of address bits used for PAC. Clear bit 55 of
// the input to make it look like a user address.
_pac_mask = (uintptr_t)pauth_strip_pointer((address)~(UINT64_C(1) << 55));
// The frame pointer must be preserved for ROP protection.
if (FLAG_IS_DEFAULT(PreserveFramePointer) == false && PreserveFramePointer == false ) {
vm_exit_during_initialization(err_msg("PreserveFramePointer cannot be disabled for ROP-protection"));
}

@ -31,6 +31,7 @@
#include "utilities/sizes.hpp"
class VM_Version : public Abstract_VM_Version {
friend class VMStructs;
friend class JVMCIVMStructs;
protected:
@ -46,6 +47,7 @@ protected:
static int _icache_line_size;
static int _initial_sve_vector_length;
static bool _rop_protection;
static uintptr_t _pac_mask;
static SpinWait _spin_wait;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -70,6 +70,9 @@ public class AARCH64Frame extends Frame {
// Native frames
private static final int NATIVE_FRAME_INITIAL_PARAM_OFFSET = 2;
private static CIntegerField ropProtectionField;
private static CIntegerField pacMaskField;
private static VMReg fp = new VMReg(29 << 1);
static {
@ -90,8 +93,11 @@ public class AARCH64Frame extends Frame {
INTERPRETER_FRAME_INITIAL_SP_OFFSET = INTERPRETER_FRAME_BCX_OFFSET - 1;
INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
}
Type vmVersion = db.lookupType("VM_Version");
ropProtectionField = vmVersion.getCIntegerField("_rop_protection");
pacMaskField = vmVersion.getCIntegerField("_pac_mask");
}
// an additional field beyond sp and pc:
Address raw_fp; // frame pointer
@ -391,7 +397,7 @@ public class AARCH64Frame extends Frame {
Address senderSP = getUnextendedSP().addOffsetTo(cb.getFrameSize());
// The return_address is always the word on the stack
Address senderPC = senderSP.getAddressAt(-1 * VM.getVM().getAddressSize());
Address senderPC = stripPAC(senderSP.getAddressAt(-1 * VM.getVM().getAddressSize()));
// This is the saved value of FP which may or may not really be an FP.
// It is only an FP if the sender is an interpreter frame.
@ -445,7 +451,19 @@ public class AARCH64Frame extends Frame {
// Return address:
public Address getSenderPCAddr() { return addressOfStackSlot(RETURN_ADDR_OFFSET); }
public Address getSenderPC() { return getSenderPCAddr().getAddressAt(0); }
public Address getSenderPC() { return stripPAC(getSenderPCAddr().getAddressAt(0)); }
// Remove any embedded pointer authentication code from an address.
private Address stripPAC(Address addr) {
// Really we should use the XPACI instruction to do this but we
// can't access that from Java so rely on the mask of PAC bits
// calculated by vm_version_aarch64.cpp on startup.
if (ropProtectionField.getValue() != 0) {
return addr.andWithMask(pacMaskField.getValue());
} else {
return addr;
}
}
// return address of param, zero origin index.
public Address getNativeParamAddr(int idx) {