Skip to content

Commit

Permalink
arm64: Use the PAN msr mnemonic rather than .inst
Browse files Browse the repository at this point in the history
Switch from creating the msr instructions to manage PAN to use the
"msr pan, #1" instruction directly. When this was added clang didn't
have support to assemble the instructions. This appears to have been
added to clang 13 which is sufficiently old enough.

Binutils releases from around the same time appear to have added this
instruction so any modern gcc should also support this instruction.

Sponsored by:	Arm Ltd
Differential Revision:	https://reviews.freebsd.org/D47817
  • Loading branch information
zxombie committed Dec 12, 2024
1 parent 8d723aa commit 6990c99
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 9 deletions.
10 changes: 4 additions & 6 deletions sys/arm64/arm64/machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,19 +187,17 @@ pan_enable(void)
{

/*
* The LLVM integrated assembler doesn't understand the PAN
* PSTATE field. Because of this we need to manually create
* the instruction in an asm block. This is equivalent to:
* msr pan, #1
*
* This sets the PAN bit, stopping the kernel from accessing
* memory when userspace can also access it unless the kernel
* uses the userspace load/store instructions.
*/
if (has_pan) {
WRITE_SPECIALREG(sctlr_el1,
READ_SPECIALREG(sctlr_el1) & ~SCTLR_SPAN);
__asm __volatile(".inst 0xd500409f | (0x1 << 8)");
__asm __volatile(
".arch_extension pan \n"
"msr pan, #1 \n"
".arch_extension nopan \n");
}
}

Expand Down
12 changes: 9 additions & 3 deletions sys/arm64/include/asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,25 @@
ldr tmp, =has_pan; /* Get the addr of has_pan */ \
ldr reg, [tmp]; /* Read it */ \
cbz reg, 997f; /* If no PAN skip */ \
.inst 0xd500409f | (0 << 8); /* Clear PAN */ \
.arch_extension pan; \
msr pan, #0; /* Disable PAN checks */ \
.arch_extension nopan; \
997:

#define EXIT_USER_ACCESS(reg) \
cbz reg, 998f; /* If no PAN skip */ \
.inst 0xd500409f | (1 << 8); /* Set PAN */ \
.arch_extension pan; \
msr pan, #1; /* Enable PAN checks */ \
.arch_extension nopan; \
998:

#define EXIT_USER_ACCESS_CHECK(reg, tmp) \
ldr tmp, =has_pan; /* Get the addr of has_pan */ \
ldr reg, [tmp]; /* Read it */ \
cbz reg, 999f; /* If no PAN skip */ \
.inst 0xd500409f | (1 << 8); /* Set PAN */ \
.arch_extension pan; \
msr pan, #1; /* Enable PAN checks */ \
.arch_extension nopan; \
999:

/*
Expand Down

0 comments on commit 6990c99

Please sign in to comment.