Skip to content
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

GCS ACLE #260

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

GCS ACLE #260

wants to merge 4 commits into from

Conversation

nsz-arm
Copy link

@nsz-arm nsz-arm commented May 31, 2023


name: Pull request
about: Technical issues, document format problems, bugs in scripts or feature proposal.


Thank you for submitting a pull request!

If this PR is about a bugfix:

Please use the bugfix label and make sure to go through the checklist below.

If this PR is about a proposal:

We are looking forward to evaluate your proposal, and if possible to
make it part of the Arm C Language Extension (ACLE) specifications.

We would like to encourage you reading through the contribution
guidelines
, in particular the section on submitting
a proposal
.

Please use the proposal label.

As for any pull request, please make sure to go through the below
checklist.

Checklist: (mark with X those which apply)

  • If an issue reporting the bug exists, I have mentioned it in the
    PR (do not bother creating the issue if all you want to do is
    fixing the bug yourself).
  • I have added/updated the SPDX-FileCopyrightText lines on top
    of any file I have edited. Format is SPDX-FileCopyrightText: Copyright {year} {entity or name} <{contact informations}>
    (Please update existing copyright lines if applicable. You can
    specify year ranges with hyphen , as in 2017-2019, and use
    commas to separate gaps, as in 2018-2020, 2022).
  • I have updated the Copyright section of the sources of the
    specification I have edited (this will show up in the text
    rendered in the PDF and other output format supported). The
    format is the same described in the previous item.
  • I have run the CI scripts (if applicable, as they might be
    tricky to set up on non-*nix machines). The sequence can be
    found in the contribution
    guidelines
    . Don't
    worry if you cannot run these scripts on your machine, your
    patch will be automatically checked in the Actions of the pull
    request.
  • I have added an item that describes the changes I have
    introduced in this PR in the section Changes for next
    release
    of the section Change Control/Document history
    of the document. Create Changes for next release if it does
    not exist. Notice that changes that are not modifying the
    content and rendering of the specifications (both HTML and PDF)
    do not need to be listed.
  • When modifying content and/or its rendering, I have checked the
    correctness of the result in the PDF output (please refer to the
    instructions on how to build the PDFs
    locally
    ).
  • The variable draftversion is set to true in the YAML header
    of the sources of the specifications I have modified.
  • Please DO NOT add my GitHub profile to the list of contributors
    in the README page of the project.

Copy link
Contributor

@DanielKristofKiss DanielKristofKiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with small comments.

main/acle.md Outdated

To use the intrinsics, `arm_acle.h` needs to be included.

The intrinsics are available if `__ARM_FEATURE_GCS_DEFAULT` is defined,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intrinsics would be always available because there could be cases when the intrinsics is called in the right context but the whole translation unit is not compiled with GCS. (e.g. target attribute or FMV)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not against making intrinsics always available, but for GCS the intrinsics are only useful if GCS is enabled, and that can only be enabled if everything is compiled in GCS compatible mode, so there is not really any context when __ARM_FEATURE_GCS_DEFAULT is undef but you want the intrinsics anyway.

main/acle.md Outdated
but they can only be called if GCS instructions are supported.

The `__chkfeat` intrinsics with `_CHKFEAT_GCS` can be used to check
if GCS protection is enabled at runtime. If GCS protection is enabled
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

superfluous space before If GCS

main/acle.md Outdated
```

Reads and returns the last entry on the GCS of the current thread and
updates the GCS pointer to point to the previous entry. If GCS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

superfluous space before If GCS

main/acle.md Outdated
```

Switches the GCS of the current thread, where the argument is the new
GCS pointer, and returns the old GCS pointer. If GCS protection is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

superfluous space before If GCS

@@ -2937,6 +2948,18 @@ inclusive. See implementation documentation for the effect (if any) of
this instruction and the meaning of the argument. This is available only
when compiling for AArch32.

``` c
uint64_t __chkfeat(uint64_t);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behaviour of this intrinsic is opposite that of the instruction (chkfeat instruction clears the bit if the feature is enabled), which I think is unique among intrinsics. It would be worthwhile specifically noting this.

Also "feature is available" should be "feature is enabled" (as the chkfeat instruction will leave the bit alone if the feature is available but disabled).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to write/read this code in applications:
if( __chkfeat(_CHKFEAT_GCS)) { // do GCS stuff. }
chkfeat must clear the bit if the feature is present due to it is a NOP on old CPUs where it won't change the register content.
That logic twist is not required for the app developers.

+1 for the

Also "feature is available" should be "feature is enabled"


Reads and returns the last entry on the GCS of the current thread and
updates the GCS pointer to point to the previous entry. If GCS
protection is disabled then it has no side effect and returns `0`.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gcspopm instruction does nothing when gcs is disabled (i.e. the value in the destination register is unchanged). Is the intent that the intrinsic sets the destination register to zero before executing the instruction?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, i think this is the only way the intrinsic is usable in the "asynchronously disabled gcs" scenario.

(which we don't know yet if linux will support, currently it does not want to)



``` c
const void *__gcspr(void);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i plan to change this back to non-const so that the intrinsics support the gcs write access enabled case (even if that's not expected to be a common setting).

Copy link
Contributor

@DanielKristofKiss DanielKristofKiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, let see what others think.
NIT maybe the draft could be dropped now from the name of the PR.

@nsz-arm
Copy link
Author

nsz-arm commented Nov 15, 2023

NIT maybe the draft could be dropped now from the name of the PR.

potential issues with current spec:

  • gcs store intrinsic is missing
  • const void* vs void* gcs (modified by bl/ret/... instructions, but normal c language stores don't work on it)
  • intrinsic availability check (feature test macros no longer imply intrinsics)

@john-brawn-arm
Copy link

john-brawn-arm commented Jun 4, 2024

  • gcs store intrinsic is missing

I'm not sure we need this. We can always add it later if there's a need.

  • const void* vs void* gcs (modified by bl/ret/... instructions, but normal c language stores don't work on it)

I think we only really need the pointer to be non-const if we have a gcs store intrinsic. constness is only about if the user is permitted to write to something, so entries on the gcs stack being modified by bl/ret isn't relevant.

  • intrinsic availability check (feature test macros no longer imply intrinsics)

Is this about #214? I think the way GCS intrinsics are currently described is OK with regards to that (though I have a couple of comments on the wording).

main/acle.md Outdated

To use the intrinsics, `arm_acle.h` needs to be included.

The intrinsics are only valid to call when GCS instructions are

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"The intrinsics are only valid to call" should be "These intrinsics are available" (that's the wording we use elsewhere).

main/acle.md Outdated
Comment on lines 4617 to 4620
to check if GCS protection is enabled at runtime. If GCS protection is
enabled then GCS instructions are supported and the code was compiled
in a GCS protection compatible way (`__ARM_FEATURE_GCS_DEFAULT` was
defined).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The final sentence here is a bit weird and I'm not sure what exactly it's saying. I think what it's saying is that "GCS enabled implies GCS available", i.e. if you have if (__chkfeat(_CHKFEAT_GCS)) { } then you know GCS must be available inside that block, or perhaps the other way around that if you know GCS isn't available then you know __chkfeat(_CHKFEAT_GCS) will never return true.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah this should be worded better, or removed.

i was trying to point out that the runtime will only enable GCS if all code is built with GCS support, so if __chkfeat check returns true, that implies __ARM_FEATURE_GCS_DEFAULT, no need to check that separately.

@nsz-arm nsz-arm changed the title GCS ACLE draft GCS ACLE Jun 12, 2024
@john-brawn-arm
Copy link

LGTM.

Copy link
Contributor

@DanielKristofKiss DanielKristofKiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

main/acle.md Outdated

`__ARM_FEATURE_GCS_DEFAULT` is defined to `1` if the code generation is
compatible with enabling the Guarded Control Stack (GCS) extension based
protection. It is undefined otherwise.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
protection. It is undefined otherwise.
protection. It is undefined otherwise.

main/acle.md Outdated
protection. It is undefined otherwise.

`__ARM_FEATURE_GCS` is defined to `1` if the Guarded Control Stack (GCS)
extension is available on the target. It is undefined otherwise.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
extension is available on the target. It is undefined otherwise.
extension is available on the target. It is undefined otherwise.

john-brawn-arm added a commit to john-brawn-arm/llvm-project that referenced this pull request Jun 27, 2024
This adds intrinsics defined in ARM-software/acle#260

Doing this requires some changes to the GCS instruction definitions,
as these intrinsics make use of how some instructions don't modify the
input register when GCS is disabled, and they need to be correctly
marked with mayLoad/mayStore/hasSideEffects for instruction selection
to work.
john-brawn-arm added a commit to llvm/llvm-project that referenced this pull request Jul 11, 2024
This adds intrinsics defined in ARM-software/acle#260

Doing this requires some changes to the GCS instruction definitions, as
these intrinsics make use of how some instructions don't modify the
input register when GCS is disabled, and they need to be correctly
marked with mayLoad/mayStore/hasSideEffects for instruction selection to
work.
aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
This adds intrinsics defined in ARM-software/acle#260

Doing this requires some changes to the GCS instruction definitions, as
these intrinsics make use of how some instructions don't modify the
input register when GCS is disabled, and they need to be correctly
marked with mayLoad/mayStore/hasSideEffects for instruction selection to
work.
@yury-khrustalev
Copy link

Regarding the return type of __gcspr() and __gcsss() and the argument type of the latter, it is suggested to implement them as void * rather than const void * for reasons explained in this GCC patch's commit message.

In a nutshell, the GCS pointer can be writeable in certain situations: via stack switch operation or via the GCSSTR instruction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants