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