Skip to content

Commit f5bd85c

Browse files
committed
vm: Refactor vm_map_prot2perms.
Remove the definition indirection via CHERI_PERMS_PROT2PERM_*; instead, make vm_map_prot2perms fully machine-dependent. Add a base_perms argument to vm_map_prot2perms. This removes the use of CHERI_PROT2PERM_MASK and make it clearer that the permission mask is inherited from a base permission bitmask that is altered according to VM_PROT_*.
1 parent 0cd5a4b commit f5bd85c

File tree

16 files changed

+94
-94
lines changed

16 files changed

+94
-94
lines changed

sys/arm64/arm64/pmap.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2541,12 +2541,15 @@ pmap_kremove_device(vm_offset_t sva, vm_size_t size)
25412541
vm_pointer_t
25422542
pmap_map(vm_pointer_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
25432543
{
2544+
vm_pointer_t p;
2545+
2546+
p = PHYS_TO_DMAP(start);
25442547
#ifdef __CHERI_PURE_CAPABILITY__
2545-
return cheri_perms_and(cheri_bounds_set(PHYS_TO_DMAP(start), end - start),
2546-
vm_map_prot2perms(prot));
2547-
#else
2548-
return PHYS_TO_DMAP(start);
2548+
p = cheri_bounds_set(p, end - start);
2549+
p = cheri_perms_and(p, vm_map_prot2perms(cheri_perms_get(p), prot));
25492550
#endif
2551+
2552+
return (p);
25502553
}
25512554

25522555
/*

sys/arm64/cheri/cheri_machdep.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <sys/kernel.h>
3535
#include <sys/devmap.h>
3636
#include <sys/proc.h>
37+
#include <vm/vm.h>
3738

3839
#include <cheri/cheri.h>
3940
#include <cheri/cheric.h>
@@ -127,3 +128,37 @@ hybridabi_thread_setregs(struct thread *td, unsigned long entry_addr)
127128
td, CHERI_CAP_USER_CODE_PERMS, CHERI_CAP_USER_CODE_BASE,
128129
CHERI_CAP_USER_CODE_LENGTH, entry_addr));
129130
}
131+
132+
int
133+
vm_map_prot2perms(int base, vm_prot_t prot)
134+
{
135+
int perms = 0;
136+
137+
if (prot & (VM_PROT_CAP | VM_PROT_NO_IMPLY_CAP)) {
138+
if (prot & (VM_PROT_READ | VM_PROT_COPY))
139+
perms |= CHERI_PERM_LOAD;
140+
if (VM_PROT_HAS_READ_CAP(prot))
141+
perms |= CHERI_PERM_LOAD_CAP | CHERI_PERM_MUTABLE_LOAD;
142+
if (prot & VM_PROT_WRITE)
143+
perms |= CHERI_PERM_STORE;
144+
if (VM_PROT_HAS_WRITE_CAP(prot))
145+
perms |= CHERI_PERM_STORE_CAP |
146+
CHERI_PERM_STORE_LOCAL_CAP;
147+
} else {
148+
if (prot & (VM_PROT_READ | VM_PROT_COPY))
149+
perms |= CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP |
150+
CHERI_PERM_MUTABLE_LOAD;
151+
if (prot & VM_PROT_WRITE)
152+
perms |= CHERI_PERM_STORE | CHERI_PERM_STORE_CAP |
153+
CHERI_PERM_STORE_LOCAL_CAP;
154+
}
155+
if (prot & VM_PROT_EXECUTE)
156+
perms |= CHERI_PERM_EXECUTE | CHERI_PERM_EXECUTIVE |
157+
CHERI_PERM_LOAD;
158+
159+
base &= ~(CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP | CHERI_PERM_MUTABLE_LOAD |
160+
CHERI_PERM_STORE | CHERI_PERM_STORE_CAP | CHERI_PERM_STORE_LOCAL_CAP |
161+
CHERI_PERM_EXECUTE | CHERI_PERM_EXECUTIVE);
162+
163+
return (base | perms);
164+
}

sys/arm64/include/cherireg.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -112,21 +112,6 @@
112112

113113
/* TODO #define CHERI_PERMS_HWALL_CID (CHERI_PERM_SETCID) */
114114

115-
/*
116-
* vm_prot_t to capability permission bits
117-
*/
118-
#define CHERI_PERMS_PROT2PERM_READ \
119-
CHERI_PERM_LOAD
120-
#define CHERI_PERMS_PROT2PERM_READ_CAP \
121-
(CHERI_PERM_LOAD_CAP | CHERI_PERM_MUTABLE_LOAD)
122-
#define CHERI_PERMS_PROT2PERM_WRITE \
123-
CHERI_PERM_STORE
124-
#define CHERI_PERMS_PROT2PERM_WRITE_CAP \
125-
(CHERI_PERM_STORE_CAP | CHERI_PERM_STORE_LOCAL_CAP)
126-
#define CHERI_PERMS_PROT2PERM_EXEC \
127-
(CHERI_PERM_EXECUTE | CHERI_PERM_EXECUTIVE | \
128-
CHERI_PERMS_PROT2PERM_READ)
129-
130115
/*
131116
* Basic userspace permission mask; CHERI_PERM_EXECUTE will be added for
132117
* executable capabilities (pcc); CHERI_PERM_STORE, CHERI_PERM_STORE_CAP,

sys/cheri/cherireg.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -104,19 +104,6 @@
104104
(CHERI_OTYPE_USER_MAX - CHERI_OTYPE_USER_MIN + 1)
105105
#define CHERI_SEALCAP_USERSPACE_OFFSET 0x0
106106

107-
/*
108-
* Definition for mapping vm_prot_t to capability permission
109-
*/
110-
#define CHERI_PROT2PERM_READ_PERMS CHERI_PERMS_PROT2PERM_READ
111-
#define CHERI_PROT2PERM_READ_CAP_PERMS CHERI_PERMS_PROT2PERM_READ_CAP
112-
#define CHERI_PROT2PERM_WRITE_PERMS CHERI_PERMS_PROT2PERM_WRITE
113-
#define CHERI_PROT2PERM_WRITE_CAP_PERMS CHERI_PERMS_PROT2PERM_WRITE_CAP
114-
#define CHERI_PROT2PERM_EXEC_PERMS CHERI_PERMS_PROT2PERM_EXEC
115-
#define CHERI_PROT2PERM_MASK \
116-
(CHERI_PROT2PERM_READ_PERMS | CHERI_PROT2PERM_WRITE_PERMS | \
117-
CHERI_PROT2PERM_READ_CAP_PERMS | CHERI_PROT2PERM_WRITE_CAP_PERMS | \
118-
CHERI_PROT2PERM_EXEC_PERMS)
119-
120107
/*
121108
* Root sealing capability for kernel managed objects.
122109
*/

sys/compat/linuxkpi/common/src/linux_page.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ __get_user_pages_fast(void * __capability addr, int nr_pages, int write,
240240
prot = write ? (VM_PROT_READ | VM_PROT_WRITE) : VM_PROT_READ;
241241
len = ptoa((vm_offset_t)nr_pages);
242242
#if __has_feature(capabilities)
243-
if (!cheri_can_access(addr, vm_map_prot2perms(prot), len))
243+
if (!cheri_can_access(addr, vm_map_prot2perms(0, prot), len))
244244
return (-1);
245245
#endif
246246
MPASS(pages != NULL);

sys/dev/pci/pci_user.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ pci_bar_mmap(device_t pcidev, struct pci_bar_mmap *pbm)
10221022
}
10231023
#if __has_feature(capabilities) && !defined(__CHERI_PURE_CAPABILITY__)
10241024
pbm->pbm_map_base = cheri_capability_build_user_data(
1025-
vm_map_prot2perms(prot), addr, plen, 0);
1025+
vm_map_prot2perms(0, prot), addr, plen, 0);
10261026
#else
10271027
pbm->pbm_map_base = (void *)addr;
10281028
#endif

sys/kern/kern_exec.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,8 +1311,7 @@ exec_map_stack(struct image_params *imgp)
13111311
}
13121312

13131313
#if __has_feature(capabilities)
1314-
perms = (~CHERI_PROT2PERM_MASK | vm_map_prot2perms(stack_prot)) &
1315-
CHERI_CAP_USER_DATA_PERMS;
1314+
perms = vm_map_prot2perms(CHERI_CAP_USER_DATA_PERMS, stack_prot);
13161315
#ifdef __CHERI_PURE_CAPABILITY__
13171316
imgp->stack = (void *)cheri_perms_and(stack_top, perms);
13181317
#else

sys/riscv/cheri/cheri_machdep.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <sys/kernel.h>
3535
#include <sys/devmap.h>
3636
#include <sys/proc.h>
37+
#include <vm/vm.h>
3738

3839
#include <cheri/cheri.h>
3940
#include <cheri/cheric.h>
@@ -100,6 +101,38 @@ hybridabi_thread_setregs(struct thread *td, unsigned long entry_addr)
100101
td, CHERI_CAP_USER_CODE_PERMS, CHERI_CAP_USER_CODE_BASE,
101102
CHERI_CAP_USER_CODE_LENGTH, entry_addr);
102103
}
104+
105+
int
106+
vm_map_prot2perms(int base, vm_prot_t prot)
107+
{
108+
int perms = 0;
109+
110+
if (prot & (VM_PROT_CAP | VM_PROT_NO_IMPLY_CAP)) {
111+
if (prot & (VM_PROT_READ | VM_PROT_COPY))
112+
perms |= CHERI_PERM_LOAD;
113+
if (VM_PROT_HAS_READ_CAP(prot))
114+
perms |= CHERI_PERM_LOAD_CAP;
115+
if (prot & VM_PROT_WRITE)
116+
perms |= CHERI_PERM_STORE;
117+
if (VM_PROT_HAS_WRITE_CAP(prot))
118+
perms |= CHERI_PERM_STORE_CAP |
119+
CHERI_PERM_STORE_LOCAL_CAP;
120+
} else {
121+
if (prot & (VM_PROT_READ | VM_PROT_COPY))
122+
perms |= CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP;
123+
if (prot & VM_PROT_WRITE)
124+
perms |= CHERI_PERM_STORE | CHERI_PERM_STORE_CAP |
125+
CHERI_PERM_STORE_LOCAL_CAP;
126+
}
127+
if (prot & VM_PROT_EXECUTE)
128+
perms |= CHERI_PERM_EXECUTE | CHERI_PERM_LOAD;
129+
130+
base &= ~(CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP | CHERI_PERM_STORE |
131+
CHERI_PERM_STORE_CAP | CHERI_PERM_STORE_LOCAL_CAP |
132+
CHERI_PERM_EXECUTE);
133+
134+
return (base | perms);
135+
}
103136
// CHERI CHANGES START
104137
// {
105138
// "updated": 20230509,

sys/riscv/include/cherireg.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,20 +96,6 @@
9696
CHERI_PERM_SEAL | CHERI_PERM_INVOKE | CHERI_PERM_UNSEAL | \
9797
CHERI_PERM_SYSTEM_REGS | CHERI_PERM_SET_CID)
9898

99-
/*
100-
* vm_prot_t to capability permission bits
101-
*/
102-
#define CHERI_PERMS_PROT2PERM_READ \
103-
CHERI_PERM_LOAD
104-
#define CHERI_PERMS_PROT2PERM_READ_CAP \
105-
CHERI_PERM_LOAD_CAP
106-
#define CHERI_PERMS_PROT2PERM_WRITE \
107-
CHERI_PERM_STORE
108-
#define CHERI_PERMS_PROT2PERM_WRITE_CAP \
109-
(CHERI_PERM_STORE_CAP | CHERI_PERM_STORE_LOCAL_CAP)
110-
#define CHERI_PERMS_PROT2PERM_EXEC \
111-
(CHERI_PERM_EXECUTE | CHERI_PERMS_PROT2PERM_READ)
112-
11399
/*
114100
* Hardware defines a kind of tripartite taxonomy: memory, type, and CID.
115101
* They're all squished together in the permission bits, so define masks

sys/riscv/riscv/pmap.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,9 +1375,10 @@ pmap_map(vm_pointer_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
13751375
vm_pointer_t p;
13761376

13771377
p = PHYS_TO_DMAP(start);
1378-
p = cheri_kern_bounds_set(p, end - start);
1379-
p = cheri_kern_perms_and(p, vm_map_prot2perms(prot) |
1380-
~CHERI_PROT2PERM_MASK);
1378+
#ifdef __CHERI_PURE_CAPABILITY__
1379+
p = cheri_bounds_set(p, end - start);
1380+
p = cheri_perms_and(p, vm_map_prot2perms(cheri_perms_get(p), prot));
1381+
#endif
13811382

13821383
return (p);
13831384
}

0 commit comments

Comments
 (0)