Re: [PATCH v4 17/36] arm64/mm: Handle GCS data aborts

Mark Brown
2023-08-15T23:54:54Z

[-- Attachment #1.1: Type: text/plain, Size: 1850 bytes --]

On Fri, Aug 11, 2023 at 04:09:33PM +0100, Catalin Marinas wrote:
> On Mon, Aug 07, 2023 at 11:00:22PM +0100, Mark Brown wrote:

> > + if (is_write_abort(esr) &&
> > + !(is_gcs_fault(esr) || is_el1_data_abort(esr)))
> > + return VM_FAULT_BADACCESS;

> Related to my PIE permissions comment: when do we have a valid EL1 data
> write abort that's not a GCS fault? Does a faulting GCSSTTR set the
> ESR_ELx_GCS bit?

Yes, it should do. The GCS instructions have access descriptors created
with CreateAccDescGCS() which results in the access being flagged as a
GCS access.

> > + } else {
> > + /*
> > + * GCS faults should never happen for pages that are
> > + * not part of a GCS and the operation being attempted
> > + * can never succeed.
> > + */
> > + if (is_gcs_fault(esr))
> > + return VM_FAULT_BADACCESS;

> If one does a GCS push/store to a non-GCS page, do we get a GCS fault or
> something else? I couldn't figure out from the engineering spec. If the
> hardware doesn't generate such exceptions, we might as well remove this
> 'else' branch. But maybe it does generate a GCS-specific fault as you
> added a similar check in is_invalid_el0_gcs_access().

Yes, see AddGCSRecord() and LoadCheckGCSRecord() - all GCS initiated
accesses need to be AccDescGCS so appropriate permissions enforcement
can happen and that's what causes the fault to be flagged as GCS.

> > @@ -595,6 +644,19 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
> > if (!vma)
> > goto lock_mmap;
> >
> > + /*
> > + * We get legitimate write faults for GCS pages from GCS
> > + * operations and from EL1 writes to EL0 pages but just plain

> What are the EL1 writes to the shadow stack? Would it not use
> copy_to_user_gcs()?

They should, yes - I'll reword the comment.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 161 bytes --]