1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2022 Oxide Computer Company
14 */
15
16
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <stropts.h>
20 #include <strings.h>
21 #include <signal.h>
22 #include <setjmp.h>
23 #include <libgen.h>
24
25 #include <sys/vmm.h>
26 #include <sys/vmm_dev.h>
27 #include <sys/mman.h>
28 #include <vmmapi.h>
29
30 #include "common.h"
31
32 enum test_segs {
33 SEG_LOWMEM = 0,
34 SEG_BOOTROM = 1,
35 };
36 #define PAGE_CNT 2
37 #define PAGE_SZ 4096
38 #define SEG_SZ (PAGE_CNT * PAGE_SZ)
39 #define WHOLE_SZ (SEG_SZ * 2)
40
41 #define TESTVAL_LOWMEM 0x1000ffff
42 #define TESTVAL_BOOTROM 0x2000eeee
43
44 int
main(int argc,char * argv[])45 main(int argc, char *argv[])
46 {
47 struct vmctx *ctx;
48 int res, fd;
49 const char *suite_name = basename(argv[0]);
50
51 ctx = create_test_vm(suite_name);
52 if (ctx == NULL) {
53 perror("could open test VM");
54 return (1);
55 }
56 fd = vm_get_device_fd(ctx);
57
58 res = alloc_memseg(ctx, SEG_LOWMEM, SEG_SZ, "");
59 if (res != 0) {
60 perror("could not alloc lowmem seg");
61 goto bail;
62 }
63 res = alloc_memseg(ctx, SEG_BOOTROM, SEG_SZ, "bootrom");
64 if (res != 0) {
65 perror("could not alloc bootrom seg");
66 goto bail;
67 }
68
69 res = vm_mmap_memseg(ctx, 0, SEG_LOWMEM, 0, SEG_SZ, PROT_ALL);
70 if (res != 0) {
71 perror("could not map lowmem into vmspace");
72 goto bail;
73 }
74 res = vm_mmap_memseg(ctx, SEG_SZ, SEG_BOOTROM, 0, SEG_SZ, PROT_READ);
75 if (res != 0) {
76 perror("could not map bootrom into vmspace");
77 goto bail;
78 }
79
80 void *guest_mem;
81 guest_mem = mmap(NULL, WHOLE_SZ, PROT_READ, MAP_SHARED, fd, 0);
82 if (guest_mem == MAP_FAILED) {
83 perror("could not mmap guest-physical memory");
84 goto bail;
85 }
86
87 void *direct_lowmem, *direct_bootrom;
88 off_t seg_obj_off;
89
90 res = vm_get_devmem_offset(ctx, SEG_LOWMEM, &seg_obj_off);
91 if (res != 0) {
92 perror("could not find mapping offset for lowmem seg");
93 goto bail;
94 }
95 direct_lowmem = mmap(NULL, SEG_SZ, PROT_READ | PROT_WRITE, MAP_SHARED,
96 fd, seg_obj_off);
97 if (direct_lowmem == MAP_FAILED) {
98 perror("could not mmap lowmem directly");
99 goto bail;
100 }
101
102 res = vm_get_devmem_offset(ctx, SEG_BOOTROM, &seg_obj_off);
103 if (res != 0) {
104 perror("could not find mapping offset for lowmem seg");
105 goto bail;
106 }
107 direct_bootrom = mmap(NULL, SEG_SZ, PROT_READ | PROT_WRITE, MAP_SHARED,
108 fd, seg_obj_off);
109 if (direct_bootrom == MAP_FAILED) {
110 perror("could not mmap bootrom directly");
111 goto bail;
112 }
113
114 uint32_t *datap;
115
116 datap = direct_lowmem;
117 *datap = TESTVAL_LOWMEM;
118 datap = direct_bootrom;
119 *datap = TESTVAL_BOOTROM;
120
121 /* check that data written though direct access is as expected */
122 datap = guest_mem;
123 if (*datap != TESTVAL_LOWMEM) {
124 (void) fprintf(stderr, "unexpected data in lowmem %x != %x\n",
125 *datap, TESTVAL_LOWMEM);
126 goto bail;
127 }
128 datap = (guest_mem + SEG_SZ);
129 if (*datap != TESTVAL_BOOTROM) {
130 (void) fprintf(stderr, "unexpected data in bootrom %x != %x\n",
131 *datap, TESTVAL_BOOTROM);
132 goto bail;
133 }
134
135 /* unmap access mappings */
136 res = munmap(guest_mem, WHOLE_SZ);
137 if (res != 0) {
138 perror("could not munmap vmspace");
139 goto bail;
140 }
141 res = munmap(direct_lowmem, SEG_SZ);
142 if (res != 0) {
143 perror("could not munmap lowmem object");
144 goto bail;
145 }
146 res = munmap(direct_bootrom, SEG_SZ);
147 if (res != 0) {
148 perror("could not munmap bootrom object");
149 goto bail;
150 }
151
152 /* mission accomplished */
153 vm_destroy(ctx);
154 (void) printf("%s\tPASS\n", suite_name);
155 return (0);
156
157 bail:
158 vm_destroy(ctx);
159 return (1);
160 }
161