Skip to content

Commit 7e006c7

Browse files
committed
Update uVisor page allocator and box initialization
1 parent 2a7f020 commit 7e006c7

File tree

19 files changed

+160
-92
lines changed

19 files changed

+160
-92
lines changed

features/FEATURE_UVISOR/AUTHORS.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
513 Milosch Meriac
2-
424 Alessandro Angelino
3-
18 Jaeden Amero
4-
18 Niklas Hauser
1+
511 Milosch Meriac
2+
433 Alessandro Angelino
3+
28 Niklas Hauser
4+
22 Jaeden Amero
55
3 Hugo Vincent
66
3 JaredCJR
77
3 Jim Huang

features/FEATURE_UVISOR/VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.9.17-alpha
1+
v0.9.20-alpha

features/FEATURE_UVISOR/includes/uvisor/api/inc/box_config.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ UVISOR_EXTERN const uint32_t __uvisor_mode;
4646
0, \
4747
0, \
4848
0, \
49-
0, \
5049
NULL, \
5150
acl_list, \
5251
acl_list_count \
@@ -78,8 +77,7 @@ UVISOR_EXTERN const uint32_t __uvisor_mode;
7877
sizeof(RtxBoxIndex), \
7978
context_size, \
8079
__uvisor_box_heapsize, \
81-
__uvisor_box_main_function, \
82-
__uvisor_box_main_priority, \
80+
__uvisor_box_lib_config, \
8381
__uvisor_box_namespace, \
8482
acl_list, \
8583
acl_list_count \
@@ -123,9 +121,9 @@ UVISOR_EXTERN const uint32_t __uvisor_mode;
123121
/* Use this macro before UVISOR_BOX_CONFIG to define the function the main
124122
* thread of your box will use for its body. If you don't want a main thread,
125123
* too bad: you have to have one. */
126-
#define UVISOR_BOX_MAIN(function, priority) \
127-
static void (*const __uvisor_box_main_function)(void const *) = (function); \
128-
static const int32_t __uvisor_box_main_priority = (priority);
124+
#define UVISOR_BOX_MAIN(function, priority, stack_size) \
125+
static osThreadDef(function, priority, stack_size); \
126+
static const void * const __uvisor_box_lib_config = osThread(function);
129127

130128
#define UVISOR_BOX_HEAPSIZE(heap_size) \
131129
static const uint32_t __uvisor_box_heapsize = heap_size;

features/FEATURE_UVISOR/includes/uvisor/api/inc/svc_exports.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,12 @@
114114
#define UVISOR_SVC_ID_PAGE_FREE UVISOR_SVC_CUSTOM_TABLE(23)
115115

116116
/* SVC immediate values for hardcoded table (call from unprivileged) */
117-
#define UVISOR_SVC_ID_UNVIC_OUT UVISOR_SVC_FIXED_TABLE(0, 0)
118-
#define UVISOR_SVC_ID_REGISTER_GATEWAY UVISOR_SVC_FIXED_TABLE(3, 0)
119-
#define UVISOR_SVC_ID_BOX_MAIN_NEXT UVISOR_SVC_FIXED_TABLE(5, 0)
117+
#define UVISOR_SVC_ID_UNVIC_OUT UVISOR_SVC_FIXED_TABLE(0, 0)
118+
/* Deprecated: UVISOR_SVC_ID_CX_IN(nargs) UVISOR_SVC_FIXED_TABLE(1, nargs) */
119+
/* Deprecated: UVISOR_SVC_ID_CX_OUT UVISOR_SVC_FIXED_TABLE(2, 0) */
120+
#define UVISOR_SVC_ID_REGISTER_GATEWAY UVISOR_SVC_FIXED_TABLE(3, 0)
121+
#define UVISOR_SVC_ID_BOX_INIT_FIRST UVISOR_SVC_FIXED_TABLE(4, 0)
122+
#define UVISOR_SVC_ID_BOX_INIT_NEXT UVISOR_SVC_FIXED_TABLE(5, 0)
120123

121124
/* SVC immediate values for hardcoded table (call from privileged) */
122125
#define UVISOR_SVC_ID_UNVIC_IN UVISOR_SVC_FIXED_TABLE(0, 0)

features/FEATURE_UVISOR/includes/uvisor/api/inc/vmpu_exports.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,24 @@
104104

105105
#if defined(UVISOR_PRESENT) && UVISOR_PRESENT == 1
106106

107+
/** Round an address down to the closest 32-byte boundary.
108+
* @param address[in] The address to round.
109+
*/
110+
#define UVISOR_ROUND32_DOWN(address) ((address) & ~0x1FUL)
111+
112+
/** Round an address up to the closest 32-byte boundary.
113+
* @param address[in] The address to round.
114+
*/
115+
#define UVISOR_ROUND32_UP(address) UVISOR_ROUND32_DOWN((address) + 31UL)
116+
117+
107118
#if defined(ARCH_MPU_ARMv7M)
108119
#define UVISOR_REGION_ROUND_DOWN(x) ((x) & ~((1UL << UVISOR_REGION_BITS(x)) - 1))
109120
#define UVISOR_REGION_ROUND_UP(x) (1UL << UVISOR_REGION_BITS(x))
110121
#define UVISOR_STACK_SIZE_ROUND(x) UVISOR_REGION_ROUND_UP(x)
111122
#elif defined(ARCH_MPU_KINETIS)
112-
#define UVISOR_REGION_ROUND_DOWN(x) ((x) & ~0x1FUL)
113-
#define UVISOR_REGION_ROUND_UP(x) UVISOR_REGION_ROUND_DOWN((x) + 31UL)
123+
#define UVISOR_REGION_ROUND_DOWN(x) UVISOR_ROUND32_DOWN(x)
124+
#define UVISOR_REGION_ROUND_UP(x) UVISOR_ROUND32_UP(x)
114125
#define UVISOR_STACK_SIZE_ROUND(x) UVISOR_REGION_ROUND_UP((x) + (UVISOR_STACK_BAND_SIZE * 2))
115126
#else
116127
#error "Unknown MPU architecture. uvisor: Check your Makefile. uvisor-lib: Check if uVisor is supported"
@@ -158,8 +169,9 @@ typedef struct {
158169
/* Contains user provided size of box heap without guards of buffers. */
159170
uint32_t heap_size;
160171

161-
void (*main_function)(void const *argument);
162-
int32_t main_priority;
172+
/* Opaque-to-uVisor data that potentially contains uvisor-lib-specific or
173+
* OS-specific per-box configuration */
174+
const void * const lib_config;
163175

164176
const char * box_namespace;
165177
const UvisorBoxAclItem * const acl_list;

features/FEATURE_UVISOR/source/page_allocator.c_inc

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <uvisor.h>
2424
#include "page_allocator.h"
25+
#include "page_allocator_faults.h"
2526
#include "mpu/vmpu_unpriv_access.h"
2627
#include "mpu/vmpu.h"
2728
#include "halt.h"
@@ -38,40 +39,31 @@
3839

3940
#endif /* defined(UVISOR_PRESENT) && (UVISOR_PRESENT == 1) */
4041

41-
/* We can only protect a small number of pages efficiently, so there should be
42-
* a relatively low limit to the number of pages.
43-
* By default a maximum of 16 pages are allowed. This can only be overridden
44-
* by the porting engineer for the current platform. */
45-
#ifndef UVISOR_PAGE_TABLE_MAX_COUNT
46-
#define UVISOR_PAGE_TABLE_MAX_COUNT ((uint32_t) 16)
47-
#endif
48-
/* The number of pages is decided by the page size. A small page size leads to
49-
* a lot of pages, however, number of pages is capped for efficiency.
50-
* Furthermore, when allocating large continous memory, a too small page size
51-
* will lead to allocation failures. This can only be overridden
52-
* by the porting engineer for the current platform. */
53-
#ifndef UVISOR_PAGE_SIZE_MINIMUM
54-
#define UVISOR_PAGE_SIZE_MINIMUM ((uint32_t) 1024)
55-
#endif
42+
#include "page_allocator_config.h"
5643

57-
/* The page box_id is the box id which is 8-bit large. */
58-
typedef uint8_t page_owner_t;
5944
/* Maps the page to the owning box handle. */
60-
static page_owner_t g_page_owner_table[UVISOR_PAGE_TABLE_MAX_COUNT];
61-
/* Define a unused value for the page table. */
62-
#define UVISOR_PAGE_UNUSED ((page_owner_t) (-1))
63-
45+
page_owner_t g_page_owner_table[UVISOR_PAGE_TABLE_MAX_COUNT];
6446
/* Contains the configured page size. */
65-
static uint32_t g_page_size;
47+
uint32_t g_page_size;
6648
/* Points to the beginning of the page heap. */
67-
static const void * g_page_heap_start;
49+
const void * g_page_heap_start;
6850
/* Points to the end of the page heap. */
69-
static const void * g_page_heap_end;
51+
const void * g_page_heap_end;
7052
/* Contains the number of free pages. */
71-
static uint8_t g_page_count_free;
53+
uint8_t g_page_count_free;
7254
/* Contains the total number of available pages. */
73-
static uint8_t g_page_count_total;
55+
uint8_t g_page_count_total;
7456

57+
/* Helper function maps pointer to page id, or UVISOR_PAGE_UNUSED. */
58+
uint8_t page_allocator_get_page_from_address(uint32_t address)
59+
{
60+
/* Range check the returned pointer. */
61+
if (address < (uint32_t) g_page_heap_start || address >= (uint32_t) g_page_heap_end) {
62+
return UVISOR_PAGE_UNUSED;
63+
}
64+
/* Compute the index for the pointer. */
65+
return (address - (uint32_t) g_page_heap_start) / g_page_size;
66+
}
7567

7668
void page_allocator_init(void * const heap_start, void * const heap_end, const uint32_t * const page_size)
7769
{
@@ -142,8 +134,9 @@ void page_allocator_init(void * const heap_start, void * const heap_end, const u
142134
(unsigned int) (g_page_size / 1024));
143135

144136
uint32_t page = 0;
145-
for (; page < g_page_count_total; page++) {
137+
for (; page < UVISOR_PAGE_TABLE_MAX_COUNT; page++) {
146138
g_page_owner_table[page] = UVISOR_PAGE_UNUSED;
139+
page_allocator_reset_faults(page);
147140
}
148141
}
149142

@@ -187,6 +180,8 @@ int page_allocator_malloc(UvisorPageTable * const table)
187180
if (g_page_owner_table[page] == UVISOR_PAGE_UNUSED) {
188181
/* Marry this page to the box id. */
189182
g_page_owner_table[page] = box_id;
183+
/* Reset the fault count for this page. */
184+
page_allocator_reset_faults(page);
190185
/* Get the pointer to the page. */
191186
void * ptr = (void *) g_page_heap_start + page * g_page_size;
192187
/* Zero the entire page before handing it out. */
@@ -239,14 +234,14 @@ int page_allocator_free(const UvisorPageTable * const table)
239234
int table_size = page_count;
240235
for (; table_size > 0; page_table++, table_size--) {
241236
void * page = (void *) page_table_read((uint32_t) page_table);
237+
/* Compute the index for the pointer. */
238+
uint8_t page_index = page_allocator_get_page_from_address((uint32_t) page);
242239
/* Range check the returned pointer. */
243-
if (page < g_page_heap_start || page >= g_page_heap_end) {
240+
if (page_index == UVISOR_PAGE_UNUSED) {
244241
DPRINTF("uvisor_page_free: FAIL: Pointer 0x%08x does not belong to any page!\n\n", (unsigned int) page);
245242
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
246243
return UVISOR_ERROR_PAGE_INVALID_PAGE_ORIGIN;
247244
}
248-
/* Compute the index for the pointer. */
249-
uint32_t page_index = (page - g_page_heap_start) / g_page_size;
250245
/* Check if the page belongs to the caller. */
251246
if (g_page_owner_table[page_index] == box_id) {
252247
g_page_owner_table[page_index] = UVISOR_PAGE_UNUSED;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2016, ARM Limited, All Rights Reserved
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
* not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef __PAGE_ALLOCATOR_CONFIG_H__
19+
#define __PAGE_ALLOCATOR_CONFIG_H__
20+
/* This file can be compiled externally to provide the page allocator algorithm
21+
* for devices NOT supported by uVisor. For this purpose this file is copied as
22+
* is into the target build folder and compiled by the target build system. */
23+
24+
/* We can only protect a small number of pages efficiently, so there should be
25+
* a relatively low limit to the number of pages.
26+
* By default a maximum of 16 pages are allowed. This can only be overwritten
27+
* by the porting engineer for the current platform. */
28+
#ifndef UVISOR_PAGE_TABLE_MAX_COUNT
29+
#define UVISOR_PAGE_TABLE_MAX_COUNT ((uint32_t) 16)
30+
#endif
31+
/* The number of pages is decided by the page size. A small page size leads to
32+
* a lot of pages, however, number of pages is capped for efficiency.
33+
* Furthermore, when allocating large continous memory, a too small page size
34+
* will lead to allocation failures. This can only be overwritten
35+
* by the porting engineer for the current platform. */
36+
#ifndef UVISOR_PAGE_SIZE_MINIMUM
37+
#define UVISOR_PAGE_SIZE_MINIMUM ((uint32_t) 1024)
38+
#endif
39+
40+
/* The page box_id is the box id which is 8-bit large. */
41+
typedef uint8_t page_owner_t;
42+
/* Define a unused value for the page table. */
43+
#define UVISOR_PAGE_UNUSED ((page_owner_t) (-1))
44+
45+
#endif /* __PAGE_ALLOCATOR_CONFIG_H__ */
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (c) 2016, ARM Limited, All Rights Reserved
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
* not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
#include "uvisor-lib/uvisor-lib.h"
18+
#include "mbed_interface.h"
19+
#include "cmsis_os.h"
20+
#include <stdint.h>
21+
#include <string.h>
22+
23+
/* This function is called by uVisor in unprivileged mode. On this OS, we
24+
* create box main threads for the box. */
25+
void __uvisor_lib_box_init(void * lib_config)
26+
{
27+
osThreadId thread_id;
28+
osThreadDef_t * flash_thread_def = lib_config;
29+
osThreadDef_t thread_def;
30+
31+
/* Copy thread definition from flash to RAM. The thread definition is most
32+
* likely in flash, so we need to copy it to box-local RAM before we can
33+
* modify it. */
34+
memcpy(&thread_def, flash_thread_def, sizeof(thread_def));
35+
36+
/* Note that the box main thread stack is separate from the box stack. This
37+
* is because the thread must be created to use a different stack than the
38+
* stack osCreateThread() is called from, as context information is saved
39+
* to the thread stack by the call to osCreateThread(). */
40+
/* Allocate memory for the main thread from the process heap (which is
41+
* private to the process). This memory is never freed, even if the box's
42+
* main thread exits. */
43+
thread_def.stack_pointer = malloc_p(thread_def.stacksize);
44+
45+
if (thread_def.stack_pointer == NULL) {
46+
/* No process heap memory available */
47+
mbed_die();
48+
}
49+
50+
thread_id = osThreadCreate(&thread_def, NULL);
51+
52+
if (thread_id == NULL) {
53+
/* Failed to create thread */
54+
mbed_die();
55+
}
56+
}

features/FEATURE_UVISOR/source/rtx/box_main.c

Lines changed: 0 additions & 43 deletions
This file was deleted.

features/FEATURE_UVISOR/source/rtx/rtx_malloc_wrapper.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ static void * memory(void * ptr, size_t size, int heap, int operation)
111111
return NULL;
112112
}
113113
/* Check if we need to aquire the mutex. */
114-
int mutexed = (is_kernel_initialized() && (heap == HEAP_PROCESS));
114+
int mutexed = is_kernel_initialized() &&
115+
((heap == HEAP_PROCESS) || __uvisor_ps->index.box_heap == __uvisor_ps->index.active_heap);
115116
void * allocator = (heap == HEAP_PROCESS) ?
116117
(__uvisor_ps->index.box_heap) :
117118
(__uvisor_ps->index.active_heap);

features/FEATURE_UVISOR/source/rtx/unsupported_page_allocator.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#define HALT_ERROR(id, ...) {}
3434
#define UVISOR_PAGE_ALLOCATOR_MUTEX_AQUIRE page_allocator_mutex_aquire()
3535
#define UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE osMutexRelease(g_page_allocator_mutex_id)
36+
#define page_allocator_reset_faults(...) {}
3637

3738
/* Forward declaration of the page allocator API. */
3839
int page_allocator_malloc(UvisorPageTable * const table);

0 commit comments

Comments
 (0)