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