This is an archive of the discontinued LLVM Phabricator instance.

Add ptrace register access for AArch64 SVE registers
ClosedPublic

Authored by omjavaid on May 10 2020, 11:48 PM.

Details

Summary

This patch adds NativeRegisterContext_arm64 ptrace routines to access AArch64 SVE registers. This patch also adds a test-case to test AArch64 SVE registers dynamic configuration and read/write.

This patch is part from previously submitted AArch64 SVE register access support.

Diff Detail

Event Timeline

omjavaid created this revision.May 10 2020, 11:48 PM
omjavaid updated this revision to Diff 263935.May 14 2020, 1:29 AM

This new updated patch overrides GetRegisterInfoAtIndex in NativeRegisterContextLinux_arm64 to reduce the impacts of register numbering conversion on the generic LLGS code.

omjavaid updated this revision to Diff 271528.Jun 17 2020, 5:07 PM

This update remove skipping over register infos requirement by overlapping sve register numbers with debug register numbers which are not required by Linux register context.

omjavaid updated this revision to Diff 275038.Jul 2 2020, 3:14 AM

This update remove dependence over generic interfaces by calling ConfigureRegisterContext on every call to ReadRegister/WriteRegister.

omjavaid updated this revision to Diff 276964.Jul 10 2020, 2:36 AM

This update incorporates suggestion from last iteration and also rebases after merger of register sets and register infos in RegisterInfosPOSIX_arm64.
Also I have posted a separate patch D83541 to make lldb/source/Plugins/Process/Linux/LinuxPTraceDefines_arm64sve.h platform independent in order to use them with elf-core.

@labath what do you think ?

omjavaid updated this revision to Diff 277703.Jul 14 2020, 1:36 AM

This update makes changes to avoid dependence on lldb-arm64-register-enums.h. Also provides rebased version after update of parent patches.

omjavaid updated this revision to Diff 278127.Jul 15 2020, 3:17 AM

Updated and re-based after changes in core file patch

omjavaid updated this revision to Diff 278718.Jul 17 2020, 4:20 AM

This revision updates SVE ptrace support to reflect changes we made in SVE core file support specially around handling of FPSR and FPCR.

I haven't looked at all the sve details, but they seem very similar to the core file stuff, so I think they should be fine. I have some other comments though...

lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
240

What's the relationship of this function and the InvalidateAllRegisters function we added (for arm64 benefit) a couple of reviews back? Can we just have one of them?

lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
22

At this point, that header is sufficiently different from the asm/ptrace.h implementation (names of all structs and fields are different) that I don't think it makes sense to use it as an optional replacement. It makes it very likely things will not build in one of the modes.

This should either use the system version (and then only build when the system has the appropriate headers), or we should use the in-house version unconditionally (which may require renaming/namespacing the rest of the file so that it does not conflict with the real asm/ptrace.h).

lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/TestSVERegisters.py
23

It would be better to have this actually detect the availability of the feature. A skip-always test is not very convincing.

IIRC, some of the tests for fancy x86 registers have the inferior detect the availability of the feature (via the cpuid instruction or something), and then exit with a predefined exit code. Then the test can check for that and skip itself if the feature is not available. Would something like that work here?

76

you don't need to set this twice

lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/main.c
3–5

In our newer register tests we use the pattern where the debugger sets the register values, which are then read back through the inferior (and vice versa). I thing this is a good thing as it avoids the possibility of making symmetrical bugs in the read/write code, which will then appear to modify the register successfully, but they won't actually change the value observed by the inferior process.

omjavaid marked 3 inline comments as done.Jul 22 2020, 7:47 PM
omjavaid added inline comments.
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
240

Both InvalidateAllRegisters and ConfigureRegisterContext are inter related.

The idea is to maintain a cache of SVE register configurations created after thread stop on first call to ReadRegister/WriteRegister, using ConfigureRegisterContext. This configuration cache is maintained unless we do register write or we issue a step or resume.

InvalidateAllRegisters is called before resume and it will invalidate all cached register data including SVE configuration thus forcing us to do ConfigureRegisterContext on stop.

There is also a case where we need to reconfigure register context when we write vector granule register and need to update register sizes and offsets and sync them up between LLDB client and server. That case is handled by the child revisions of this patch.

lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
22

Ack.

lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/main.c
3–5

In this test we are also doing the same please have a look at TestSVERegisters.py:140-142.

The code in main.c is used to make sure we enable SVE mode. AArch64 SVE mode is enabled by Linux kernel on first execution of SVE code.

omjavaid marked an inline comment as done.Jul 22 2020, 8:29 PM
omjavaid added inline comments.
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
22

asm/ptrace.h also describes legacy structs for fpsimd access, hardware breakpoint structs and other related ptrace access. Newer versions of ptrace only append SVE specific structs and macros. In house LLDB's SVE macros file only include SVE specific register names. I dont see any conflict since I have also added a guard for multiple definitions in LinuxPTraceDefines_arm64sve.h as it protects against builds of AArch64/Linux where ThreadElfCore also includes sigcontext and ptrace.h for accessing elf-core related struct definitions.

omjavaid updated this revision to Diff 280037.Jul 23 2020, 12:09 AM

This update fixes issues highlighted in last review iteration.

@labath any further action on this?

labath added inline comments.Jul 23 2020, 4:22 AM
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
240

Right, it's that inter-relatedness that worries me. Back when we were talking about InvalidateAllRegisters we (I) decided that it was simpler to call it before a thread resumes. I'm wondering if that wasn't a mistake.

Like, if we called InvalidateAllRegisters when a thread stops, then you could use this opportunity to initialize the SVE configuration, right? And that would avoid the need to call ConfigureRegisterContext on every register read operation? Obviously there'd still need to be some reconfiguration/invalidation of the SVE context after some register writes, but that would be similar to us invalidating the GPR cache when the GPR registers get written.

Basically, it seems to me that would make things more homogeneous.

lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
22

I'm not saying we shouldn't include asm/ptrace.h at all. It obviously contains a lot of useful stuff, and we wouldn't want to duplicate all of that.

What I am saying is that for the stuff that we already have duplicated, we just be using that unconditionally. Doing otherwise just needlessly forks the build matrix and creates opportunities for things to not work in one mode or the other. We're already committed to ensuring things work with the in-house definitions so why bothering to ensure that things work both with them _and_ with the system ones.

lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/main.c
3–5

I have a feeling we're misunderstanding each other. I am talking about the tests in test/Shell/Register (e.g. x86-64-xmm16-read.test, x86-64-xmm16-write.test). This test definitely doesn't to that. The code in 140-142 is just reading back what was written by lines 135-137, not values set by the inferior.

omjavaid marked 3 inline comments as done.Jul 23 2020, 8:27 PM
omjavaid added inline comments.
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
240

Agreed. I can give that a shot that probably was the original idea behind InvalidateAllRegisters.

lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
22

Right now SVE in-house macros and the ones in asm/ptrace.h are identical. If we include asm/ptrace.h and it already has SVE macros we cannot avoid that inclusion so in case we want to force use of in-house macros we ll have to rename the in-house macros and headers with LLVM_ or LLDB_ prefix to make sure we avoid duplication. If you have strong opinion in favor of renaming i can go ahead and do that.

lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/main.c
3–5

The problem in case of SVE is that size of vector is unknown untill we run therefore we cannot hard write value that will be written and read back.
Also this API based test actually verifies that vector granule register value and Z/P register sizes make sense. It then prepares a value to be written to Z, P or FFr registers based on currently configured vector length and the read that same value back. I could not find a way to do that using shell based tests.

omjavaid updated this revision to Diff 280373.Jul 24 2020, 2:01 AM

In this update I have moved ConfigureRegisterContext insider InvalidateAllRegisters in light of D84501 where we move InvalidateAllRegisters on every stop rather than doing so before step/resume

labath added inline comments.Jul 27 2020, 1:34 AM
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
22

I do, actually. Given that this code is also used for the core files, which can be used from any host, and the fact that we have already started making changes to it because of that (_uNN vs uintNN_t, the msvc compatibility patch, etc), I think we just just treating this as a part of our codebase and not some asm/ptrace addon.

I wouldn't tack an additional LLDB_ onto the names though. What I'd do is replace all of these macros with regular C(++) symbols. Parameter-less macros can be constants and function-like macros can just be functions. They can keep the original all-caps spelling to make it clear where they are coming from, but in order to distinguish them from the system symbols we can make a tiny modification -- instead of naming everyting SVE_FOO, we name the thing just FOO, but put it inside a lldb_private::SVE namespace -- that way the symbols can be referred to as SVE::FOO.

lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/main.c
3–5

Right. While it would definitely be nice if this test was next to the other ones, rewriting this as a lit test is not what I was going for. I think these are sufficiently special to handle them this way.

What I was referring to is the general principle of setting the registers in the inferior (via asm or something) and then reading them from the test. That principle applies no matter which style is the test written in.

omjavaid updated this revision to Diff 284328.Aug 10 2020, 5:36 AM

This patch fixes review items from last review cycles. Now we do not use LinuxPTraceDefines_arm64sve.h for NativeProcessLinux_arm64 as these defs are already back ported into libc ptrace.h available on most distros. LLDB arm64 build bot and release builders should already have the header included.

We have updated LinuxPTraceDefines_arm64sve.h in D85641 where macros are converted into c++ consts and inlines.

Also test case now include ASM writing of by all SVE registers and they are read back and verified by the test case. I have also retained the writing test that was already there previously.

@labath Any further action needed on this change? I have updated test main.c for doing asm write to SVE regs and then reading them back during testing. Also i have removed NativeProcessLinux_arm64 dependence on LinuxPTraceDefines_arm64sve.h. We are using sys root's ptrace.h as SVE marcros are back ported in most versions of ptrace.h.

@labath Any further action needed on this change? I have updated test main.c for doing asm write to SVE regs and then reading them back during testing. Also i have removed NativeProcessLinux_arm64 dependence on LinuxPTraceDefines_arm64sve.h. We are using sys root's ptrace.h as SVE marcros are back ported in most versions of ptrace.h.

Almost. I have two more questions/requests inline.

lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/TestSVERegisters.py
101–107

Are you sure this will work if the system does not support SVE? I would expect the test application to die from SIGILL (or something) long before we reach this part.

Even if it does work, it will mean that the test will be skipped (instead of failing) if the lldb-server stops reporting the sve registers (or even if it just slightly changes the register set name). That's why I was originally suggesting to check for SVE support from within the inferior process.

Is there a simple way to do that? I'm assuming there must be, otherwise the application could not detect whether it can use sve...

135

So, the program sets all p registers to the same value (0xffff..) right? Would it be possible to introduce some variance there (like you did for the z registers), to ensure that the registers are actually read from the right place?

omjavaid updated this revision to Diff 285956.Aug 17 2020, 4:03 AM

This update adds check for SVE support using /proc/cpuinfo in SVE testcases. Also tests case to read predicate registers with 5 different values instead of 0xff.

@labath this seems reasonable now?

labath accepted this revision.Aug 18 2020, 9:51 AM

Looks good, just the cpuinfo detection function could use a bit of improvement.

Thanks for your patience.

lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/TestSVERegisters.py
23

This will put the file into the CWD, which is in the source tree. This should be self.getBuildArtifact(cpuinfo), and then you don't need the tear down hook.

Also, "platform get-file" (or SBPlatform::Get) should also work on local setups.

This revision is now accepted and ready to land.Aug 18 2020, 9:51 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 19 2020, 3:11 AM