probes: consolidate ID register forging into idregs.h
This commit is contained in:
1 parent
6c756de34c
commit
a552920894
3 files changed
+30
-21
No files matched your search
@@ -72,4 +72,24 @@ static uint64_t id_register(uint32_t crm, uint32_t op2)
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/* Features this machine does not have, cleared out of the ID registers.
|
||||
*
|
||||
* XNU believes what the ID registers say and then uses it. Left alone, the
|
||||
* Snapdragon advertises SME, so XNU wrote SMCR_EL1 and then `msr TPIDR2_EL0,
|
||||
* xzr` at 0xfffffe000c245030 -- undefined here, and delivered to EL1 where we
|
||||
* cannot see it. Every feature we cannot actually support has to be denied at
|
||||
* the source rather than caught after the fact. */
|
||||
#define ID_AA64PFR0_EL1_SVE (0xfUL << 32)
|
||||
#define ID_AA64PFR1_EL1_SME (0xfUL << 24)
|
||||
|
||||
static uint64_t id_forge(uint32_t crm, uint32_t op2, uint64_t value)
|
||||
{
|
||||
if (crm == 4 && op2 == 0) value &= ~ID_AA64PFR0_EL1_SVE; /* ID_AA64PFR0 */
|
||||
if (crm == 4 && op2 == 1) value &= ~ID_AA64PFR1_EL1_SME; /* ID_AA64PFR1 */
|
||||
if (crm == 4 && op2 == 4) value = 0; /* ID_AA64ZFR0 */
|
||||
if (crm == 4 && op2 == 5) value = 0; /* ID_AA64SMFR0 */
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -5984,7 +5984,6 @@ int xnuboot_async(uint64_t elr, uint64_t which, const uint64_t *frame)
|
||||
* word and the host reads it as a signed 64-bit value, so a 32-bit -6 arrives
|
||||
* as 0x00000000fffffffa and reads as an EL2 fault with a nonsense ESR. */
|
||||
static int64_t vcpu_arch_prepare(struct context *c);
|
||||
static uint64_t id_forge(uint32_t crm,uint32_t op2,uint64_t value);
|
||||
static int secondary_prepare_records(struct context *c);
|
||||
int64_t xnuboot_prepare(void);
|
||||
static int pauth_domain_prepare(struct context *c)
|
||||
@@ -9715,24 +9714,6 @@ static int multipage_fast(struct context *c,const struct sptm_multipage_plan *pl
|
||||
#define SR_CONST_LOWER SYSREG(3, 0, 11, 1, 2)
|
||||
#define SR_CONST_UPPER SYSREG(3, 0, 11, 1, 3)
|
||||
|
||||
/* Features this machine does not have, cleared out of the ID registers.
|
||||
*
|
||||
* XNU believes what the ID registers say and then uses it. Left alone, the
|
||||
* Snapdragon advertises SME, so XNU wrote SMCR_EL1 and then `msr TPIDR2_EL0,
|
||||
* xzr` at 0xfffffe000c245030 -- undefined here, and delivered to EL1 where we
|
||||
* cannot see it. Every feature we cannot actually support has to be denied at
|
||||
* the source rather than caught after the fact. */
|
||||
#define ID_AA64PFR0_EL1_SVE (0xfUL << 32)
|
||||
#define ID_AA64PFR1_EL1_SME (0xfUL << 24)
|
||||
|
||||
static uint64_t id_forge(uint32_t crm, uint32_t op2, uint64_t value)
|
||||
{
|
||||
if (crm == 4 && op2 == 0) value &= ~ID_AA64PFR0_EL1_SVE; /* ID_AA64PFR0 */
|
||||
if (crm == 4 && op2 == 1) value &= ~ID_AA64PFR1_EL1_SME; /* ID_AA64PFR1 */
|
||||
if (crm == 4 && op2 == 4) value = 0; /* ID_AA64ZFR0 */
|
||||
if (crm == 4 && op2 == 5) value = 0; /* ID_AA64SMFR0 */
|
||||
return value;
|
||||
}
|
||||
|
||||
/* AMX is not optional to this kernel. `machine_routines_apple.c:165` decodes
|
||||
* AMXIDR_EL1 as a version: bits 0..5 select versions 1..6, anything set in bits
|
||||
|
||||
+10
-2
@@ -53,7 +53,14 @@ import unittest
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
HEADER = (ROOT / 'probes/idregs.h').read_text()
|
||||
SOURCE = (ROOT / 'probes/xnuboot.c').read_text()
|
||||
LLVM = Path('/opt/homebrew/opt/llvm/bin')
|
||||
_LLVM_BIN = os.environ.get('LLVM_BIN')
|
||||
if _LLVM_BIN:
|
||||
LLVM = Path(_LLVM_BIN)
|
||||
elif Path('/opt/homebrew/opt/llvm/bin/llvm-mc').exists():
|
||||
LLVM = Path('/opt/homebrew/opt/llvm/bin')
|
||||
else:
|
||||
_mc = shutil.which('llvm-mc')
|
||||
LLVM = Path(_mc).parent if _mc else Path('/usr/bin')
|
||||
|
||||
# The allocated AArch64 ID registers of op0=3, op1=0, CRn=0, by (CRm, op2): Arm ARM (DDI 0487), the AArch64
|
||||
# System register index. Everything else in CRm 0-7 is unallocated (CRm=0) or reserved (CRm 1-7).
|
||||
@@ -222,7 +229,8 @@ class Source(unittest.TestCase):
|
||||
self.assertEqual(SOURCE.count(HANDLER), 1)
|
||||
branch = SOURCE[SOURCE.index('if (op0 == 3 && op1 == 0 && crn == 0 && crm < 8 && (iss & 1)) {'):]
|
||||
self.assertTrue(branch[:200].split('\n')[1].strip() == HANDLER)
|
||||
forge = SOURCE[SOURCE.index('static uint64_t id_forge(uint32_t crm, uint32_t op2, uint64_t value)\n{'):]
|
||||
forge_src = HEADER if 'static uint64_t id_forge(' in HEADER else SOURCE
|
||||
forge = forge_src[forge_src.index('static uint64_t id_forge(uint32_t crm, uint32_t op2, uint64_t value)\n{'):]
|
||||
forge = forge[:forge.index('\n}\n')]
|
||||
pairs = {(int(a), int(b)) for a, b in re.findall(r'crm == (\d) && op2 == (\d)', forge)}
|
||||
self.assertEqual(pairs, {(4, 0), (4, 1), (4, 4), (4, 5)})
|
||||
|
||||
Reference in new issue
Block a user