3 // Copyright (c) 2020 Metempsy Technology Consulting
6 // The license below extends only to copyright in the software and shall
7 // not be construed as granting a license to any other intellectual
8 // property including but not limited to intellectual property relating
9 // to a hardware implementation of the functionality of the software
10 // licensed hereunder. You may use the software subject to the license
11 // terms below provided that you ensure that this notice is replicated
12 // unmodified and in its entirety in all distributions of the software,
13 // modified or unmodified, in source code or in binary form.
15 // Redistribution and use in source and binary forms, with or without
16 // modification, are permitted provided that the following conditions are
17 // met: redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer;
19 // redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution;
22 // neither the name of the copyright holders nor the names of its
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
26 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include "arch/arm/pauth_helpers.hh"
40 #include "arch/arm/faults.hh"
41 #include "base/bitfield.hh"
43 using namespace ArmISA
;
47 ArmISA::calculateTBI(ThreadContext
* tc
, ExceptionLevel el
,
48 uint64_t ptr
, bool data
)
51 if (upperAndLowerRange(tc
, el
)) {
53 ExceptionLevel s1_el
= s1TranslationRegime(tc
, el
);
54 assert (s1_el
== EL1
|| s1_el
== EL2
);
55 TCR tcr
= (s1_el
== EL1
) ? tc
->readMiscReg(MISCREG_TCR_EL1
):
56 tc
->readMiscReg(MISCREG_TCR_EL2
);
57 bool b55
= bits(ptr
, 55) == 1;
59 tbi
= b55
? tcr
.tbi1
== 1 : tcr
.tbi0
== 1;
61 tbi
= b55
? (tcr
.tbi1
== 1 && tcr
.tbid1
== 0) :
62 (tcr
.tbi0
== 1 && tcr
.tbid0
== 0);
66 TCR tcr
= tc
->readMiscReg(MISCREG_TCR_EL2
);
67 tbi
= data
? tcr
.tbi
== 1 : (tcr
.tbi
== 1 && tcr
.tbid
== 0);
70 TCR tcr
= tc
->readMiscReg(MISCREG_TCR_EL3
);
71 tbi
= data
? tcr
.tbi
== 1 : (tcr
.tbi
== 1 && tcr
.tbid
== 0);
77 ArmISA::calculateBottomPACBit(ThreadContext
* tc
, ExceptionLevel el
,
82 if (upperAndLowerRange(tc
, el
)) {
83 ExceptionLevel s1_el
= s1TranslationRegime(tc
, el
);
84 assert (s1_el
== EL1
|| s1_el
== EL2
);
86 // EL1 translation regime registers
87 TCR tcr
= tc
->readMiscReg(MISCREG_TCR_EL1
);
88 tsz_field
= top_bit
? (uint32_t)tcr
.t1sz
: (uint32_t)tcr
.t0sz
;
89 using64k
= top_bit
? tcr
.tg1
== 0x3 : tcr
.tg0
== 0x1;
91 // EL2 translation regime registers
92 TCR tcr
= tc
->readMiscReg(MISCREG_TCR_EL2
);
93 assert (ArmSystem::haveEL(tc
, EL2
));
94 tsz_field
= top_bit
? (uint32_t)tcr
.t1sz
: (uint32_t)tcr
.t0sz
;
95 using64k
= top_bit
? tcr
.tg1
== 0x3 : tcr
.tg0
== 0x1;
98 TCR tcr2
= tc
->readMiscReg(MISCREG_TCR_EL2
);
99 TCR tcr3
= tc
->readMiscReg(MISCREG_TCR_EL3
);
100 tsz_field
= el
== EL2
? (uint32_t)tcr2
.t0sz
: (uint32_t)tcr3
.t0sz
;
101 using64k
= el
== EL2
? tcr2
.tg0
== 0x1 : tcr3
.tg0
== 0x1 ;
103 uint32_t max_limit_tsz_field
= using64k
? 47 : 48;
104 tsz_field
= min(tsz_field
, max_limit_tsz_field
);
105 const AA64MMFR2 mm_fr2
= tc
->readMiscReg(MISCREG_ID_AA64MMFR2_EL1
);
107 uint32_t tszmin
= (using64k
&& (bool)mm_fr2
.varange
) ? 12 : 16;
108 tsz_field
= max(tsz_field
, tszmin
);
110 return (64-tsz_field
);
114 ArmISA::trapPACUse(ThreadContext
*tc
, ExceptionLevel target_el
)
116 assert(ArmSystem::haveEL(tc
, target_el
) &&
117 target_el
!= EL0
&& (target_el
>= currEL(tc
)));
121 return std::make_shared
<HypervisorTrap
>(0x0, 0, EC_TRAPPED_PAC
);
123 return std::make_shared
<SecureMonitorTrap
>(0x0, 0, EC_TRAPPED_PAC
);
130 ArmISA::addPAC (ThreadContext
* tc
, ExceptionLevel el
, uint64_t ptr
,
131 uint64_t modifier
, uint64_t k1
, uint64_t k0
, bool data
)
138 bool tbi
= calculateTBI(tc
, el
, ptr
, data
);
139 int top_bit
= tbi
? 55 : 63;
140 bool b55
= bits(ptr
, 55);
141 bool b63
= bits(ptr
, 63);
142 // If tagged pointers are in use for a regime with two TTBRs,use bit<55> of
143 // the pointer to select between upper and lower ranges, and preserve this.
144 // This handles the awkward case where there is apparently no correct
145 // choice between the upper and lower address range - ie an addr of
146 // 1xxxxxxx0... with TBI0=0 and TBI1=1 and 0xxxxxxx1 with TBI1=0 and TBI0=1
148 if (upperAndLowerRange(tc
, el
)) {
149 ExceptionLevel s1_el
= s1TranslationRegime(tc
, el
);
150 assert (s1_el
== EL1
|| s1_el
== EL2
);
152 // EL1 translation regime registers
153 TCR tcr
= tc
->readMiscReg(MISCREG_TCR_EL1
);
155 selbit
= (tcr
.tbi1
== 1 || tcr
.tbi0
== 1) ? b55
: b63
;
157 selbit
= ((tcr
.tbi1
== 1 && tcr
.tbid1
== 0)
158 || (tcr
.tbi0
== 1 && tcr
.tbid0
== 0)) ? b55
: b63
;
161 // EL2 translation regime registers
162 TCR tcr
= tc
->readMiscReg(MISCREG_TCR_EL2
);
163 bool have_el2
= ArmSystem::haveEL(tc
, EL2
);
165 selbit
= (have_el2
&&
166 (tcr
.tbi0
== 1 || tcr
.tbi1
== 1))? b55
: b63
;
170 selbit
= (have_el2
&&
171 ((tcr
.tbi1
== 1 && tcr
.tbid1
== 0) ||
172 (tcr
.tbi0
== 1 && tcr
.tbid0
== 0)))? b55
: b63
;
176 selbit
= tbi
? b55
: b63
;
179 int bottom_PAC_bit
= calculateBottomPACBit(tc
, el
, selbit
);
180 // The pointer authentication code field takes all the available
183 uint32_t nbits
= (top_bit
+1) - bottom_PAC_bit
;
184 uint64_t pacbits
= ((uint64_t)0x1 << nbits
) -1; // 2^n -1;
185 uint64_t mask
= pacbits
<< bottom_PAC_bit
; // creates mask
188 ext_ptr
= ptr
| mask
;
190 ext_ptr
= ptr
& ~mask
;
193 PAC
= QARMA::computePAC(ext_ptr
, modifier
, k1
, k0
);
194 // Check if the ptr has good extension bits and corrupt the
195 // pointer authentication code if not;
196 uint64_t t
= bits(ptr
, top_bit
, bottom_PAC_bit
);
197 if (t
!= 0x0 && t
!= pacbits
) {
198 PAC
^= ((uint64_t)0x1 << (top_bit
-1));
200 // Preserve the determination between upper and lower address
201 // at bit<55> and insert PAC
203 // ptr<63:56>:selbit:PAC<54:bottom_PAC_bit>:ptr<bottom_PAC_bit-1:0>;
204 result
= ptr
& 0xFF00000000000000;
206 // PAC<63:56>:selbit:PAC<54:bottom_PAC_bit>:ptr<bottom_PAC_bit-1:0>;
207 result
= PAC
& 0xFF00000000000000;
210 uint64_t masked_PAC
= PAC
& 0x007FFFFFFFFFFFFF;
211 uint64_t pacbit_mask
= ((uint64_t)0x1 << bottom_PAC_bit
) -1;
212 uint64_t masked_ptr
= ptr
& pacbit_mask
;
214 masked_PAC
&= ~pacbit_mask
;
215 result
|= ((uint64_t)selbit
<< 55) | masked_PAC
| masked_ptr
;
222 ArmISA::auth(ThreadContext
*tc
, ExceptionLevel el
, uint64_t ptr
,
223 uint64_t modifier
, uint64_t k1
, uint64_t k0
, bool data
,
228 uint64_t original_ptr
;
229 // Reconstruct the extension field used of adding the PAC to the pointer
230 bool tbi
= calculateTBI(tc
, el
, ptr
, data
);
231 bool selbit
= (bool) bits(ptr
, 55);
233 int bottom_PAC_bit
= calculateBottomPACBit(tc
, el
, selbit
);
235 uint32_t top_tbi
= tbi
? 56: 64;
236 uint32_t nbits
= top_tbi
- bottom_PAC_bit
;
237 uint64_t pacbits
= ((uint64_t)0x1 << nbits
) -1; // 2^n -1;
238 uint64_t mask
= (pacbits
<< bottom_PAC_bit
); // creates mask
241 original_ptr
= ptr
| mask
;
243 original_ptr
= ptr
& ~mask
;
247 PAC
= QARMA::computePAC(original_ptr
, modifier
, k1
, k0
);
248 // Check pointer authentication code
250 // <bottom_PAC_bit:0>
251 uint64_t low_mask
= ((uint64_t)0x1 << bottom_PAC_bit
) -1;
252 // <54:bottom_PAC_bit>
253 uint64_t pac_mask
= 0x007FFFFFFFFFFFFF & ~low_mask
;
255 uint64_t masked_pac
= PAC
& pac_mask
;
256 uint64_t masked_ptr
= ptr
& pac_mask
;
259 if (masked_pac
== masked_ptr
) {
260 result
= original_ptr
;
262 uint64_t mask2
= ~((uint64_t)0x3 << 53);
263 result
= original_ptr
& mask2
;
264 result
|= (uint64_t)errorcode
<< 53;
267 if ((masked_pac
== masked_ptr
) && ((PAC
>>56)==(ptr
>> 56))) {
268 result
= original_ptr
;
270 uint64_t mask2
= ~((uint64_t)0x3 << 61);
271 result
= original_ptr
& mask2
;
272 result
|= (uint64_t)errorcode
<< 61;
279 ArmISA::authDA(ThreadContext
* tc
, uint64_t X
, uint64_t Y
, uint64_t* out
)
282 Returns a 64-bit value containing X, but replacing the pointer
283 authentication code field bits with the extension of the address bits.
284 The instruction checks a pointer
285 authentication code in the pointer authentication code field bits of X,
286 using the same algorithm and key as AddPACDA().
293 uint64_t hi_key
= tc
->readMiscReg(MISCREG_APDAKeyHi_EL1
);
294 uint64_t lo_key
= tc
->readMiscReg(MISCREG_APDAKeyLo_EL1
);
296 ExceptionLevel el
= currEL(tc
);
297 SCTLR sc1
= tc
->readMiscReg(MISCREG_SCTLR_EL1
);
298 SCTLR sc2
= tc
->readMiscReg(MISCREG_SCTLR_EL2
);
299 SCTLR sc3
= tc
->readMiscReg(MISCREG_SCTLR_EL3
);
300 SCR scr3
= tc
->readMiscReg(MISCREG_SCR_EL3
);
301 HCR hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
302 bool have_el3
= ArmSystem::haveEL(tc
, EL3
);
308 bool IsEL1Regime
= s1TranslationRegime(tc
, el
) == EL1
;
309 enable
= IsEL1Regime
? (bool)sc1
.enda
: (bool)sc2
.enda
;
310 trapEL2
= (EL2Enabled(tc
) && hcr
.api
== 0 &&
311 (hcr
.tge
== 0 || hcr
.e2h
== 0));
312 trapEL3
= have_el3
&& scr3
.api
== 0;
317 trapEL2
= EL2Enabled(tc
) && hcr
.api
== 0;
318 trapEL3
= have_el3
&& scr3
.api
== 0;
323 trapEL3
= have_el3
&& scr3
.api
== 0;
337 return trapPACUse(tc
, EL2
);
339 return trapPACUse(tc
, EL3
);
341 *out
= auth(tc
, el
, X
, Y
, hi_key
, lo_key
, true, 0x1);
347 ArmISA::authDB(ThreadContext
* tc
, uint64_t X
, uint64_t Y
, uint64_t* out
)
350 Returns a 64-bit value containing X, but replacing the pointer
351 authentication code field bits with the extension of the address bits.
352 The instruction checks a pointer
353 authentication code in the pointer authentication code field bits of X,
354 using the same algorithm and key as AddPACDA().
361 uint64_t hi_key
= tc
->readMiscReg(MISCREG_APDBKeyHi_EL1
);
362 uint64_t lo_key
= tc
->readMiscReg(MISCREG_APDBKeyLo_EL1
);
364 ExceptionLevel el
= currEL(tc
);
365 SCTLR sc1
= tc
->readMiscReg(MISCREG_SCTLR_EL1
);
366 SCTLR sc2
= tc
->readMiscReg(MISCREG_SCTLR_EL2
);
367 SCTLR sc3
= tc
->readMiscReg(MISCREG_SCTLR_EL3
);
368 SCR scr3
= tc
->readMiscReg(MISCREG_SCR_EL3
);
370 HCR hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
371 bool have_el3
= ArmSystem::haveEL(tc
, EL3
);
377 bool IsEL1Regime
= s1TranslationRegime(tc
, el
) == EL1
;
378 enable
= IsEL1Regime
? (bool)sc1
.endb
: (bool)sc2
.endb
;
379 trapEL2
= (EL2Enabled(tc
) && hcr
.api
== 0 &&
380 (hcr
.tge
== 0 || hcr
.e2h
== 0));
381 trapEL3
= have_el3
&& scr3
.api
== 0;
386 trapEL2
= EL2Enabled(tc
) && hcr
.api
== 0;
387 trapEL3
= have_el3
&& scr3
.api
== 0;
392 trapEL3
= have_el3
&& scr3
.api
== 0;
406 return trapPACUse(tc
, EL2
);
408 return trapPACUse(tc
, EL3
);
410 *out
= auth(tc
, el
, X
, Y
, hi_key
, lo_key
, true, 0x2);
417 ArmISA::authIA(ThreadContext
* tc
, uint64_t X
, uint64_t Y
, uint64_t* out
)
420 Returns a 64-bit value containing X, but replacing the pointer
421 authentication code field bits with the extension of the address bits.
422 The instruction checks a pointer
423 authentication code in the pointer authentication code field bits of X,
424 using the same algorithm and key as AddPACDA().
431 uint64_t hi_key
= tc
->readMiscReg(MISCREG_APIAKeyHi_EL1
);
432 uint64_t lo_key
= tc
->readMiscReg(MISCREG_APIAKeyLo_EL1
);
434 ExceptionLevel el
= currEL(tc
);
435 SCTLR sc1
= tc
->readMiscReg(MISCREG_SCTLR_EL1
);
436 SCTLR sc2
= tc
->readMiscReg(MISCREG_SCTLR_EL2
);
437 SCTLR sc3
= tc
->readMiscReg(MISCREG_SCTLR_EL3
);
438 SCR scr3
= tc
->readMiscReg(MISCREG_SCR_EL3
);
439 HCR hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
440 bool have_el3
= ArmSystem::haveEL(tc
, EL3
);
446 bool IsEL1Regime
= s1TranslationRegime(tc
, el
) == EL1
;
447 enable
= IsEL1Regime
? (bool)sc1
.enia
: (bool)sc2
.enia
;
448 trapEL2
= (EL2Enabled(tc
) && hcr
.api
== 0 &&
449 (hcr
.tge
== 0 || hcr
.e2h
== 0));
450 trapEL3
= have_el3
&& scr3
.api
== 0;
456 trapEL2
= EL2Enabled(tc
) && hcr
.api
== 0;
457 trapEL3
= have_el3
&& scr3
.api
== 0;
464 trapEL3
= have_el3
&& scr3
.api
== 0;
481 return trapPACUse(tc
, EL2
);
483 return trapPACUse(tc
, EL3
);
485 *out
= auth(tc
, el
, X
, Y
, hi_key
, lo_key
, false, 0x1);
491 ArmISA::authIB(ThreadContext
*tc
, uint64_t X
, uint64_t Y
, uint64_t* out
)
494 Returns a 64-bit value containing X, but replacing the pointer
495 authentication code field bits with the extension of the address bits.
496 The instruction checks a pointer
497 authentication code in the pointer authentication code field bits of X,
498 using the same algorithm and key as AddPACDA().
505 uint64_t hi_key
= tc
->readMiscReg(MISCREG_APIBKeyHi_EL1
);
506 uint64_t lo_key
= tc
->readMiscReg(MISCREG_APIBKeyLo_EL1
);
508 ExceptionLevel el
= currEL(tc
);
509 SCTLR sc1
= tc
->readMiscReg(MISCREG_SCTLR_EL1
);
510 SCTLR sc2
= tc
->readMiscReg(MISCREG_SCTLR_EL2
);
511 SCTLR sc3
= tc
->readMiscReg(MISCREG_SCTLR_EL3
);
512 SCR scr3
= tc
->readMiscReg(MISCREG_SCR_EL3
);
513 HCR hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
514 bool have_el3
= ArmSystem::haveEL(tc
, EL3
);
520 bool IsEL1Regime
= s1TranslationRegime(tc
, el
) == EL1
;
521 enable
= IsEL1Regime
? (bool)sc1
.enib
: (bool)sc2
.enib
;
522 trapEL2
= (EL2Enabled(tc
) && hcr
.api
== 0 &&
523 (hcr
.tge
== 0 || hcr
.e2h
== 0));
524 trapEL3
= have_el3
&& scr3
.api
== 0;
530 trapEL2
= EL2Enabled(tc
) && hcr
.api
== 0;
531 trapEL3
= have_el3
&& scr3
.api
== 0;
538 trapEL3
= have_el3
&& scr3
.api
== 0;
555 return trapPACUse(tc
, EL2
);
557 return trapPACUse(tc
, EL3
);
559 *out
= auth(tc
, el
, X
, Y
, hi_key
, lo_key
, false, 0x2);
567 ArmISA::addPACDA(ThreadContext
* tc
, uint64_t X
, uint64_t Y
, uint64_t* out
)
573 uint64_t hi_key
= tc
->readMiscReg(MISCREG_APDAKeyHi_EL1
);
574 uint64_t lo_key
= tc
->readMiscReg(MISCREG_APDAKeyLo_EL1
);
576 ExceptionLevel el
= currEL(tc
);
577 SCTLR sc1
= tc
->readMiscReg(MISCREG_SCTLR_EL1
);
578 SCTLR sc2
= tc
->readMiscReg(MISCREG_SCTLR_EL2
);
579 SCTLR sc3
= tc
->readMiscReg(MISCREG_SCTLR_EL3
);
580 SCR scr3
= tc
->readMiscReg(MISCREG_SCR_EL3
);
581 HCR hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
582 bool have_el3
= ArmSystem::haveEL(tc
, EL3
);
588 bool IsEL1Regime
= s1TranslationRegime(tc
, el
) == EL1
;
589 enable
= IsEL1Regime
? (bool)sc1
.enda
: (bool)sc2
.enda
;
590 trapEL2
= (EL2Enabled(tc
) && hcr
.api
== 0 &&
591 (hcr
.tge
== 0 || hcr
.e2h
== 0));
592 trapEL3
= have_el3
&& scr3
.api
== 0;
598 trapEL2
= EL2Enabled(tc
) && hcr
.api
== 0;
599 trapEL3
= have_el3
&& scr3
.api
== 0;
606 trapEL3
= have_el3
&& scr3
.api
== 0;
620 return trapPACUse(tc
, EL2
);
622 return trapPACUse(tc
, EL3
);
624 *out
= addPAC(tc
, el
, X
, Y
, hi_key
, lo_key
, true);
631 ArmISA::addPACDB(ThreadContext
* tc
, uint64_t X
, uint64_t Y
, uint64_t* out
)
637 uint64_t hi_key
= tc
->readMiscReg(MISCREG_APDBKeyHi_EL1
);
638 uint64_t lo_key
= tc
->readMiscReg(MISCREG_APDBKeyLo_EL1
);
640 ExceptionLevel el
= currEL(tc
);
641 SCTLR sc1
= tc
->readMiscReg(MISCREG_SCTLR_EL1
);
642 SCTLR sc2
= tc
->readMiscReg(MISCREG_SCTLR_EL2
);
643 SCTLR sc3
= tc
->readMiscReg(MISCREG_SCTLR_EL3
);
644 SCR scr3
= tc
->readMiscReg(MISCREG_SCR_EL3
);
645 HCR hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
646 bool have_el3
= ArmSystem::haveEL(tc
, EL3
);
652 bool IsEL1Regime
= s1TranslationRegime(tc
, el
) == EL1
;
653 enable
= IsEL1Regime
? (bool)sc1
.endb
: (bool)sc2
.endb
;
654 trapEL2
= (EL2Enabled(tc
) && hcr
.api
== 0 &&
655 (hcr
.tge
== 0 || hcr
.e2h
== 0));
656 trapEL3
= have_el3
&& scr3
.api
== 0;
661 trapEL2
= EL2Enabled(tc
) && hcr
.api
== 0;
662 trapEL3
= have_el3
&& scr3
.api
== 0;
667 trapEL3
= have_el3
&& scr3
.api
== 0;
681 return trapPACUse(tc
, EL2
);
683 return trapPACUse(tc
, EL3
);
685 *out
= addPAC(tc
, el
, X
, Y
, hi_key
, lo_key
, true);
692 ArmISA::addPACGA(ThreadContext
* tc
, uint64_t X
, uint64_t Y
, uint64_t* out
)
697 uint64_t hi_key
= tc
->readMiscReg(MISCREG_APGAKeyHi_EL1
);
698 uint64_t lo_key
= tc
->readMiscReg(MISCREG_APGAKeyLo_EL1
);
700 ExceptionLevel el
= currEL(tc
);
701 SCR sc3
= tc
->readMiscReg(MISCREG_SCR_EL3
);
702 HCR hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
703 bool have_el3
= ArmSystem::haveEL(tc
, EL3
);
708 trapEL2
= (EL2Enabled(tc
) && hcr
.api
== 0 &&
709 (hcr
.tge
== '0' || hcr
.e2h
== 0));
710 trapEL3
= have_el3
&& sc3
.api
== 0;
713 trapEL2
= EL2Enabled(tc
) && hcr
.api
== 0;
714 trapEL3
= have_el3
&& sc3
.api
== 0;
718 trapEL3
= have_el3
&& sc3
.api
== 0;
729 return trapPACUse(tc
, EL2
);
731 return trapPACUse(tc
, EL3
);
733 *out
= QARMA::computePAC(X
, Y
, hi_key
, lo_key
) & 0xFFFFFFFF00000000;
740 ArmISA::addPACIA(ThreadContext
* tc
, uint64_t X
, uint64_t Y
, uint64_t* out
){
745 uint64_t hi_key
= tc
->readMiscReg(MISCREG_APIAKeyHi_EL1
);
746 uint64_t lo_key
= tc
->readMiscReg(MISCREG_APIAKeyLo_EL1
);
748 ExceptionLevel el
= currEL(tc
);
749 SCTLR sc1
= tc
->readMiscReg(MISCREG_SCTLR_EL1
);
750 SCTLR sc2
= tc
->readMiscReg(MISCREG_SCTLR_EL2
);
751 SCTLR sc3
= tc
->readMiscReg(MISCREG_SCTLR_EL3
);
752 SCR scr3
= tc
->readMiscReg(MISCREG_SCR_EL3
);
753 HCR hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
754 bool have_el3
= ArmSystem::haveEL(tc
, EL3
);
760 bool IsEL1Regime
= s1TranslationRegime(tc
, el
) == EL1
;
761 enable
= IsEL1Regime
? (bool)sc1
.enia
: (bool)sc2
.enia
;
762 trapEL2
= (EL2Enabled(tc
) && hcr
.api
== 0 &&
763 (hcr
.tge
== 0 || hcr
.e2h
== 0));
764 trapEL3
= have_el3
&& scr3
.api
== 0;
769 trapEL2
= EL2Enabled(tc
) && hcr
.api
== 0;
770 trapEL3
= have_el3
&& scr3
.api
== 0;
775 trapEL3
= have_el3
&& scr3
.api
== 0;
789 return trapPACUse(tc
, EL2
);
791 return trapPACUse(tc
, EL3
);
793 *out
= addPAC(tc
, el
, X
, Y
, hi_key
, lo_key
, false);
799 ArmISA::addPACIB(ThreadContext
* tc
, uint64_t X
, uint64_t Y
, uint64_t* out
){
804 uint64_t hi_key
= tc
->readMiscReg(MISCREG_APIBKeyHi_EL1
);
805 uint64_t lo_key
= tc
->readMiscReg(MISCREG_APIBKeyLo_EL1
);
807 ExceptionLevel el
= currEL(tc
);
808 SCTLR sc1
= tc
->readMiscReg(MISCREG_SCTLR_EL1
);
809 SCTLR sc2
= tc
->readMiscReg(MISCREG_SCTLR_EL2
);
810 SCTLR sc3
= tc
->readMiscReg(MISCREG_SCTLR_EL3
);
811 SCR scr3
= tc
->readMiscReg(MISCREG_SCR_EL3
);
812 HCR hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
813 bool have_el3
= ArmSystem::haveEL(tc
, EL3
);
819 bool IsEL1Regime
= s1TranslationRegime(tc
, el
) == EL1
;
820 enable
= IsEL1Regime
? (bool)sc1
.enib
: (bool)sc2
.enib
;
821 trapEL2
= (EL2Enabled(tc
) && hcr
.api
== 0 &&
822 (hcr
.tge
== 0 || hcr
.e2h
== 0));
823 trapEL3
= have_el3
&& scr3
.api
== 0;
828 trapEL2
= EL2Enabled(tc
) && hcr
.api
== 0;
829 trapEL3
= have_el3
&& scr3
.api
== 0;
834 trapEL3
= have_el3
&& scr3
.api
== 0;
849 return trapPACUse(tc
, EL2
);
851 return trapPACUse(tc
, EL3
);
853 *out
= addPAC(tc
, el
, X
, Y
, hi_key
, lo_key
, false);
861 ArmISA::stripPAC(ThreadContext
* tc
, uint64_t A
, bool data
, uint64_t* out
){
867 ExceptionLevel el
= currEL(tc
);
869 bool tbi
= calculateTBI(tc
, el
, A
, data
);
870 bool selbit
= (bool) bits(A
, 55);
871 int bottom_PAC_bit
= calculateBottomPACBit(tc
, el
, selbit
);
873 int top_bit
= tbi
? 55 : 63;
874 uint32_t nbits
= (top_bit
+1) - bottom_PAC_bit
;
875 uint64_t pacbits
= ((uint64_t)0x1 << nbits
) -1; // 2^n -1;
876 uint64_t mask
= pacbits
<< bottom_PAC_bit
; // creates mask
885 SCR scr3
= tc
->readMiscReg(MISCREG_SCR_EL3
);
886 HCR hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
887 bool have_el3
= ArmSystem::haveEL(tc
, EL3
);
892 trapEL2
= (EL2Enabled(tc
) && hcr
.api
== 0 &&
893 (hcr
.tge
== 0 || hcr
.e2h
== 0));
894 trapEL3
= have_el3
&& scr3
.api
== 0;
897 trapEL2
= EL2Enabled(tc
) && hcr
.api
== 0;
898 trapEL3
= have_el3
&& scr3
.api
== 0;
902 trapEL3
= have_el3
&& scr3
.api
== 0;
913 return trapPACUse(tc
, EL2
);
915 return trapPACUse(tc
, EL3
);