gem5  v20.1.0.0
pauth_helpers.cc
Go to the documentation of this file.
1 // -*- mode:c++ -*-
2 
3 // Copyright (c) 2020 Metempsy Technology Consulting
4 // All rights reserved
5 //
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.
14 //
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.
25 //
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.
37 
39 
40 #include "arch/arm/faults.hh"
41 #include "base/bitfield.hh"
42 
43 using namespace ArmISA;
44 using namespace std;
45 
46 bool
48  uint64_t ptr, bool data)
49 {
50  bool tbi = false;
51  if (upperAndLowerRange(tc, el)) {
52 
54  assert (s1_el == EL1 || s1_el == EL2);
55  TCR tcr = (s1_el == EL1) ? tc->readMiscReg(MISCREG_TCR_EL1):
57  bool b55 = bits(ptr, 55) == 1;
58  if (data)
59  tbi = b55 ? tcr.tbi1 == 1 : tcr.tbi0 == 1;
60  else
61  tbi = b55 ? (tcr.tbi1 == 1 && tcr.tbid1 == 0) :
62  (tcr.tbi0 == 1 && tcr.tbid0 == 0);
63 
64  }
65  else if (el == EL2) {
66  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
67  tbi = data ? tcr.tbi == 1 : (tcr.tbi == 1 && tcr.tbid == 0);
68  }
69  else if (el == EL3) {
70  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL3);
71  tbi = data ? tcr.tbi == 1 : (tcr.tbi == 1 && tcr.tbid == 0);
72  }
73  return tbi;
74 }
75 
76 int
78  bool top_bit)
79 {
80  uint32_t tsz_field;
81  bool using64k;
82  if (upperAndLowerRange(tc, el)) {
84  assert (s1_el == EL1 || s1_el == EL2);
85  if (s1_el == EL1) {
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;
90  } else {
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;
96  }
97  } else {
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 ;
102  }
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);
106 
107  uint32_t tszmin = (using64k && (bool)mm_fr2.varange) ? 12 : 16;
108  tsz_field = max(tsz_field, tszmin);
109 
110  return (64-tsz_field);
111 }
112 
113 Fault
115 {
116  assert(ArmSystem::haveEL(tc, target_el) &&
117  target_el != EL0 && (target_el >= currEL(tc)));
118 
119  switch (target_el) {
120  case EL2:
121  return std::make_shared<HypervisorTrap>(0x0, 0, EC_TRAPPED_PAC);
122  case EL3:
123  return std::make_shared<SecureMonitorTrap>(0x0, 0, EC_TRAPPED_PAC);
124  default:
125  return NoFault;
126  }
127 }
128 
129 uint64_t
131  uint64_t modifier, uint64_t k1, uint64_t k0, bool data)
132 {
133  uint64_t PAC;
134  uint64_t result;
135  uint64_t ext_ptr;
136  bool selbit;
137 
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
147 
148  if (upperAndLowerRange(tc, el)) {
150  assert (s1_el == EL1 || s1_el == EL2);
151  if (s1_el == EL1) {
152  // EL1 translation regime registers
153  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL1);
154  if (data) {
155  selbit = (tcr.tbi1 == 1 || tcr.tbi0 == 1) ? b55: b63;
156  } else {
157  selbit = ((tcr.tbi1 == 1 && tcr.tbid1 == 0)
158  || (tcr.tbi0 == 1 && tcr.tbid0 == 0)) ? b55 : b63;
159  }
160  } else {
161  // EL2 translation regime registers
162  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
163  bool have_el2 = ArmSystem::haveEL(tc, EL2);
164  if (data) {
165  selbit = (have_el2 &&
166  (tcr.tbi0 == 1 || tcr.tbi1 == 1))? b55: b63;
167  }
168  else
169  {
170  selbit = (have_el2 &&
171  ((tcr.tbi1 == 1 && tcr.tbid1 == 0) ||
172  (tcr.tbi0 == 1 && tcr.tbid0 == 0)))? b55: b63;
173  }
174  }
175  } else {
176  selbit = tbi ? b55: b63;
177  }
178 
179  int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
180  // The pointer authentication code field takes all the available
181  // bits in between
182 
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
186 
187  if (selbit) {
188  ext_ptr = ptr | mask;
189  } else {
190  ext_ptr = ptr & ~mask;
191  }
192 
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));
199  }
200  // Preserve the determination between upper and lower address
201  // at bit<55> and insert PAC
202  if (tbi) {
203  // ptr<63:56>:selbit:PAC<54:bottom_PAC_bit>:ptr<bottom_PAC_bit-1:0>;
204  result = ptr & 0xFF00000000000000;
205  } else {
206  // PAC<63:56>:selbit:PAC<54:bottom_PAC_bit>:ptr<bottom_PAC_bit-1:0>;
207  result = PAC & 0xFF00000000000000;
208  }
209 
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;
213 
214  masked_PAC &= ~pacbit_mask;
215  result |= ((uint64_t)selbit << 55) | masked_PAC | masked_ptr;
216 
217  return result;
218 }
219 
220 
221 uint64_t
223  uint64_t modifier, uint64_t k1, uint64_t k0, bool data,
224  uint8_t errorcode)
225 {
226  uint64_t PAC;
227  uint64_t result;
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);
232 
233  int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
234 
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
239 
240  if (selbit) {
241  original_ptr = ptr | mask;
242  } else {
243  original_ptr = ptr & ~mask;
244  }
245 
246 
247  PAC = QARMA::computePAC(original_ptr, modifier, k1, k0);
248  // Check pointer authentication code
249 
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;
254 
255  uint64_t masked_pac = PAC & pac_mask;
256  uint64_t masked_ptr = ptr & pac_mask;
257 
258  if (tbi) {
259  if (masked_pac == masked_ptr) {
260  result = original_ptr;
261  } else {
262  uint64_t mask2= ~((uint64_t)0x3 << 53);
263  result = original_ptr & mask2;
264  result |= (uint64_t)errorcode << 53;
265  }
266  } else {
267  if ((masked_pac == masked_ptr) && ((PAC >>56)==(ptr >> 56))) {
268  result = original_ptr;
269  } else {
270  uint64_t mask2 = ~((uint64_t)0x3 << 61);
271  result = original_ptr & mask2;
272  result |= (uint64_t)errorcode << 61;
273  }
274  }
275  return result;
276 }
277 
278 Fault
279 ArmISA::authDA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
280 {
281 /*
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().
287 */
288 
289  bool trapEL2 = false;
290  bool trapEL3 = false;
291  bool enable = false;
292 
293  uint64_t hi_key= tc->readMiscReg(MISCREG_APDAKeyHi_EL1);
294  uint64_t lo_key= tc->readMiscReg(MISCREG_APDAKeyLo_EL1);
295 
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);
303 
304  switch (el)
305  {
306  case EL0:
307  {
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;
313  break;
314  }
315  case EL1:
316  enable = sc1.enda;
317  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
318  trapEL3 = have_el3 && scr3.api == 0;
319  break;
320  case EL2:
321  enable = sc2.enda;
322  trapEL2 = false;
323  trapEL3 = have_el3 && scr3.api == 0;
324  break;
325  case EL3:
326  enable = sc3.enda;
327  trapEL2 = false;
328  trapEL3 = false;
329  break;
330  default:
331  // Unreachable
332  break;
333  }
334  if (!enable)
335  *out = X;
336  else if (trapEL2)
337  return trapPACUse(tc, EL2);
338  else if (trapEL3)
339  return trapPACUse(tc, EL3);
340  else {
341  *out = auth(tc, el, X, Y, hi_key, lo_key, true, 0x1);
342  }
343  return NoFault;
344 }
345 
346 Fault
347 ArmISA::authDB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
348 {
349 /*
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().
355 */
356 
357  bool trapEL2 = false;
358  bool trapEL3 = false;
359  bool enable = false;
360 
361  uint64_t hi_key= tc->readMiscReg(MISCREG_APDBKeyHi_EL1);
362  uint64_t lo_key= tc->readMiscReg(MISCREG_APDBKeyLo_EL1);
363 
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);
369 
370  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
371  bool have_el3 = ArmSystem::haveEL(tc, EL3);
372 
373  switch (el)
374  {
375  case EL0:
376  {
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;
382  break;
383  }
384  case EL1:
385  enable = sc1.endb;
386  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
387  trapEL3 = have_el3 && scr3.api == 0;
388  break;
389  case EL2:
390  enable = sc2.endb;
391  trapEL2 = false;
392  trapEL3 = have_el3 && scr3.api == 0;
393  break;
394  case EL3:
395  enable = sc3.endb;
396  trapEL2 = false;
397  trapEL3 = false;
398  break;
399  default:
400  //unreachable
401  break;
402  }
403  if (!enable)
404  *out = X;
405  else if (trapEL2)
406  return trapPACUse(tc, EL2);
407  else if (trapEL3)
408  return trapPACUse(tc, EL3);
409  else
410  *out = auth(tc, el, X, Y, hi_key, lo_key, true, 0x2);
411 
412  return NoFault;
413 }
414 
415 
416 Fault
417 ArmISA::authIA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
418 {
419 /*
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().
425 */
426 
427  bool trapEL2 = false;
428  bool trapEL3 = false;
429  bool enable = false;
430 
431  uint64_t hi_key= tc->readMiscReg(MISCREG_APIAKeyHi_EL1);
432  uint64_t lo_key= tc->readMiscReg(MISCREG_APIAKeyLo_EL1);
433 
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);
441 
442  switch (el)
443  {
444  case EL0:
445  {
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;
451  break;
452  }
453  case EL1:
454  {
455  enable = sc1.enia;
456  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
457  trapEL3 = have_el3 && scr3.api == 0;
458  break;
459  }
460  case EL2:
461  {
462  enable = sc2.enia;
463  trapEL2 = false;
464  trapEL3 = have_el3 && scr3.api == 0;
465  break;
466  }
467  case EL3:
468  {
469  enable = sc3.enia;
470  trapEL2 = false;
471  trapEL3 = false;
472  break;
473  }
474  default:
475  //unreachable
476  break;
477  }
478  if (!enable)
479  *out = X;
480  else if (trapEL2)
481  return trapPACUse(tc, EL2);
482  else if (trapEL3)
483  return trapPACUse(tc, EL3);
484  else
485  *out = auth(tc, el, X, Y, hi_key, lo_key, false, 0x1);
486 
487  return NoFault;
488 }
489 
490 Fault
491 ArmISA::authIB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t* out)
492 {
493 /*
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().
499 */
500 
501  bool trapEL2 = false;
502  bool trapEL3 = false;
503  bool enable = false;
504 
505  uint64_t hi_key= tc->readMiscReg(MISCREG_APIBKeyHi_EL1);
506  uint64_t lo_key= tc->readMiscReg(MISCREG_APIBKeyLo_EL1);
507 
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);
515 
516  switch (el)
517  {
518  case EL0:
519  {
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;
525  break;
526  }
527  case EL1:
528  {
529  enable = sc1.enib;
530  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
531  trapEL3 = have_el3 && scr3.api == 0;
532  break;
533  }
534  case EL2:
535  {
536  enable = sc2.enib;
537  trapEL2 = false;
538  trapEL3 = have_el3 && scr3.api == 0;
539  break;
540  }
541  case EL3:
542  {
543  enable = sc3.enib;
544  trapEL2 = false;
545  trapEL3 = false;
546  break;
547  }
548  default:
549  //unreachable
550  break;
551  }
552  if (!enable)
553  *out = X;
554  else if (trapEL2)
555  return trapPACUse(tc, EL2);
556  else if (trapEL3)
557  return trapPACUse(tc, EL3);
558  else
559  *out = auth(tc, el, X, Y, hi_key, lo_key, false, 0x2);
560 
561  return NoFault;
562 }
563 
564 
565 
566 Fault
567 ArmISA::addPACDA(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
568 {
569  bool trapEL2 = false;
570  bool trapEL3 = false;
571  bool enable = false;
572 
573  uint64_t hi_key= tc->readMiscReg(MISCREG_APDAKeyHi_EL1);
574  uint64_t lo_key= tc->readMiscReg(MISCREG_APDAKeyLo_EL1);
575 
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);
583 
584  switch (el)
585  {
586  case EL0:
587  {
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;
593  break;
594  }
595  case EL1:
596  {
597  enable = sc1.enda;
598  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
599  trapEL3 = have_el3 && scr3.api == 0;
600  break;
601  }
602  case EL2:
603  {
604  enable = sc2.enda;
605  trapEL2 = false;
606  trapEL3 = have_el3 && scr3.api == 0;
607  break;
608  }
609  case EL3:
610  {
611  enable = sc3.enda;
612  trapEL2 = false;
613  trapEL3 = false;
614  break;
615  }
616  }
617  if (!enable)
618  *out = X;
619  else if (trapEL2)
620  return trapPACUse(tc, EL2);
621  else if (trapEL3)
622  return trapPACUse(tc, EL3);
623  else
624  *out = addPAC(tc, el, X, Y, hi_key, lo_key, true);
625 
626  return NoFault;
627 }
628 
629 
630 Fault
631 ArmISA::addPACDB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
632 {
633  bool trapEL2 = false;
634  bool trapEL3 = false;
635  bool enable = false;
636 
637  uint64_t hi_key= tc->readMiscReg(MISCREG_APDBKeyHi_EL1);
638  uint64_t lo_key= tc->readMiscReg(MISCREG_APDBKeyLo_EL1);
639 
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);
647 
648  switch (el)
649  {
650  case EL0:
651  {
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;
657  break;
658  }
659  case EL1:
660  enable = sc1.endb;
661  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
662  trapEL3 = have_el3 && scr3.api == 0;
663  break;
664  case EL2:
665  enable = sc2.endb;
666  trapEL2 = false;
667  trapEL3 = have_el3 && scr3.api == 0;
668  break;
669  case EL3:
670  enable = sc3.endb;
671  trapEL2 = false;
672  trapEL3 = false;
673  break;
674  default:
675  // unreachable
676  break;
677  }
678  if (!enable)
679  *out = X;
680  else if (trapEL2)
681  return trapPACUse(tc, EL2);
682  else if (trapEL3)
683  return trapPACUse(tc, EL3);
684  else
685  *out = addPAC(tc, el, X, Y, hi_key, lo_key, true);
686 
687  return NoFault;
688 }
689 
690 
691 Fault
692 ArmISA::addPACGA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
693 {
694  bool trapEL2 = false;
695  bool trapEL3 = false;
696 
697  uint64_t hi_key= tc->readMiscReg(MISCREG_APGAKeyHi_EL1);
698  uint64_t lo_key= tc->readMiscReg(MISCREG_APGAKeyLo_EL1);
699 
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);
704 
705  switch (el)
706  {
707  case EL0:
708  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
709  (hcr.tge == 0 || hcr.e2h == 0));
710  trapEL3 = have_el3 && sc3.api == 0;
711  break;
712  case EL1:
713  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
714  trapEL3 = have_el3 && sc3.api == 0;
715  break;
716  case EL2:
717  trapEL2 = false;
718  trapEL3 = have_el3 && sc3.api == 0;
719  break;
720  case EL3:
721  trapEL2 = false;
722  trapEL3 = false;
723  break;
724  default:
725  //unreachable
726  break;
727  }
728  if (trapEL2)
729  return trapPACUse(tc, EL2);
730  else if (trapEL3)
731  return trapPACUse(tc, EL3);
732  else
733  *out = QARMA::computePAC(X, Y, hi_key, lo_key) & 0xFFFFFFFF00000000;
734 
735  return NoFault;
736 }
737 
738 
739 Fault
740 ArmISA::addPACIA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out){
741  bool trapEL2 = false;
742  bool trapEL3 = false;
743  bool enable = false;
744 
745  uint64_t hi_key= tc->readMiscReg(MISCREG_APIAKeyHi_EL1);
746  uint64_t lo_key= tc->readMiscReg(MISCREG_APIAKeyLo_EL1);
747 
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);
755 
756  switch (el)
757  {
758  case EL0:
759  {
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;
765  break;
766  }
767  case EL1:
768  enable = sc1.enia;
769  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
770  trapEL3 = have_el3 && scr3.api == 0;
771  break;
772  case EL2:
773  enable = sc2.enia;
774  trapEL2 = false;
775  trapEL3 = have_el3 && scr3.api == 0;
776  break;
777  case EL3:
778  enable = sc3.enia;
779  trapEL2 = false;
780  trapEL3 = false;
781  break;
782  default:
783  //unreachable
784  break;
785  }
786  if (!enable)
787  *out = X;
788  else if (trapEL2)
789  return trapPACUse(tc, EL2);
790  else if (trapEL3)
791  return trapPACUse(tc, EL3);
792  else
793  *out = addPAC(tc, el, X, Y, hi_key, lo_key, false);
794 
795  return NoFault;
796 }
797 
798 Fault
799 ArmISA::addPACIB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out){
800  bool trapEL2 = false;
801  bool trapEL3 = false;
802  bool enable = false;
803 
804  uint64_t hi_key= tc->readMiscReg(MISCREG_APIBKeyHi_EL1);
805  uint64_t lo_key= tc->readMiscReg(MISCREG_APIBKeyLo_EL1);
806 
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);
814 
815  switch (el)
816  {
817  case EL0:
818  {
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;
824  break;
825  }
826  case EL1:
827  enable = sc1.enib;
828  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
829  trapEL3 = have_el3 && scr3.api == 0;
830  break;
831  case EL2:
832  enable = sc2.enib;
833  trapEL2 = false;
834  trapEL3 = have_el3 && scr3.api == 0;
835  break;
836  case EL3:
837  enable = sc3.enib;
838  trapEL2 = false;
839  trapEL3 = false;
840  break;
841  default:
842  // Unnaccessible
843  break;
844  }
845 
846  if (!enable)
847  *out = X;
848  else if (trapEL2)
849  return trapPACUse(tc, EL2);
850  else if (trapEL3)
851  return trapPACUse(tc, EL3);
852  else
853  *out = addPAC(tc, el, X, Y, hi_key, lo_key, false);
854 
855  return NoFault;
856 }
857 
858 
859 
860 Fault
861 ArmISA::stripPAC(ThreadContext* tc, uint64_t A, bool data, uint64_t* out){
862  bool trapEL2 = false;
863  bool trapEL3 = false;
864 
865  uint64_t ptr;
866 
867  ExceptionLevel el = currEL(tc);
868 
869  bool tbi = calculateTBI(tc, el, A, data);
870  bool selbit = (bool) bits(A, 55);
871  int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
872 
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
877 
878 
879  if (selbit) {
880  ptr = A | mask;
881  } else {
882  ptr = A & ~mask;
883  }
884 
885  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
886  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
887  bool have_el3 = ArmSystem::haveEL(tc, EL3);
888 
889  switch (el)
890  {
891  case EL0:
892  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
893  (hcr.tge == 0 || hcr.e2h == 0));
894  trapEL3 = have_el3 && scr3.api == 0;
895  break;
896  case EL1:
897  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
898  trapEL3 = have_el3 && scr3.api == 0;
899  break;
900  case EL2:
901  trapEL2 = false;
902  trapEL3 = have_el3 && scr3.api == 0;
903  break;
904  case EL3:
905  trapEL2 = false;
906  trapEL3 = false;
907  break;
908  default:
909  // Unnaccessible
910  break;
911  }
912  if (trapEL2)
913  return trapPACUse(tc, EL2);
914  else if (trapEL3)
915  return trapPACUse(tc, EL3);
916  else
917  *out = ptr;
918 
919  return NoFault;
920 }
921 
ArmISA::MISCREG_ID_AA64MMFR2_EL1
@ MISCREG_ID_AA64MMFR2_EL1
Definition: miscregs.hh:814
ArmISA::MISCREG_APIBKeyLo_EL1
@ MISCREG_APIBKeyLo_EL1
Definition: miscregs.hh:826
ArmISA::EL2Enabled
bool EL2Enabled(ThreadContext *tc)
Definition: utility.cc:369
ArmISA::EC_TRAPPED_PAC
@ EC_TRAPPED_PAC
Definition: types.hh:659
ArmISA::trapPACUse
Fault trapPACUse(ThreadContext *tc, ExceptionLevel el)
Definition: pauth_helpers.cc:114
ArmISA::EL2
@ EL2
Definition: types.hh:624
data
const char data[]
Definition: circlebuf.test.cc:42
ArmISA::calculateTBI
bool calculateTBI(ThreadContext *tc, ExceptionLevel el, uint64_t ptr, bool data)
Definition: pauth_helpers.cc:47
ArmISA::MISCREG_APDBKeyLo_EL1
@ MISCREG_APDBKeyLo_EL1
Definition: miscregs.hh:820
ArmISA::addPACGA
Fault addPACGA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:692
ArmISA::EL0
@ EL0
Definition: types.hh:622
ArmISA::upperAndLowerRange
bool upperAndLowerRange(ThreadContext *tc, ExceptionLevel el)
Definition: pauth_helpers.hh:53
ArmISA::currEL
static ExceptionLevel currEL(const ThreadContext *tc)
Definition: utility.hh:143
ArmISA::auth
uint64_t auth(ThreadContext *tc, ExceptionLevel el, uint64_t ptr, uint64_t modifier, uint64_t k1, uint64_t K0, bool data, uint8_t errorcode)
Definition: pauth_helpers.cc:222
ArmISA::MISCREG_APDBKeyHi_EL1
@ MISCREG_APDBKeyHi_EL1
Definition: miscregs.hh:819
ArmISA::stripPAC
Fault stripPAC(ThreadContext *tc, uint64_t A, bool data, uint64_t *out)
Definition: pauth_helpers.cc:861
ArmISA::tbi
Bitfield< 20 > tbi
Definition: miscregs_types.hh:509
ArmISA::EL3
@ EL3
Definition: types.hh:625
X86ISA::X
Bitfield< 15, 0 > X
Definition: int.hh:53
ArmISA::MISCREG_APGAKeyHi_EL1
@ MISCREG_APGAKeyHi_EL1
Definition: miscregs.hh:821
ArmISA::MISCREG_TCR_EL2
@ MISCREG_TCR_EL2
Definition: miscregs.hh:596
ArmISA::addPACDA
Fault addPACDA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:567
ArmISA
Definition: ccregs.hh:41
ArmISA::MISCREG_TCR_EL3
@ MISCREG_TCR_EL3
Definition: miscregs.hh:602
ArmISA::calculateBottomPACBit
int calculateBottomPACBit(ThreadContext *tc, ExceptionLevel el, bool top_bit)
Definition: pauth_helpers.cc:77
ArmISA::authIB
Fault authIB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:491
ArmISA::sc2
Bitfield< 19 > sc2
Definition: miscregs_types.hh:734
ArmISA::authIA
Fault authIA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:417
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
ArmISA::addPACDB
Fault addPACDB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:631
bitfield.hh
ArmISA::ExceptionLevel
ExceptionLevel
Definition: types.hh:621
ArmISA::addPAC
uint64_t addPAC(ThreadContext *tc, ExceptionLevel el, uint64_t ptr, uint64_t modifier, uint64_t k1, uint64_t k0, bool data)
Definition: pauth_helpers.cc:130
Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
ArmISA::MISCREG_APIBKeyHi_EL1
@ MISCREG_APIBKeyHi_EL1
Definition: miscregs.hh:825
ArmISA::MISCREG_APDAKeyLo_EL1
@ MISCREG_APDAKeyLo_EL1
Definition: miscregs.hh:818
ArmISA::MISCREG_APGAKeyLo_EL1
@ MISCREG_APGAKeyLo_EL1
Definition: miscregs.hh:822
ArmISA::MISCREG_TCR_EL1
@ MISCREG_TCR_EL1
Definition: miscregs.hh:593
ArmISA::el
Bitfield< 3, 2 > el
Definition: miscregs_types.hh:69
ArmISA::s1TranslationRegime
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:333
faults.hh
ArmISA::MISCREG_HCR_EL2
@ MISCREG_HCR_EL2
Definition: miscregs.hh:578
NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:245
ArmISA::EL1
@ EL1
Definition: types.hh:623
ArmISA::MISCREG_APIAKeyLo_EL1
@ MISCREG_APIAKeyLo_EL1
Definition: miscregs.hh:824
ArmISA::MISCREG_APIAKeyHi_EL1
@ MISCREG_APIAKeyHi_EL1
Definition: miscregs.hh:823
pauth_helpers.hh
ArmISA::MISCREG_SCR_EL3
@ MISCREG_SCR_EL3
Definition: miscregs.hh:585
ArmISA::MISCREG_APDAKeyHi_EL1
@ MISCREG_APDAKeyHi_EL1
Definition: miscregs.hh:817
QARMA::computePAC
BIT64 computePAC(BIT64 data, BIT64 modifier, BIT64 key0, BIT64 key1)
Definition: qarma.cc:330
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
ArmISA::t
Bitfield< 5 > t
Definition: miscregs_types.hh:67
X86ISA::enable
Bitfield< 11 > enable
Definition: misc.hh:1051
ThreadContext::readMiscReg
virtual RegVal readMiscReg(RegIndex misc_reg)=0
ArmSystem::haveEL
static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el)
Return true if the system implements a specific exception level.
Definition: system.cc:135
MipsISA::k0
Bitfield< 2, 0 > k0
Definition: pra_constants.hh:226
ArmISA::authDB
Fault authDB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:347
ArmISA::addPACIB
Fault addPACIB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:799
ArmISA::addPACIA
Fault addPACIA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:740
ArmISA::MISCREG_SCTLR_EL3
@ MISCREG_SCTLR_EL3
Definition: miscregs.hh:583
ArmISA::authDA
Fault authDA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:279
ArmISA::MISCREG_SCTLR_EL2
@ MISCREG_SCTLR_EL2
Definition: miscregs.hh:576
ArmISA::mask
Bitfield< 28, 24 > mask
Definition: miscregs_types.hh:711
ArmISA::MISCREG_SCTLR_EL1
@ MISCREG_SCTLR_EL1
Definition: miscregs.hh:571
bits
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:75

Generated on Wed Sep 30 2020 14:02:01 for gem5 by doxygen 1.8.17