xref: /openbmc/qemu/target/riscv/pmp.c (revision e924074f)
1 /*
2  * QEMU RISC-V PMP (Physical Memory Protection)
3  *
4  * Author: Daire McNamara, daire.mcnamara@emdalo.com
5  *         Ivan Griffin, ivan.griffin@emdalo.com
6  *
7  * This provides a RISC-V Physical Memory Protection implementation
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms and conditions of the GNU General Public License,
11  * version 2 or later, as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along with
19  * this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "qemu/osdep.h"
23 #include "qemu/log.h"
24 #include "qapi/error.h"
25 #include "cpu.h"
26 #include "trace.h"
27 #include "exec/exec-all.h"
28 
29 static bool pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
30                           uint8_t val);
31 static uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t addr_index);
32 static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index);
33 
34 /*
35  * Accessor method to extract address matching type 'a field' from cfg reg
36  */
37 static inline uint8_t pmp_get_a_field(uint8_t cfg)
38 {
39     uint8_t a = cfg >> 3;
40     return a & 0x3;
41 }
42 
43 /*
44  * Check whether a PMP is locked or not.
45  */
46 static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
47 {
48 
49     if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) {
50         return 1;
51     }
52 
53     /* Top PMP has no 'next' to check */
54     if ((pmp_index + 1u) >= MAX_RISCV_PMPS) {
55         return 0;
56     }
57 
58     return 0;
59 }
60 
61 /*
62  * Count the number of active rules.
63  */
64 uint32_t pmp_get_num_rules(CPURISCVState *env)
65 {
66      return env->pmp_state.num_rules;
67 }
68 
69 /*
70  * Accessor to get the cfg reg for a specific PMP/HART
71  */
72 static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index)
73 {
74     if (pmp_index < MAX_RISCV_PMPS) {
75         return env->pmp_state.pmp[pmp_index].cfg_reg;
76     }
77 
78     return 0;
79 }
80 
81 
82 /*
83  * Accessor to set the cfg reg for a specific PMP/HART
84  * Bounds checks and relevant lock bit.
85  */
86 static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
87 {
88     if (pmp_index < MAX_RISCV_PMPS) {
89         bool locked = true;
90 
91         if (riscv_cpu_cfg(env)->epmp) {
92             /* mseccfg.RLB is set */
93             if (MSECCFG_RLB_ISSET(env)) {
94                 locked = false;
95             }
96 
97             /* mseccfg.MML is not set */
98             if (!MSECCFG_MML_ISSET(env) && !pmp_is_locked(env, pmp_index)) {
99                 locked = false;
100             }
101 
102             /* mseccfg.MML is set */
103             if (MSECCFG_MML_ISSET(env)) {
104                 /* not adding execute bit */
105                 if ((val & PMP_LOCK) != 0 && (val & PMP_EXEC) != PMP_EXEC) {
106                     locked = false;
107                 }
108                 /* shared region and not adding X bit */
109                 if ((val & PMP_LOCK) != PMP_LOCK &&
110                     (val & 0x7) != (PMP_WRITE | PMP_EXEC)) {
111                     locked = false;
112                 }
113             }
114         } else {
115             if (!pmp_is_locked(env, pmp_index)) {
116                 locked = false;
117             }
118         }
119 
120         if (locked) {
121             qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
122         } else if (env->pmp_state.pmp[pmp_index].cfg_reg != val) {
123             env->pmp_state.pmp[pmp_index].cfg_reg = val;
124             pmp_update_rule(env, pmp_index);
125             return true;
126         }
127     } else {
128         qemu_log_mask(LOG_GUEST_ERROR,
129                       "ignoring pmpcfg write - out of bounds\n");
130     }
131 
132     return false;
133 }
134 
135 static void pmp_decode_napot(target_ulong a, target_ulong *sa,
136                              target_ulong *ea)
137 {
138     /*
139      * aaaa...aaa0   8-byte NAPOT range
140      * aaaa...aa01   16-byte NAPOT range
141      * aaaa...a011   32-byte NAPOT range
142      * ...
143      * aa01...1111   2^XLEN-byte NAPOT range
144      * a011...1111   2^(XLEN+1)-byte NAPOT range
145      * 0111...1111   2^(XLEN+2)-byte NAPOT range
146      * 1111...1111   Reserved
147      */
148     a = (a << 2) | 0x3;
149     *sa = a & (a + 1);
150     *ea = a | (a + 1);
151 }
152 
153 void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
154 {
155     uint8_t this_cfg = env->pmp_state.pmp[pmp_index].cfg_reg;
156     target_ulong this_addr = env->pmp_state.pmp[pmp_index].addr_reg;
157     target_ulong prev_addr = 0u;
158     target_ulong sa = 0u;
159     target_ulong ea = 0u;
160 
161     if (pmp_index >= 1u) {
162         prev_addr = env->pmp_state.pmp[pmp_index - 1].addr_reg;
163     }
164 
165     switch (pmp_get_a_field(this_cfg)) {
166     case PMP_AMATCH_OFF:
167         sa = 0u;
168         ea = -1;
169         break;
170 
171     case PMP_AMATCH_TOR:
172         sa = prev_addr << 2; /* shift up from [xx:0] to [xx+2:2] */
173         ea = (this_addr << 2) - 1u;
174         if (sa > ea) {
175             sa = ea = 0u;
176         }
177         break;
178 
179     case PMP_AMATCH_NA4:
180         sa = this_addr << 2; /* shift up from [xx:0] to [xx+2:2] */
181         ea = (sa + 4u) - 1u;
182         break;
183 
184     case PMP_AMATCH_NAPOT:
185         pmp_decode_napot(this_addr, &sa, &ea);
186         break;
187 
188     default:
189         sa = 0u;
190         ea = 0u;
191         break;
192     }
193 
194     env->pmp_state.addr[pmp_index].sa = sa;
195     env->pmp_state.addr[pmp_index].ea = ea;
196 }
197 
198 void pmp_update_rule_nums(CPURISCVState *env)
199 {
200     int i;
201 
202     env->pmp_state.num_rules = 0;
203     for (i = 0; i < MAX_RISCV_PMPS; i++) {
204         const uint8_t a_field =
205             pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
206         if (PMP_AMATCH_OFF != a_field) {
207             env->pmp_state.num_rules++;
208         }
209     }
210 }
211 
212 /*
213  * Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
214  *   end address values.
215  *   This function is called relatively infrequently whereas the check that
216  *   an address is within a pmp rule is called often, so optimise that one
217  */
218 static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
219 {
220     pmp_update_rule_addr(env, pmp_index);
221     pmp_update_rule_nums(env);
222 }
223 
224 static int pmp_is_in_range(CPURISCVState *env, int pmp_index,
225                            target_ulong addr)
226 {
227     int result = 0;
228 
229     if ((addr >= env->pmp_state.addr[pmp_index].sa) &&
230         (addr <= env->pmp_state.addr[pmp_index].ea)) {
231         result = 1;
232     } else {
233         result = 0;
234     }
235 
236     return result;
237 }
238 
239 /*
240  * Check if the address has required RWX privs when no PMP entry is matched.
241  */
242 static bool pmp_hart_has_privs_default(CPURISCVState *env, pmp_priv_t privs,
243                                        pmp_priv_t *allowed_privs,
244                                        target_ulong mode)
245 {
246     bool ret;
247 
248     if (MSECCFG_MMWP_ISSET(env)) {
249         /*
250          * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
251          * so we default to deny all, even for M-mode.
252          */
253         *allowed_privs = 0;
254         return false;
255     } else if (MSECCFG_MML_ISSET(env)) {
256         /*
257          * The Machine Mode Lockdown (mseccfg.MML) bit is set
258          * so we can only execute code in M-mode with an applicable
259          * rule. Other modes are disabled.
260          */
261         if (mode == PRV_M && !(privs & PMP_EXEC)) {
262             ret = true;
263             *allowed_privs = PMP_READ | PMP_WRITE;
264         } else {
265             ret = false;
266             *allowed_privs = 0;
267         }
268 
269         return ret;
270     }
271 
272     if (!riscv_cpu_cfg(env)->pmp || (mode == PRV_M)) {
273         /*
274          * Privileged spec v1.10 states if HW doesn't implement any PMP entry
275          * or no PMP entry matches an M-Mode access, the access succeeds.
276          */
277         ret = true;
278         *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
279     } else {
280         /*
281          * Other modes are not allowed to succeed if they don't * match a rule,
282          * but there are rules. We've checked for no rule earlier in this
283          * function.
284          */
285         ret = false;
286         *allowed_privs = 0;
287     }
288 
289     return ret;
290 }
291 
292 
293 /*
294  * Public Interface
295  */
296 
297 /*
298  * Check if the address has required RWX privs to complete desired operation
299  * Return true if a pmp rule match or default match
300  * Return false if no match
301  */
302 bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
303                         target_ulong size, pmp_priv_t privs,
304                         pmp_priv_t *allowed_privs, target_ulong mode)
305 {
306     int i = 0;
307     bool ret = false;
308     int pmp_size = 0;
309     target_ulong s = 0;
310     target_ulong e = 0;
311 
312     /* Short cut if no rules */
313     if (0 == pmp_get_num_rules(env)) {
314         return pmp_hart_has_privs_default(env, privs, allowed_privs, mode);
315     }
316 
317     if (size == 0) {
318         if (riscv_cpu_cfg(env)->mmu) {
319             /*
320              * If size is unknown (0), assume that all bytes
321              * from addr to the end of the page will be accessed.
322              */
323             pmp_size = -(addr | TARGET_PAGE_MASK);
324         } else {
325             pmp_size = sizeof(target_ulong);
326         }
327     } else {
328         pmp_size = size;
329     }
330 
331     /*
332      * 1.10 draft priv spec states there is an implicit order
333      * from low to high
334      */
335     for (i = 0; i < MAX_RISCV_PMPS; i++) {
336         s = pmp_is_in_range(env, i, addr);
337         e = pmp_is_in_range(env, i, addr + pmp_size - 1);
338 
339         /* partially inside */
340         if ((s + e) == 1) {
341             qemu_log_mask(LOG_GUEST_ERROR,
342                           "pmp violation - access is partially inside\n");
343             ret = false;
344             break;
345         }
346 
347         /* fully inside */
348         const uint8_t a_field =
349             pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
350 
351         /*
352          * Convert the PMP permissions to match the truth table in the
353          * ePMP spec.
354          */
355         const uint8_t epmp_operation =
356             ((env->pmp_state.pmp[i].cfg_reg & PMP_LOCK) >> 4) |
357             ((env->pmp_state.pmp[i].cfg_reg & PMP_READ) << 2) |
358             (env->pmp_state.pmp[i].cfg_reg & PMP_WRITE) |
359             ((env->pmp_state.pmp[i].cfg_reg & PMP_EXEC) >> 2);
360 
361         if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
362             /*
363              * If the PMP entry is not off and the address is in range,
364              * do the priv check
365              */
366             if (!MSECCFG_MML_ISSET(env)) {
367                 /*
368                  * If mseccfg.MML Bit is not set, do pmp priv check
369                  * This will always apply to regular PMP.
370                  */
371                 *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
372                 if ((mode != PRV_M) || pmp_is_locked(env, i)) {
373                     *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
374                 }
375             } else {
376                 /*
377                  * If mseccfg.MML Bit set, do the enhanced pmp priv check
378                  */
379                 if (mode == PRV_M) {
380                     switch (epmp_operation) {
381                     case 0:
382                     case 1:
383                     case 4:
384                     case 5:
385                     case 6:
386                     case 7:
387                     case 8:
388                         *allowed_privs = 0;
389                         break;
390                     case 2:
391                     case 3:
392                     case 14:
393                         *allowed_privs = PMP_READ | PMP_WRITE;
394                         break;
395                     case 9:
396                     case 10:
397                         *allowed_privs = PMP_EXEC;
398                         break;
399                     case 11:
400                     case 13:
401                         *allowed_privs = PMP_READ | PMP_EXEC;
402                         break;
403                     case 12:
404                     case 15:
405                         *allowed_privs = PMP_READ;
406                         break;
407                     default:
408                         g_assert_not_reached();
409                     }
410                 } else {
411                     switch (epmp_operation) {
412                     case 0:
413                     case 8:
414                     case 9:
415                     case 12:
416                     case 13:
417                     case 14:
418                         *allowed_privs = 0;
419                         break;
420                     case 1:
421                     case 10:
422                     case 11:
423                         *allowed_privs = PMP_EXEC;
424                         break;
425                     case 2:
426                     case 4:
427                     case 15:
428                         *allowed_privs = PMP_READ;
429                         break;
430                     case 3:
431                     case 6:
432                         *allowed_privs = PMP_READ | PMP_WRITE;
433                         break;
434                     case 5:
435                         *allowed_privs = PMP_READ | PMP_EXEC;
436                         break;
437                     case 7:
438                         *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
439                         break;
440                     default:
441                         g_assert_not_reached();
442                     }
443                 }
444             }
445 
446             /*
447              * If matching address range was found, the protection bits
448              * defined with PMP must be used. We shouldn't fallback on
449              * finding default privileges.
450              */
451             ret = true;
452             break;
453         }
454     }
455 
456     /* No rule matched */
457     if (!ret) {
458         ret = pmp_hart_has_privs_default(env, privs, allowed_privs, mode);
459     }
460 
461     return ret;
462 }
463 
464 /*
465  * Handle a write to a pmpcfg CSR
466  */
467 void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
468                       target_ulong val)
469 {
470     int i;
471     uint8_t cfg_val;
472     int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
473     bool modified = false;
474 
475     trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
476 
477     for (i = 0; i < pmpcfg_nums; i++) {
478         cfg_val = (val >> 8 * i)  & 0xff;
479         modified |= pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
480     }
481 
482     /* If PMP permission of any addr has been changed, flush TLB pages. */
483     if (modified) {
484         tlb_flush(env_cpu(env));
485     }
486 }
487 
488 
489 /*
490  * Handle a read from a pmpcfg CSR
491  */
492 target_ulong pmpcfg_csr_read(CPURISCVState *env, uint32_t reg_index)
493 {
494     int i;
495     target_ulong cfg_val = 0;
496     target_ulong val = 0;
497     int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
498 
499     for (i = 0; i < pmpcfg_nums; i++) {
500         val = pmp_read_cfg(env, (reg_index * 4) + i);
501         cfg_val |= (val << (i * 8));
502     }
503     trace_pmpcfg_csr_read(env->mhartid, reg_index, cfg_val);
504 
505     return cfg_val;
506 }
507 
508 
509 /*
510  * Handle a write to a pmpaddr CSR
511  */
512 void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
513                        target_ulong val)
514 {
515     trace_pmpaddr_csr_write(env->mhartid, addr_index, val);
516     bool is_next_cfg_tor = false;
517 
518     if (addr_index < MAX_RISCV_PMPS) {
519         /*
520          * In TOR mode, need to check the lock bit of the next pmp
521          * (if there is a next).
522          */
523         if (addr_index + 1 < MAX_RISCV_PMPS) {
524             uint8_t pmp_cfg = env->pmp_state.pmp[addr_index + 1].cfg_reg;
525             is_next_cfg_tor = PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg);
526 
527             if (pmp_cfg & PMP_LOCK && is_next_cfg_tor) {
528                 qemu_log_mask(LOG_GUEST_ERROR,
529                               "ignoring pmpaddr write - pmpcfg + 1 locked\n");
530                 return;
531             }
532         }
533 
534         if (!pmp_is_locked(env, addr_index)) {
535             if (env->pmp_state.pmp[addr_index].addr_reg != val) {
536                 env->pmp_state.pmp[addr_index].addr_reg = val;
537                 pmp_update_rule_addr(env, addr_index);
538                 if (is_next_cfg_tor) {
539                     pmp_update_rule_addr(env, addr_index + 1);
540                 }
541                 tlb_flush(env_cpu(env));
542             }
543         } else {
544             qemu_log_mask(LOG_GUEST_ERROR,
545                           "ignoring pmpaddr write - locked\n");
546         }
547     } else {
548         qemu_log_mask(LOG_GUEST_ERROR,
549                       "ignoring pmpaddr write - out of bounds\n");
550     }
551 }
552 
553 
554 /*
555  * Handle a read from a pmpaddr CSR
556  */
557 target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index)
558 {
559     target_ulong val = 0;
560 
561     if (addr_index < MAX_RISCV_PMPS) {
562         val = env->pmp_state.pmp[addr_index].addr_reg;
563         trace_pmpaddr_csr_read(env->mhartid, addr_index, val);
564     } else {
565         qemu_log_mask(LOG_GUEST_ERROR,
566                       "ignoring pmpaddr read - out of bounds\n");
567     }
568 
569     return val;
570 }
571 
572 /*
573  * Handle a write to a mseccfg CSR
574  */
575 void mseccfg_csr_write(CPURISCVState *env, target_ulong val)
576 {
577     int i;
578 
579     trace_mseccfg_csr_write(env->mhartid, val);
580 
581     /* RLB cannot be enabled if it's already 0 and if any regions are locked */
582     if (!MSECCFG_RLB_ISSET(env)) {
583         for (i = 0; i < MAX_RISCV_PMPS; i++) {
584             if (pmp_is_locked(env, i)) {
585                 val &= ~MSECCFG_RLB;
586                 break;
587             }
588         }
589     }
590 
591     if (riscv_cpu_cfg(env)->epmp) {
592         /* Sticky bits */
593         val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML));
594         if ((val ^ env->mseccfg) & (MSECCFG_MMWP | MSECCFG_MML)) {
595             tlb_flush(env_cpu(env));
596         }
597     } else {
598         val &= ~(MSECCFG_MMWP | MSECCFG_MML | MSECCFG_RLB);
599     }
600 
601     env->mseccfg = val;
602 }
603 
604 /*
605  * Handle a read from a mseccfg CSR
606  */
607 target_ulong mseccfg_csr_read(CPURISCVState *env)
608 {
609     trace_mseccfg_csr_read(env->mhartid, env->mseccfg);
610     return env->mseccfg;
611 }
612 
613 /*
614  * Calculate the TLB size.
615  * It's possible that PMP regions only cover partial of the TLB page, and
616  * this may split the page into regions with different permissions.
617  * For example if PMP0 is (0x80000008~0x8000000F, R) and PMP1 is (0x80000000
618  * ~0x80000FFF, RWX), then region 0x80000008~0x8000000F has R permission, and
619  * the other regions in this page have RWX permissions.
620  * A write access to 0x80000000 will match PMP1. However we cannot cache the
621  * translation result in the TLB since this will make the write access to
622  * 0x80000008 bypass the check of PMP0.
623  * To avoid this we return a size of 1 (which means no caching) if the PMP
624  * region only covers partial of the TLB page.
625  */
626 target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr)
627 {
628     target_ulong pmp_sa;
629     target_ulong pmp_ea;
630     target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
631     target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
632     int i;
633 
634     /*
635      * If PMP is not supported or there are no PMP rules, the TLB page will not
636      * be split into regions with different permissions by PMP so we set the
637      * size to TARGET_PAGE_SIZE.
638      */
639     if (!riscv_cpu_cfg(env)->pmp || !pmp_get_num_rules(env)) {
640         return TARGET_PAGE_SIZE;
641     }
642 
643     for (i = 0; i < MAX_RISCV_PMPS; i++) {
644         if (pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg) == PMP_AMATCH_OFF) {
645             continue;
646         }
647 
648         pmp_sa = env->pmp_state.addr[i].sa;
649         pmp_ea = env->pmp_state.addr[i].ea;
650 
651         /*
652          * Only the first PMP entry that covers (whole or partial of) the TLB
653          * page really matters:
654          * If it covers the whole TLB page, set the size to TARGET_PAGE_SIZE,
655          * since the following PMP entries have lower priority and will not
656          * affect the permissions of the page.
657          * If it only covers partial of the TLB page, set the size to 1 since
658          * the allowed permissions of the region may be different from other
659          * region of the page.
660          */
661         if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) {
662             return TARGET_PAGE_SIZE;
663         } else if ((pmp_sa >= tlb_sa && pmp_sa <= tlb_ea) ||
664                    (pmp_ea >= tlb_sa && pmp_ea <= tlb_ea)) {
665             return 1;
666         }
667     }
668 
669     /*
670      * If no PMP entry matches the TLB page, the TLB page will also not be
671      * split into regions with different permissions by PMP so we set the size
672      * to TARGET_PAGE_SIZE.
673      */
674     return TARGET_PAGE_SIZE;
675 }
676 
677 /*
678  * Convert PMP privilege to TLB page privilege.
679  */
680 int pmp_priv_to_page_prot(pmp_priv_t pmp_priv)
681 {
682     int prot = 0;
683 
684     if (pmp_priv & PMP_READ) {
685         prot |= PAGE_READ;
686     }
687     if (pmp_priv & PMP_WRITE) {
688         prot |= PAGE_WRITE;
689     }
690     if (pmp_priv & PMP_EXEC) {
691         prot |= PAGE_EXEC;
692     }
693 
694     return prot;
695 }
696