gem5  v21.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 
45 bool
47  uint64_t ptr, bool data)
48 {
49  bool tbi = false;
50  if (upperAndLowerRange(tc, el)) {
51 
53  assert (s1_el == EL1 || s1_el == EL2);
54  TCR tcr = (s1_el == EL1) ? tc->readMiscReg(MISCREG_TCR_EL1):
56  bool b55 = bits(ptr, 55) == 1;
57  if (data)
58  tbi = b55 ? tcr.tbi1 == 1 : tcr.tbi0 == 1;
59  else
60  tbi = b55 ? (tcr.tbi1 == 1 && tcr.tbid1 == 0) :
61  (tcr.tbi0 == 1 && tcr.tbid0 == 0);
62 
63  }
64  else if (el == EL2) {
65  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
66  tbi = data ? tcr.tbi == 1 : (tcr.tbi == 1 && tcr.tbid == 0);
67  }
68  else if (el == EL3) {
69  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL3);
70  tbi = data ? tcr.tbi == 1 : (tcr.tbi == 1 && tcr.tbid == 0);
71  }
72  return tbi;
73 }
74 
75 int
77  bool top_bit)
78 {
79  uint32_t tsz_field;
80  bool using64k;
81  if (upperAndLowerRange(tc, el)) {
83  assert (s1_el == EL1 || s1_el == EL2);
84  if (s1_el == EL1) {
85  // EL1 translation regime registers
86  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL1);
87  tsz_field = top_bit ? (uint32_t)tcr.t1sz : (uint32_t)tcr.t0sz;
88  using64k = top_bit ? tcr.tg1 == 0x3 : tcr.tg0 == 0x1;
89  } else {
90  // EL2 translation regime registers
91  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
92  assert (ArmSystem::haveEL(tc, EL2));
93  tsz_field = top_bit? (uint32_t)tcr.t1sz : (uint32_t)tcr.t0sz;
94  using64k = top_bit ? tcr.tg1 == 0x3 : tcr.tg0 == 0x1;
95  }
96  } else {
97  TCR tcr2 = tc->readMiscReg(MISCREG_TCR_EL2);
98  TCR tcr3 = tc->readMiscReg(MISCREG_TCR_EL3);
99  tsz_field = el == EL2 ? (uint32_t)tcr2.t0sz: (uint32_t)tcr3.t0sz;
100  using64k = el == EL2 ? tcr2.tg0 == 0x1 : tcr3.tg0 == 0x1 ;
101  }
102  uint32_t max_limit_tsz_field = using64k ? 47 : 48;
103  tsz_field = std::min(tsz_field, max_limit_tsz_field);
104  const AA64MMFR2 mm_fr2 = tc->readMiscReg(MISCREG_ID_AA64MMFR2_EL1);
105 
106  uint32_t tszmin = (using64k && (bool)mm_fr2.varange) ? 12 : 16;
107  tsz_field = std::max(tsz_field, tszmin);
108 
109  return (64-tsz_field);
110 }
111 
112 Fault
114 {
115  assert(ArmSystem::haveEL(tc, target_el) &&
116  target_el != EL0 && (target_el >= currEL(tc)));
117 
118  switch (target_el) {
119  case EL2:
120  return std::make_shared<HypervisorTrap>(0x0, 0, EC_TRAPPED_PAC);
121  case EL3:
122  return std::make_shared<SecureMonitorTrap>(0x0, 0, EC_TRAPPED_PAC);
123  default:
124  return NoFault;
125  }
126 }
127 
128 uint64_t
130  uint64_t modifier, uint64_t k1, uint64_t k0, bool data)
131 {
132  uint64_t PAC;
133  uint64_t result;
134  uint64_t ext_ptr;
135  bool selbit;
136 
137  bool tbi = calculateTBI(tc, el, ptr, data);
138  int top_bit = tbi ? 55 : 63;
139  bool b55 = bits(ptr, 55);
140  bool b63 = bits(ptr, 63);
141  // If tagged pointers are in use for a regime with two TTBRs,use bit<55> of
142  // the pointer to select between upper and lower ranges, and preserve this.
143  // This handles the awkward case where there is apparently no correct
144  // choice between the upper and lower address range - ie an addr of
145  // 1xxxxxxx0... with TBI0=0 and TBI1=1 and 0xxxxxxx1 with TBI1=0 and TBI0=1
146 
147  if (upperAndLowerRange(tc, el)) {
149  assert (s1_el == EL1 || s1_el == EL2);
150  if (s1_el == EL1) {
151  // EL1 translation regime registers
152  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL1);
153  if (data) {
154  selbit = (tcr.tbi1 == 1 || tcr.tbi0 == 1) ? b55: b63;
155  } else {
156  selbit = ((tcr.tbi1 == 1 && tcr.tbid1 == 0)
157  || (tcr.tbi0 == 1 && tcr.tbid0 == 0)) ? b55 : b63;
158  }
159  } else {
160  // EL2 translation regime registers
161  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
162  bool have_el2 = ArmSystem::haveEL(tc, EL2);
163  if (data) {
164  selbit = (have_el2 &&
165  (tcr.tbi0 == 1 || tcr.tbi1 == 1))? b55: b63;
166  }
167  else
168  {
169  selbit = (have_el2 &&
170  ((tcr.tbi1 == 1 && tcr.tbid1 == 0) ||
171  (tcr.tbi0 == 1 && tcr.tbid0 == 0)))? b55: b63;
172  }
173  }
174  } else {
175  selbit = tbi ? b55: b63;
176  }
177 
178  int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
179  // The pointer authentication code field takes all the available
180  // bits in between
181 
182  uint32_t nbits = (top_bit+1) - bottom_PAC_bit;
183  uint64_t pacbits = ((uint64_t)0x1 << nbits) -1; // 2^n -1;
184  uint64_t mask = pacbits << bottom_PAC_bit; // creates mask
185 
186  if (selbit) {
187  ext_ptr = ptr | mask;
188  } else {
189  ext_ptr = ptr & ~mask;
190  }
191 
192  PAC = QARMA::computePAC(ext_ptr, modifier, k1, k0);
193  // Check if the ptr has good extension bits and corrupt the
194  // pointer authentication code if not;
195  uint64_t t = bits(ptr, top_bit, bottom_PAC_bit);
196  if (t != 0x0 && t != pacbits) {
197  PAC ^= ((uint64_t)0x1 << (top_bit-1));
198  }
199  // Preserve the determination between upper and lower address
200  // at bit<55> and insert PAC
201  if (tbi) {
202  // ptr<63:56>:selbit:PAC<54:bottom_PAC_bit>:ptr<bottom_PAC_bit-1:0>;
203  result = ptr & 0xFF00000000000000;
204  } else {
205  // PAC<63:56>:selbit:PAC<54:bottom_PAC_bit>:ptr<bottom_PAC_bit-1:0>;
206  result = PAC & 0xFF00000000000000;
207  }
208 
209  uint64_t masked_PAC = PAC & 0x007FFFFFFFFFFFFF;
210  uint64_t pacbit_mask = ((uint64_t)0x1 << bottom_PAC_bit) -1;
211  uint64_t masked_ptr = ptr & pacbit_mask;
212 
213  masked_PAC &= ~pacbit_mask;
214  result |= ((uint64_t)selbit << 55) | masked_PAC | masked_ptr;
215 
216  return result;
217 }
218 
219 
220 uint64_t
222  uint64_t modifier, uint64_t k1, uint64_t k0, bool data,
223  uint8_t errorcode)
224 {
225  uint64_t PAC;
226  uint64_t result;
227  uint64_t original_ptr;
228  // Reconstruct the extension field used of adding the PAC to the pointer
229  bool tbi = calculateTBI(tc, el, ptr, data);
230  bool selbit = (bool) bits(ptr, 55);
231 
232  int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
233 
234  uint32_t top_tbi = tbi? 56: 64;
235  uint32_t nbits = top_tbi - bottom_PAC_bit;
236  uint64_t pacbits = ((uint64_t)0x1 << nbits) -1; // 2^n -1;
237  uint64_t mask = (pacbits << bottom_PAC_bit); // creates mask
238 
239  if (selbit) {
240  original_ptr = ptr | mask;
241  } else {
242  original_ptr = ptr & ~mask;
243  }
244 
245 
246  PAC = QARMA::computePAC(original_ptr, modifier, k1, k0);
247  // Check pointer authentication code
248 
249  // <bottom_PAC_bit:0>
250  uint64_t low_mask = ((uint64_t)0x1 << bottom_PAC_bit) -1;
251  // <54:bottom_PAC_bit>
252  uint64_t pac_mask = 0x007FFFFFFFFFFFFF & ~low_mask;
253 
254  uint64_t masked_pac = PAC & pac_mask;
255  uint64_t masked_ptr = ptr & pac_mask;
256 
257  if (tbi) {
258  if (masked_pac == masked_ptr) {
259  result = original_ptr;
260  } else {
261  uint64_t mask2= ~((uint64_t)0x3 << 53);
262  result = original_ptr & mask2;
263  result |= (uint64_t)errorcode << 53;
264  }
265  } else {
266  if ((masked_pac == masked_ptr) && ((PAC >>56)==(ptr >> 56))) {
267  result = original_ptr;
268  } else {
269  uint64_t mask2 = ~((uint64_t)0x3 << 61);
270  result = original_ptr & mask2;
271  result |= (uint64_t)errorcode << 61;
272  }
273  }
274  return result;
275 }
276 
277 Fault
278 ArmISA::authDA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
279 {
280 /*
281  Returns a 64-bit value containing X, but replacing the pointer
282  authentication code field bits with the extension of the address bits.
283  The instruction checks a pointer
284  authentication code in the pointer authentication code field bits of X,
285  using the same algorithm and key as AddPACDA().
286 */
287 
288  bool trapEL2 = false;
289  bool trapEL3 = false;
290  bool enable = false;
291 
292  uint64_t hi_key= tc->readMiscReg(MISCREG_APDAKeyHi_EL1);
293  uint64_t lo_key= tc->readMiscReg(MISCREG_APDAKeyLo_EL1);
294 
295  ExceptionLevel el = currEL(tc);
296  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
297  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
298  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
299  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
300  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
301  bool have_el3 = ArmSystem::haveEL(tc, EL3);
302 
303  switch (el)
304  {
305  case EL0:
306  {
307  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
308  enable = IsEL1Regime ? (bool)sc1.enda : (bool)sc2.enda;
309  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
310  (hcr.tge == 0 || hcr.e2h == 0));
311  trapEL3 = have_el3 && scr3.api == 0;
312  break;
313  }
314  case EL1:
315  enable = sc1.enda;
316  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
317  trapEL3 = have_el3 && scr3.api == 0;
318  break;
319  case EL2:
320  enable = sc2.enda;
321  trapEL2 = false;
322  trapEL3 = have_el3 && scr3.api == 0;
323  break;
324  case EL3:
325  enable = sc3.enda;
326  trapEL2 = false;
327  trapEL3 = false;
328  break;
329  default:
330  // Unreachable
331  break;
332  }
333  if (!enable)
334  *out = X;
335  else if (trapEL2)
336  return trapPACUse(tc, EL2);
337  else if (trapEL3)
338  return trapPACUse(tc, EL3);
339  else {
340  *out = auth(tc, el, X, Y, hi_key, lo_key, true, 0x1);
341  }
342  return NoFault;
343 }
344 
345 Fault
346 ArmISA::authDB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
347 {
348 /*
349  Returns a 64-bit value containing X, but replacing the pointer
350  authentication code field bits with the extension of the address bits.
351  The instruction checks a pointer
352  authentication code in the pointer authentication code field bits of X,
353  using the same algorithm and key as AddPACDA().
354 */
355 
356  bool trapEL2 = false;
357  bool trapEL3 = false;
358  bool enable = false;
359 
360  uint64_t hi_key= tc->readMiscReg(MISCREG_APDBKeyHi_EL1);
361  uint64_t lo_key= tc->readMiscReg(MISCREG_APDBKeyLo_EL1);
362 
363  ExceptionLevel el = currEL(tc);
364  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
365  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
366  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
367  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
368 
369  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
370  bool have_el3 = ArmSystem::haveEL(tc, EL3);
371 
372  switch (el)
373  {
374  case EL0:
375  {
376  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
377  enable = IsEL1Regime ? (bool)sc1.endb : (bool)sc2.endb;
378  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
379  (hcr.tge == 0 || hcr.e2h == 0));
380  trapEL3 = have_el3 && scr3.api == 0;
381  break;
382  }
383  case EL1:
384  enable = sc1.endb;
385  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
386  trapEL3 = have_el3 && scr3.api == 0;
387  break;
388  case EL2:
389  enable = sc2.endb;
390  trapEL2 = false;
391  trapEL3 = have_el3 && scr3.api == 0;
392  break;
393  case EL3:
394  enable = sc3.endb;
395  trapEL2 = false;
396  trapEL3 = false;
397  break;
398  default:
399  //unreachable
400  break;
401  }
402  if (!enable)
403  *out = X;
404  else if (trapEL2)
405  return trapPACUse(tc, EL2);
406  else if (trapEL3)
407  return trapPACUse(tc, EL3);
408  else
409  *out = auth(tc, el, X, Y, hi_key, lo_key, true, 0x2);
410 
411  return NoFault;
412 }
413 
414 
415 Fault
416 ArmISA::authIA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
417 {
418 /*
419  Returns a 64-bit value containing X, but replacing the pointer
420  authentication code field bits with the extension of the address bits.
421  The instruction checks a pointer
422  authentication code in the pointer authentication code field bits of X,
423  using the same algorithm and key as AddPACDA().
424 */
425 
426  bool trapEL2 = false;
427  bool trapEL3 = false;
428  bool enable = false;
429 
430  uint64_t hi_key= tc->readMiscReg(MISCREG_APIAKeyHi_EL1);
431  uint64_t lo_key= tc->readMiscReg(MISCREG_APIAKeyLo_EL1);
432 
433  ExceptionLevel el = currEL(tc);
434  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
435  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
436  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
437  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
438  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
439  bool have_el3 = ArmSystem::haveEL(tc, EL3);
440 
441  switch (el)
442  {
443  case EL0:
444  {
445  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
446  enable = IsEL1Regime ? (bool)sc1.enia : (bool)sc2.enia;
447  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
448  (hcr.tge == 0 || hcr.e2h == 0));
449  trapEL3 = have_el3 && scr3.api == 0;
450  break;
451  }
452  case EL1:
453  {
454  enable = sc1.enia;
455  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
456  trapEL3 = have_el3 && scr3.api == 0;
457  break;
458  }
459  case EL2:
460  {
461  enable = sc2.enia;
462  trapEL2 = false;
463  trapEL3 = have_el3 && scr3.api == 0;
464  break;
465  }
466  case EL3:
467  {
468  enable = sc3.enia;
469  trapEL2 = false;
470  trapEL3 = false;
471  break;
472  }
473  default:
474  //unreachable
475  break;
476  }
477  if (!enable)
478  *out = X;
479  else if (trapEL2)
480  return trapPACUse(tc, EL2);
481  else if (trapEL3)
482  return trapPACUse(tc, EL3);
483  else
484  *out = auth(tc, el, X, Y, hi_key, lo_key, false, 0x1);
485 
486  return NoFault;
487 }
488 
489 Fault
490 ArmISA::authIB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t* out)
491 {
492 /*
493  Returns a 64-bit value containing X, but replacing the pointer
494  authentication code field bits with the extension of the address bits.
495  The instruction checks a pointer
496  authentication code in the pointer authentication code field bits of X,
497  using the same algorithm and key as AddPACDA().
498 */
499 
500  bool trapEL2 = false;
501  bool trapEL3 = false;
502  bool enable = false;
503 
504  uint64_t hi_key= tc->readMiscReg(MISCREG_APIBKeyHi_EL1);
505  uint64_t lo_key= tc->readMiscReg(MISCREG_APIBKeyLo_EL1);
506 
507  ExceptionLevel el = currEL(tc);
508  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
509  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
510  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
511  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
512  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
513  bool have_el3 = ArmSystem::haveEL(tc, EL3);
514 
515  switch (el)
516  {
517  case EL0:
518  {
519  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
520  enable = IsEL1Regime ? (bool)sc1.enib : (bool)sc2.enib;
521  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
522  (hcr.tge == 0 || hcr.e2h == 0));
523  trapEL3 = have_el3 && scr3.api == 0;
524  break;
525  }
526  case EL1:
527  {
528  enable = sc1.enib;
529  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
530  trapEL3 = have_el3 && scr3.api == 0;
531  break;
532  }
533  case EL2:
534  {
535  enable = sc2.enib;
536  trapEL2 = false;
537  trapEL3 = have_el3 && scr3.api == 0;
538  break;
539  }
540  case EL3:
541  {
542  enable = sc3.enib;
543  trapEL2 = false;
544  trapEL3 = false;
545  break;
546  }
547  default:
548  //unreachable
549  break;
550  }
551  if (!enable)
552  *out = X;
553  else if (trapEL2)
554  return trapPACUse(tc, EL2);
555  else if (trapEL3)
556  return trapPACUse(tc, EL3);
557  else
558  *out = auth(tc, el, X, Y, hi_key, lo_key, false, 0x2);
559 
560  return NoFault;
561 }
562 
563 
564 
565 Fault
566 ArmISA::addPACDA(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
567 {
568  bool trapEL2 = false;
569  bool trapEL3 = false;
570  bool enable = false;
571 
572  uint64_t hi_key= tc->readMiscReg(MISCREG_APDAKeyHi_EL1);
573  uint64_t lo_key= tc->readMiscReg(MISCREG_APDAKeyLo_EL1);
574 
575  ExceptionLevel el = currEL(tc);
576  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
577  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
578  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
579  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
580  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
581  bool have_el3 = ArmSystem::haveEL(tc, EL3);
582 
583  switch (el)
584  {
585  case EL0:
586  {
587  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
588  enable = IsEL1Regime ? (bool)sc1.enda : (bool)sc2.enda;
589  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
590  (hcr.tge == 0 || hcr.e2h == 0));
591  trapEL3 = have_el3 && scr3.api == 0;
592  break;
593  }
594  case EL1:
595  {
596  enable = sc1.enda;
597  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
598  trapEL3 = have_el3 && scr3.api == 0;
599  break;
600  }
601  case EL2:
602  {
603  enable = sc2.enda;
604  trapEL2 = false;
605  trapEL3 = have_el3 && scr3.api == 0;
606  break;
607  }
608  case EL3:
609  {
610  enable = sc3.enda;
611  trapEL2 = false;
612  trapEL3 = false;
613  break;
614  }
615  }
616  if (!enable)
617  *out = X;
618  else if (trapEL2)
619  return trapPACUse(tc, EL2);
620  else if (trapEL3)
621  return trapPACUse(tc, EL3);
622  else
623  *out = addPAC(tc, el, X, Y, hi_key, lo_key, true);
624 
625  return NoFault;
626 }
627 
628 
629 Fault
630 ArmISA::addPACDB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
631 {
632  bool trapEL2 = false;
633  bool trapEL3 = false;
634  bool enable = false;
635 
636  uint64_t hi_key= tc->readMiscReg(MISCREG_APDBKeyHi_EL1);
637  uint64_t lo_key= tc->readMiscReg(MISCREG_APDBKeyLo_EL1);
638 
639  ExceptionLevel el = currEL(tc);
640  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
641  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
642  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
643  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
644  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
645  bool have_el3 = ArmSystem::haveEL(tc, EL3);
646 
647  switch (el)
648  {
649  case EL0:
650  {
651  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
652  enable = IsEL1Regime ? (bool)sc1.endb : (bool)sc2.endb;
653  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
654  (hcr.tge == 0 || hcr.e2h == 0));
655  trapEL3 = have_el3 && scr3.api == 0;
656  break;
657  }
658  case EL1:
659  enable = sc1.endb;
660  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
661  trapEL3 = have_el3 && scr3.api == 0;
662  break;
663  case EL2:
664  enable = sc2.endb;
665  trapEL2 = false;
666  trapEL3 = have_el3 && scr3.api == 0;
667  break;
668  case EL3:
669  enable = sc3.endb;
670  trapEL2 = false;
671  trapEL3 = false;
672  break;
673  default:
674  // unreachable
675  break;
676  }
677  if (!enable)
678  *out = X;
679  else if (trapEL2)
680  return trapPACUse(tc, EL2);
681  else if (trapEL3)
682  return trapPACUse(tc, EL3);
683  else
684  *out = addPAC(tc, el, X, Y, hi_key, lo_key, true);
685 
686  return NoFault;
687 }
688 
689 
690 Fault
691 ArmISA::addPACGA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
692 {
693  bool trapEL2 = false;
694  bool trapEL3 = false;
695 
696  uint64_t hi_key= tc->readMiscReg(MISCREG_APGAKeyHi_EL1);
697  uint64_t lo_key= tc->readMiscReg(MISCREG_APGAKeyLo_EL1);
698 
699  ExceptionLevel el = currEL(tc);
700  SCR sc3 = tc->readMiscReg(MISCREG_SCR_EL3);
701  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
702  bool have_el3 = ArmSystem::haveEL(tc, EL3);
703 
704  switch (el)
705  {
706  case EL0:
707  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
708  (hcr.tge == 0 || hcr.e2h == 0));
709  trapEL3 = have_el3 && sc3.api == 0;
710  break;
711  case EL1:
712  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
713  trapEL3 = have_el3 && sc3.api == 0;
714  break;
715  case EL2:
716  trapEL2 = false;
717  trapEL3 = have_el3 && sc3.api == 0;
718  break;
719  case EL3:
720  trapEL2 = false;
721  trapEL3 = false;
722  break;
723  default:
724  //unreachable
725  break;
726  }
727  if (trapEL2)
728  return trapPACUse(tc, EL2);
729  else if (trapEL3)
730  return trapPACUse(tc, EL3);
731  else
732  *out = QARMA::computePAC(X, Y, hi_key, lo_key) & 0xFFFFFFFF00000000;
733 
734  return NoFault;
735 }
736 
737 
738 Fault
739 ArmISA::addPACIA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out){
740  bool trapEL2 = false;
741  bool trapEL3 = false;
742  bool enable = false;
743 
744  uint64_t hi_key= tc->readMiscReg(MISCREG_APIAKeyHi_EL1);
745  uint64_t lo_key= tc->readMiscReg(MISCREG_APIAKeyLo_EL1);
746 
747  ExceptionLevel el = currEL(tc);
748  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
749  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
750  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
751  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
752  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
753  bool have_el3 = ArmSystem::haveEL(tc, EL3);
754 
755  switch (el)
756  {
757  case EL0:
758  {
759  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
760  enable = IsEL1Regime ? (bool)sc1.enia : (bool)sc2.enia;
761  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
762  (hcr.tge == 0 || hcr.e2h == 0));
763  trapEL3 = have_el3 && scr3.api == 0;
764  break;
765  }
766  case EL1:
767  enable = sc1.enia;
768  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
769  trapEL3 = have_el3 && scr3.api == 0;
770  break;
771  case EL2:
772  enable = sc2.enia;
773  trapEL2 = false;
774  trapEL3 = have_el3 && scr3.api == 0;
775  break;
776  case EL3:
777  enable = sc3.enia;
778  trapEL2 = false;
779  trapEL3 = false;
780  break;
781  default:
782  //unreachable
783  break;
784  }
785  if (!enable)
786  *out = X;
787  else if (trapEL2)
788  return trapPACUse(tc, EL2);
789  else if (trapEL3)
790  return trapPACUse(tc, EL3);
791  else
792  *out = addPAC(tc, el, X, Y, hi_key, lo_key, false);
793 
794  return NoFault;
795 }
796 
797 Fault
798 ArmISA::addPACIB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out){
799  bool trapEL2 = false;
800  bool trapEL3 = false;
801  bool enable = false;
802 
803  uint64_t hi_key= tc->readMiscReg(MISCREG_APIBKeyHi_EL1);
804  uint64_t lo_key= tc->readMiscReg(MISCREG_APIBKeyLo_EL1);
805 
806  ExceptionLevel el = currEL(tc);
807  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
808  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
809  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
810  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
811  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
812  bool have_el3 = ArmSystem::haveEL(tc, EL3);
813 
814  switch (el)
815  {
816  case EL0:
817  {
818  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
819  enable = IsEL1Regime ? (bool)sc1.enib : (bool)sc2.enib;
820  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
821  (hcr.tge == 0 || hcr.e2h == 0));
822  trapEL3 = have_el3 && scr3.api == 0;
823  break;
824  }
825  case EL1:
826  enable = sc1.enib;
827  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
828  trapEL3 = have_el3 && scr3.api == 0;
829  break;
830  case EL2:
831  enable = sc2.enib;
832  trapEL2 = false;
833  trapEL3 = have_el3 && scr3.api == 0;
834  break;
835  case EL3:
836  enable = sc3.enib;
837  trapEL2 = false;
838  trapEL3 = false;
839  break;
840  default:
841  // Unnaccessible
842  break;
843  }
844 
845  if (!enable)
846  *out = X;
847  else if (trapEL2)
848  return trapPACUse(tc, EL2);
849  else if (trapEL3)
850  return trapPACUse(tc, EL3);
851  else
852  *out = addPAC(tc, el, X, Y, hi_key, lo_key, false);
853 
854  return NoFault;
855 }
856 
857 
858 
859 Fault
860 ArmISA::stripPAC(ThreadContext* tc, uint64_t A, bool data, uint64_t* out){
861  bool trapEL2 = false;
862  bool trapEL3 = false;
863 
864  uint64_t ptr;
865 
866  ExceptionLevel el = currEL(tc);
867 
868  bool tbi = calculateTBI(tc, el, A, data);
869  bool selbit = (bool) bits(A, 55);
870  int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
871 
872  int top_bit = tbi ? 55 : 63;
873  uint32_t nbits = (top_bit+1) - bottom_PAC_bit;
874  uint64_t pacbits = ((uint64_t)0x1 << nbits) -1; // 2^n -1;
875  uint64_t mask = pacbits << bottom_PAC_bit; // creates mask
876 
877 
878  if (selbit) {
879  ptr = A | mask;
880  } else {
881  ptr = A & ~mask;
882  }
883 
884  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
885  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
886  bool have_el3 = ArmSystem::haveEL(tc, EL3);
887 
888  switch (el)
889  {
890  case EL0:
891  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
892  (hcr.tge == 0 || hcr.e2h == 0));
893  trapEL3 = have_el3 && scr3.api == 0;
894  break;
895  case EL1:
896  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
897  trapEL3 = have_el3 && scr3.api == 0;
898  break;
899  case EL2:
900  trapEL2 = false;
901  trapEL3 = have_el3 && scr3.api == 0;
902  break;
903  case EL3:
904  trapEL2 = false;
905  trapEL3 = false;
906  break;
907  default:
908  // Unnaccessible
909  break;
910  }
911  if (trapEL2)
912  return trapPACUse(tc, EL2);
913  else if (trapEL3)
914  return trapPACUse(tc, EL3);
915  else
916  *out = ptr;
917 
918  return NoFault;
919 }
920 
ArmISA::MISCREG_ID_AA64MMFR2_EL1
@ MISCREG_ID_AA64MMFR2_EL1
Definition: miscregs.hh:818
ArmISA::MISCREG_APIBKeyLo_EL1
@ MISCREG_APIBKeyLo_EL1
Definition: miscregs.hh:830
ArmISA::EL2Enabled
bool EL2Enabled(ThreadContext *tc)
Definition: utility.cc:314
ArmISA::EC_TRAPPED_PAC
@ EC_TRAPPED_PAC
Definition: types.hh:659
ArmISA::trapPACUse
Fault trapPACUse(ThreadContext *tc, ExceptionLevel el)
Definition: pauth_helpers.cc:113
ArmISA::EL2
@ EL2
Definition: types.hh:624
data
const char data[]
Definition: circlebuf.test.cc:47
ArmISA::calculateTBI
bool calculateTBI(ThreadContext *tc, ExceptionLevel el, uint64_t ptr, bool data)
Definition: pauth_helpers.cc:46
ArmISA::MISCREG_APDBKeyLo_EL1
@ MISCREG_APDBKeyLo_EL1
Definition: miscregs.hh:824
ArmISA::addPACGA
Fault addPACGA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:691
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:131
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:221
ArmISA::MISCREG_APDBKeyHi_EL1
@ MISCREG_APDBKeyHi_EL1
Definition: miscregs.hh:823
ArmISA::stripPAC
Fault stripPAC(ThreadContext *tc, uint64_t A, bool data, uint64_t *out)
Definition: pauth_helpers.cc:860
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:825
ArmISA::MISCREG_TCR_EL2
@ MISCREG_TCR_EL2
Definition: miscregs.hh:600
ArmISA::addPACDA
Fault addPACDA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:566
ArmISA
Definition: ccregs.hh:41
ArmISA::MISCREG_TCR_EL3
@ MISCREG_TCR_EL3
Definition: miscregs.hh:606
ArmISA::calculateBottomPACBit
int calculateBottomPACBit(ThreadContext *tc, ExceptionLevel el, bool top_bit)
Definition: pauth_helpers.cc:76
ArmISA::authIB
Fault authIB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:490
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:416
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:630
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:129
Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:246
ArmISA::MISCREG_APIBKeyHi_EL1
@ MISCREG_APIBKeyHi_EL1
Definition: miscregs.hh:829
ArmISA::MISCREG_APDAKeyLo_EL1
@ MISCREG_APDAKeyLo_EL1
Definition: miscregs.hh:822
ArmISA::MISCREG_APGAKeyLo_EL1
@ MISCREG_APGAKeyLo_EL1
Definition: miscregs.hh:826
ArmISA::MISCREG_TCR_EL1
@ MISCREG_TCR_EL1
Definition: miscregs.hh:597
ArmISA::el
Bitfield< 3, 2 > el
Definition: miscregs_types.hh:69
ArmISA::s1TranslationRegime
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:278
faults.hh
ArmISA::MISCREG_HCR_EL2
@ MISCREG_HCR_EL2
Definition: miscregs.hh:582
NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:251
ArmISA::EL1
@ EL1
Definition: types.hh:623
ArmISA::MISCREG_APIAKeyLo_EL1
@ MISCREG_APIAKeyLo_EL1
Definition: miscregs.hh:828
ArmISA::MISCREG_APIAKeyHi_EL1
@ MISCREG_APIAKeyHi_EL1
Definition: miscregs.hh:827
pauth_helpers.hh
ArmISA::MISCREG_SCR_EL3
@ MISCREG_SCR_EL3
Definition: miscregs.hh:589
ArmISA::MISCREG_APDAKeyHi_EL1
@ MISCREG_APDAKeyHi_EL1
Definition: miscregs.hh:821
QARMA::computePAC
BIT64 computePAC(BIT64 data, BIT64 modifier, BIT64 key0, BIT64 key1)
Definition: qarma.cc:329
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
bits
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:73
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:346
ArmISA::addPACIB
Fault addPACIB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:798
ArmISA::addPACIA
Fault addPACIA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:739
ArmISA::MISCREG_SCTLR_EL3
@ MISCREG_SCTLR_EL3
Definition: miscregs.hh:587
ArmISA::authDA
Fault authDA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Definition: pauth_helpers.cc:278
ArmISA::MISCREG_SCTLR_EL2
@ MISCREG_SCTLR_EL2
Definition: miscregs.hh:580
ArmISA::mask
Bitfield< 28, 24 > mask
Definition: miscregs_types.hh:711
ArmISA::MISCREG_SCTLR_EL1
@ MISCREG_SCTLR_EL1
Definition: miscregs.hh:575

Generated on Tue Mar 23 2021 19:41:20 for gem5 by doxygen 1.8.17