Skip to content

Commit 917466c

Browse files
committed
Expose KVM's memory slot interface on Linux
1 parent 437ae00 commit 917466c

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

include/vmm.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,29 @@ int vmm_cpu_set_state(vmm_vm_t vm, vmm_cpu_t cpu, int id, uint64_t value);
119119
typedef const void *vmm_uvaddr_t;
120120
typedef uint64_t vmm_gpaddr_t;
121121

122+
123+
/* TODO: Abstract memory map management in Linux KVM */
124+
#ifdef __APPLE__
125+
122126
int vmm_memory_map(vmm_vm_t vm, vmm_uvaddr_t uva, vmm_gpaddr_t gpa, size_t size, int prot);
123127
int vmm_memory_unmap(vmm_vm_t vm, vmm_gpaddr_t gpa, size_t size);
124128
int vmm_memory_protect(vmm_vm_t vm, vmm_gpaddr_t gpa, size_t size, int prot);
125129

130+
#elif __linux__
131+
132+
#include <linux/kvm.h>
133+
typedef struct kvm_userspace_memory_region *vmm_memregion_t;
134+
135+
int vmm_memregion_set(vmm_vm_t vm, uint32_t reg_slot, vmm_uvaddr_t uva, vmm_gpaddr_t gpa, size_t size, int prot);
136+
int vmm_memregion_unset(vmm_vm_t vm, uint32_t reg_slot);
137+
138+
int vmm_memory_map(vmm_vm_t vm, vmm_uvaddr_t uva, vmm_gpaddr_t gpa, size_t size, int prot) __attribute__ ((warning ("vmm_memory_map is not fully supported for KVM")));
139+
int vmm_memory_unmap(vmm_vm_t vm, vmm_gpaddr_t gpa, size_t size) __attribute__ ((error ("vmm_memory_unmap is not supported for KVM")));
140+
int vmm_memory_protect(vmm_vm_t vm, vmm_gpaddr_t gpa, size_t size, int prot) __attribute__ ((error ("vmm_memory_protect is not supported for KVM")));
141+
142+
#endif
143+
144+
126145
#ifdef __cplusplus
127146
}
128147
#endif

src/vmm_kvm.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,24 +83,42 @@ vmm_destroy(vmm_vm_t vm)
8383

8484
int
8585
vmm_memory_map(vmm_vm_t vm, vmm_uvaddr_t uva, vmm_gpaddr_t gpa, size_t size, int prot)
86+
{
87+
static uint32_t slot = 0;
88+
return vmm_memregion_set(vm, slot++, uva, gpa, size, prot);
89+
}
90+
91+
int
92+
vmm_memregion_set(vmm_vm_t vm, uint32_t reg_slot, vmm_uvaddr_t uva, vmm_gpaddr_t gpa, size_t size, int prot)
8693
{
8794
int valid_prots = PROT_READ | PROT_WRITE | PROT_EXEC;
8895

8996
if (prot & ~valid_prots)
9097
return VMM_EINVAL;
91-
if ((prot & PROT_EXEC) == 0)
98+
if ((prot & PROT_EXEC) == 0) // Non-executable cannot be supported directly on KVM
9299
return VMM_EINVAL;
93100

94101
struct kvm_userspace_memory_region region = {
95-
.slot = 0, // FIXME
102+
.slot = reg_slot,
96103
.flags = (prot & PROT_WRITE) == 0 ? KVM_MEM_READONLY : 0,
97104
.guest_phys_addr = gpa,
98105
.memory_size = size,
99106
.userspace_addr = (uint64_t)uva,
100107
};
101-
int ret;
108+
if (ioctl(vm->vmfd, KVM_SET_USER_MEMORY_REGION, &region) < 0)
109+
return -errno;
102110

103-
if ((ret = ioctl(vm->vmfd, KVM_SET_USER_MEMORY_REGION, &region)) < 0)
111+
return 0;
112+
}
113+
114+
int
115+
vmm_memregion_unset(vmm_vm_t vm, uint32_t reg_slot)
116+
{
117+
struct kvm_userspace_memory_region zero_region = {
118+
.slot = reg_slot,
119+
.memory_size = 0,
120+
};
121+
if (ioctl(vm->vmfd, KVM_SET_USER_MEMORY_REGION, &zero_region) < 0)
104122
return -errno;
105123

106124
return 0;

0 commit comments

Comments
 (0)