Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 249bea0

Browse files
author
Oren Cohen
committedAug 24, 2017
Handle armv8m unpriv_access with SAU
Previously when we got to unpriv_access we verfied the operation with the TT assembly command, we now switch to using the SAU with uVisor vmpu functions. This could slow down the operation since we switch an assembly command with a C function which scans the virtual regions.
1 parent cb31268 commit 249bea0

File tree

1 file changed

+25
-99
lines changed

1 file changed

+25
-99
lines changed
 

‎core/vmpu/src/mpu_armv8m/vmpu_armv8m_unpriv_access.c

+25-99
Original file line numberDiff line numberDiff line change
@@ -15,112 +15,38 @@
1515
* limitations under the License.
1616
*/
1717
#include <uvisor.h>
18+
#include <stdbool.h>
1819
#include "context.h"
19-
#include "debug.h"
20-
#include "vmpu.h"
20+
#include "halt.h"
21+
#include "vmpu_mpu.h"
2122
#include "vmpu_unpriv_access.h"
22-
#include <stdbool.h>
23-
24-
#define TT_RESP_IREGION_Pos 24U
25-
#define TT_RESP_IREGION_Msk (0xFFUL << TT_RESP_IREGION_Pos)
26-
27-
#define TT_RESP_IRVALID_Pos 23U
28-
#define TT_RESP_IRVALID_Msk (1UL << TT_RESP_IRVALID_Pos)
29-
30-
#define TT_RESP_S_Pos 22U
31-
#define TT_RESP_S_Msk (1UL << TT_RESP_S_Pos)
32-
33-
#define TT_RESP_NSRW_Pos 21U
34-
#define TT_RESP_NSRW_Msk (1UL << TT_RESP_NSRW_Pos)
35-
36-
#define TT_RESP_NSR_Pos 20U
37-
#define TT_RESP_NSR_Msk (1UL << TT_RESP_NSR_Pos)
38-
39-
#define TT_RESP_RW_Pos 19U
40-
#define TT_RESP_RW_Msk (1UL << TT_RESP_RW_Pos)
41-
42-
#define TT_RESP_R_Pos 18U
43-
#define TT_RESP_R_Msk (1UL << TT_RESP_R_Pos)
44-
45-
#define TT_RESP_SRVALID_Pos 17U
46-
#define TT_RESP_SRVALID_Msk (1UL << TT_RESP_SRVALID_Pos)
47-
48-
#define TT_RESP_MRVALID_Pos 16U
49-
#define TT_RESP_MRVALID_Msk (1UL << TT_RESP_MRVALID_Pos)
50-
51-
#define TT_RESP_SREGION_Pos 8U
52-
#define TT_RESP_SREGION_Msk (0xFFUL << TT_RESP_SREGION_Pos)
53-
54-
#define TT_RESP_MREGION_Pos 0U
55-
#define TT_RESP_MREGION_Msk (0xFFUL << TT_RESP_MREGION_Pos)
56-
57-
58-
static uint32_t vmpu_unpriv_test_range(uint32_t addr, uint32_t size)
59-
{
60-
if (!size) size = 1;
61-
uint32_t response_lower, response_upper;
62-
uint32_t test_addr_lower = addr & ~31UL;
63-
uint32_t test_addr_upper = (addr + size - 1) & ~31UL;
64-
65-
/* Test lower address. */
66-
asm volatile (
67-
"tta %[response], %[addr]"
68-
: [response] "=r" (response_lower)
69-
: [addr] "r" (test_addr_lower)
70-
);
71-
if (test_addr_lower != test_addr_upper) {
72-
/* Test upper address. */
73-
asm volatile (
74-
"tta %[response], %[addr]"
75-
: [response] "=r" (response_upper)
76-
: [addr] "r" (test_addr_upper)
77-
);
78-
/* If lower and upper do not have the same S|SRVALID|SREGION, then it's definitely not the same region. */
79-
if (((response_lower ^ response_upper) & (TT_RESP_S_Msk | TT_RESP_SRVALID_Msk | TT_RESP_SREGION_Msk))) {
80-
/* Upper memory region has different SAU region than lower memory region! */
81-
return 0;
82-
}
83-
/* Both memory locations have the same non-secure SAU region and therefore same properties.
84-
* No Secure SAU region can be inbetween due to SAU region overlap rules. */
85-
response_lower &= response_upper;
86-
}
87-
88-
return response_lower & (TT_RESP_NSRW_Msk | TT_RESP_NSR_Msk | TT_RESP_RW_Msk | TT_RESP_R_Msk |
89-
TT_RESP_S_Msk | TT_RESP_SRVALID_Msk | TT_RESP_SREGION_Msk);
90-
}
91-
92-
extern int vmpu_fault_recovery_mpu(uint32_t pc, uint32_t sp, uint32_t fault_addr, uint32_t fault_status);
9323

9424
uint32_t vmpu_unpriv_access(uint32_t addr, uint32_t size, uint32_t data)
9525
{
96-
unsigned int tries = 0;
97-
while(1) {
98-
if ((vmpu_unpriv_test_range(addr, UVISOR_UNPRIV_ACCESS_SIZE(size)) & (TT_RESP_NSRW_Msk | TT_RESP_SRVALID_Msk)) == (TT_RESP_NSRW_Msk | TT_RESP_SRVALID_Msk)) {
99-
switch(size) {
100-
case UVISOR_UNPRIV_ACCESS_READ(1):
101-
return *((uint8_t *) addr);
102-
case UVISOR_UNPRIV_ACCESS_READ(2):
103-
return *((uint16_t *) addr);
104-
case UVISOR_UNPRIV_ACCESS_READ(4):
105-
return *((uint32_t *) addr);
106-
case UVISOR_UNPRIV_ACCESS_WRITE(1):
107-
*((uint8_t *) addr) = (uint8_t) data;
108-
return 0;
109-
case UVISOR_UNPRIV_ACCESS_WRITE(2):
110-
*((uint16_t *) addr) = (uint16_t) data;
111-
return 0;
112-
case UVISOR_UNPRIV_ACCESS_WRITE(4):
113-
*((uint32_t *) addr) = data;
114-
return 0;
115-
default:
116-
break;
117-
}
118-
break;
119-
}
120-
if (++tries > 1 || !vmpu_fault_recovery_mpu(0, 0, addr, 0)) {
121-
break;
26+
// This operation could be slow since we are scanning all the regions defined for the box
27+
// an implementation using the TTA command is faster but causes misses since it works with the MPU
28+
if (vmpu_buffer_access_is_ok(g_active_box, (const void *) addr, UVISOR_UNPRIV_ACCESS_SIZE(size))){
29+
switch(size) {
30+
case UVISOR_UNPRIV_ACCESS_READ(1):
31+
return *((uint8_t *) addr);
32+
case UVISOR_UNPRIV_ACCESS_READ(2):
33+
return *((uint16_t *) addr);
34+
case UVISOR_UNPRIV_ACCESS_READ(4):
35+
return *((uint32_t *) addr);
36+
case UVISOR_UNPRIV_ACCESS_WRITE(1):
37+
*((uint8_t *) addr) = (uint8_t) data;
38+
return 0;
39+
case UVISOR_UNPRIV_ACCESS_WRITE(2):
40+
*((uint16_t *) addr) = (uint16_t) data;
41+
return 0;
42+
case UVISOR_UNPRIV_ACCESS_WRITE(4):
43+
*((uint32_t *) addr) = data;
44+
return 0;
45+
default:
46+
break;
12247
}
12348
}
49+
12450
HALT_ERROR(PERMISSION_DENIED, "Access to restricted resource denied");
12551
return 0;
12652
}

0 commit comments

Comments
 (0)
Please sign in to comment.