1/* 2 * Copyright (c) 2016 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29#include <arm64/asm.h> 30#include <pexpert/arm64/board_config.h> 31#include <arm64/proc_reg.h> 32 33/* 34 * Compare two instructions with constant, spin on mismatch. 35 * arg0 - Constant scratch register 36 * arg1 - Instruction address scratch register 37 * arg2 - Instruction location 38 * arg3 - Instruction constant 39 */ 40.macro check_instruction 41 // construct 64-bit constant inline to make sure it is non-executable 42 movz $0, #(($3 >> 48) & 0xffff), lsl #48 43 movk $0, #(($3 >> 32) & 0xffff), lsl #32 44 movk $0, #(($3 >> 16) & 0xffff), lsl #16 45 movk $0, #(($3) & 0xffff) 46 // fetch instructions from "untrusted" memory 47 adrp $1, $2@page 48 add $1, $1, $2@pageoff 49 ldr $1, [$1] 50 // spin forever if we do not find what we expect 51 cmp $0, $1 52 b.ne . 53.endmacro 54 55#if defined(KERNEL_INTEGRITY_KTRR) 56 57/* AMCC only KTRR protected text, non-executable once the MMU is enabled */ 58 .text 59 .section __LAST,__pinst 60 .align 2 61 62__pinst_set_ttbr1: 63 msr TTBR1_EL1, x0 64 ret 65 66__pinst_set_vbar: 67 msr VBAR_EL1, x0 68 ret 69 70__pinst_set_tcr: 71 msr TCR_EL1, x0 72 ret 73 74 .globl _pinst_set_sctlr_trap_addr 75__pinst_set_sctlr: 76 msr SCTLR_EL1, x0 77_pinst_set_sctlr_trap_addr: 78 ret 79 80 81/* MMU and AMCC KTRR protected text */ 82 .text 83 .section __TEXT_EXEC,__text 84 .align 2 85 86 .globl _pinst_set_ttbr1 87_pinst_set_ttbr1: 88 ARM64_PROLOG 89 check_instruction x2, x3, __pinst_set_ttbr1, 0xd65f03c0d5182020 90 b __pinst_set_ttbr1 91 92 .globl _pinst_set_vbar 93_pinst_set_vbar: 94 ARM64_PROLOG 95 check_instruction x2, x3, __pinst_set_vbar, 0xd65f03c0d518c000 96 b __pinst_set_vbar 97 98 .globl _pinst_set_tcr 99_pinst_set_tcr: 100 ARM64_PROLOG 101 check_instruction x2, x3, __pinst_set_tcr, 0xd65f03c0d5182040 102 b __pinst_set_tcr 103 104 .globl _pinst_set_sctlr 105_pinst_set_sctlr: 106 ARM64_PROLOG 107 check_instruction x2, x3, __pinst_set_sctlr, 0xd65f03c0d5181000 108 b __pinst_set_sctlr 109 110#endif /* defined(KERNEL_INTEGRITY_KTRR) */ 111 112#if defined(KERNEL_INTEGRITY_KTRR) || defined(KERNEL_INTEGRITY_CTRR) 113 114 .text 115 .section __LAST,__pinst 116 .align 2 117 118__pinst_spsel_1: 119 msr SPSel, #1 120 ret 121 122 .text 123 .section __TEXT_EXEC,__text 124 .align 2 125 126 .globl _pinst_spsel_1 127_pinst_spsel_1: 128 ARM64_PROLOG 129 check_instruction x2, x3, __pinst_spsel_1, 0xd65f03c0d50041bf 130 b __pinst_spsel_1 131 132#endif /* defined(KERNEL_INTEGRITY_KTRR) || defined(KERNEL_INTEGRITY_CTRR) */ 133 134