1 // © 2021 Qualcomm Innovation Center, Inc. All rights reserved.
2 //
3 // SPDX-License-Identifier; BSD-3-Clause
4
5 #include <assert.h>
6 #include <hyptypes.h>
7
8 #include <hypregisters.h>
9
10 #include <compiler.h>
11 #include <hyp_aspace.h>
12 #include <log.h>
13 #include <panic.h>
14 #include <partition.h>
15 #include <trace.h>
16 #include <util.h>
17
18 #include "event_handlers.h"
19
20 void
partition_phys_access_cpu_warm_init(void)21 partition_phys_access_cpu_warm_init(void)
22 {
23 #if ARCH_AARCH64_USE_PAN
24 __asm__ volatile("msr PAN, 1" ::: "memory");
25 #else
26 // Nothing to do here.
27 #endif
28 }
29
30 static bool
memory_attr_type_check(MAIR_ATTR_t memattr,paddr_t check_pa)31 memory_attr_type_check(MAIR_ATTR_t memattr, paddr_t check_pa)
32 {
33 bool ret = true;
34
35 switch (memattr) {
36 case MAIR_ATTR_DEVICE_NGNRNE:
37 case MAIR_ATTR_DEVICE_NGNRE:
38 case MAIR_ATTR_DEVICE_NGRE:
39 case MAIR_ATTR_DEVICE_GRE:
40 ret = false;
41 break;
42 case MAIR_ATTR_NORMAL_NC:
43 case MAIR_ATTR_NORMAL_WB_OUTER_NC:
44 #if defined(ARCH_ARM_FEAT_MTE)
45 case MAIR_ATTR_TAGGED_NORMAL_WB:
46 #endif
47 case MAIR_ATTR_NORMAL_WB:
48 break;
49 case MAIR_ATTR_DEVICE_NGNRNE_XS:
50 case MAIR_ATTR_DEVICE_NGNRE_XS:
51 case MAIR_ATTR_DEVICE_NGRE_XS:
52 case MAIR_ATTR_DEVICE_GRE_XS:
53 default:
54 LOG(ERROR, WARN,
55 "Unexpected look-up result in partition_phys_valid."
56 " PA:{:#x}, attr : {:#x}",
57 check_pa, (register_t)memattr);
58 ret = false;
59 break;
60 }
61
62 return ret;
63 }
64
65 bool
partition_phys_valid(paddr_t paddr,size_t size)66 partition_phys_valid(paddr_t paddr, size_t size)
67 {
68 bool ret = true;
69
70 if (util_add_overflows(paddr, size)) {
71 ret = false;
72 goto out;
73 }
74 if (paddr >= util_bit(HYP_ASPACE_MAP_DIRECT_BITS)) {
75 ret = false;
76 goto out;
77 }
78
79 for (paddr_t check_pa = paddr; check_pa < (paddr + size);
80 check_pa += PGTABLE_HYP_PAGE_SIZE) {
81 paddr_t pa_lookup;
82 MAIR_ATTR_t memattr;
83 void *check_va = (void *)((uintptr_t)check_pa +
84 hyp_aspace_get_physaccess_offset());
85 error_t err = hyp_aspace_va_to_pa_el2_read(check_va, &pa_lookup,
86 &memattr, NULL);
87
88 if (err != OK) {
89 LOG(DEBUG, INFO,
90 "partition_phys_valid failed for PA: {:#x}",
91 check_pa);
92 ret = false;
93 break;
94 }
95
96 if (compiler_unexpected(check_pa != pa_lookup)) {
97 LOG(ERROR, WARN,
98 "Unexpected look-up result in partition_phys_valid."
99 " PA:{:#x}, looked-up PA: {:#x}",
100 check_pa, pa_lookup);
101 panic("partition_phys_valid: Bad look-up result");
102 }
103
104 // We map the hyp_aspace_physaccess_offset as device type when
105 // invalid.
106 ret = memory_attr_type_check(memattr, check_pa);
107
108 if (!ret) {
109 break;
110 }
111 }
112
113 out:
114 return ret;
115 }
116
117 void *
partition_phys_map(paddr_t paddr,size_t size)118 partition_phys_map(paddr_t paddr, size_t size)
119 {
120 assert(!util_add_overflows(paddr, size));
121 assert_debug(partition_phys_valid(paddr, size));
122
123 return (void *)((uintptr_t)paddr + hyp_aspace_get_physaccess_offset());
124 }
125
126 void
partition_phys_access_enable(const void * ptr)127 partition_phys_access_enable(const void *ptr)
128 {
129 (void)ptr;
130 #if ARCH_AARCH64_USE_PAN
131 __asm__ volatile("msr PAN, 0" ::: "memory");
132 #else
133 // Nothing to do here.
134 #endif
135 }
136
137 void
partition_phys_access_disable(const void * ptr)138 partition_phys_access_disable(const void *ptr)
139 {
140 (void)ptr;
141 #if ARCH_AARCH64_USE_PAN
142 __asm__ volatile("msr PAN, 1" ::: "memory");
143 #else
144 // Nothing to do here.
145 #endif
146 }
147
148 void
partition_phys_unmap(const void * vaddr,paddr_t paddr,size_t size)149 partition_phys_unmap(const void *vaddr, paddr_t paddr, size_t size)
150 {
151 #if ARCH_AARCH64_USE_PAN
152 (void)vaddr;
153 (void)paddr;
154 (void)size;
155
156 // Nothing to do here.
157 #else
158 (void)vaddr;
159 (void)paddr;
160 (void)size;
161
162 // Nothing to do here.
163 #endif
164 }
165