lcd-domains-arch-tests.c 5.21 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
/**
 * Regression tests for lcd arch code.
 *
 * Included in lcd-domains-arch.c and
 * ran last in lcd_arch_init.
 */

static int test01(void)
{
	struct lcd_arch_vmcs *vmcs;
	vmcs = vmx_alloc_vmcs(raw_smp_processor_id());
	if (!vmcs) {
13
		LCD_ARCH_ERR("failed");
14 15 16 17 18 19 20 21 22 23 24
		return -1;
	}
	vmx_free_vmcs(vmcs);
	return 0;
}

static int test02(void)
{
	struct lcd_arch *lcd;
	int i;
	char *buf;
25 26 27
	int ret = -1;

	lcd = lcd_arch_create();
28
	if (!lcd) {
29
		LCD_ARCH_ERR("failed to alloc lcd");
30 31 32
		goto fail_alloc;
	}

Charles Jacobsen's avatar
Charles Jacobsen committed
33
	buf = (char *)lcd->ept.root;
34 35
	for (i = 0; i < PAGE_SIZE; i++) {
		if (buf[i]) {
36 37
			LCD_ARCH_ERR("nonzero in ept");
			goto out;
38 39 40
		}
	}		

41
	ret = 0;
42

43 44
out:
	lcd_arch_destroy(lcd);
45
fail_alloc:
46
	return ret;
47 48
}

49
static int test03_help(struct lcd_arch *lcd, gpa_t base)
50 51 52 53 54 55
{
	hpa_t actual;
	unsigned long off;

	for (off = 0; off < 0x40000; off += PAGE_SIZE) {
		if (lcd_arch_ept_gpa_to_hpa(lcd, gpa_add(base, off), &actual)) {
56
			LCD_ARCH_ERR("failed lookup at %lx",
57 58 59 60
				gpa_val(gpa_add(base, off)));
			return -1;
		}
		if (hpa_val(actual) != gpa_val(gpa_add(base, off))) {
61
			LCD_ARCH_ERR("expected hpa %lx got %lx\n",
62 63 64 65 66
				gpa_val(gpa_add(base, off)),
				hpa_val(actual));
			return -1;
		}
	}
Charles Jacobsen's avatar
Charles Jacobsen committed
67
	return 0;
68 69
}

70
static int test03(void)
Charlie Jacobsen's avatar
Charlie Jacobsen committed
71 72
{
	struct lcd_arch *lcd;
73
	gpa_t base;
74
	int ret = -1;
Charlie Jacobsen's avatar
Charlie Jacobsen committed
75

76
	lcd = lcd_arch_create();
Charlie Jacobsen's avatar
Charlie Jacobsen committed
77
	if (!lcd) {
78
		LCD_ARCH_ERR("failed to alloc lcd");
79
		goto fail1;
Charlie Jacobsen's avatar
Charlie Jacobsen committed
80 81 82
	}

	/*
83
	 * Map 0x0 - 0x400000 (first 4 MBs, takes two page tables)
Charlie Jacobsen's avatar
Charlie Jacobsen committed
84
	 */
85
	if (lcd_arch_ept_map_range(lcd, __gpa(0), __hpa(0), 1024)) {
86
		LCD_ARCH_ERR("failed to map first 4 MBs");
87
		goto fail3;
Charlie Jacobsen's avatar
Charlie Jacobsen committed
88 89 90
	}

	/*
91
	 * Map 0x40000000 - 0x40400000 (1GB -- 1GB + 4MBs)
Charlie Jacobsen's avatar
Charlie Jacobsen committed
92
	 */
93
	if (lcd_arch_ept_map_range(lcd, __gpa(1 << 30), __hpa(1 << 30), 1024)) {
94
		LCD_ARCH_ERR("failed to map 2nd 4 MBs");
95
		goto fail4;
Charlie Jacobsen's avatar
Charlie Jacobsen committed
96 97 98
	}

	/*
99
	 * Map 0x8000000000 - 0x8000400000 (512GB -- 512GB + 4MBs)
Charlie Jacobsen's avatar
Charlie Jacobsen committed
100
	 */
101 102
	if (lcd_arch_ept_map_range(lcd, __gpa(1UL << 39), 
					__hpa(1UL << 39), 1024)) {
103
		LCD_ARCH_ERR("failed to map 3rd 4 MBs");
104
		goto fail5;
Charlie Jacobsen's avatar
Charlie Jacobsen committed
105 106 107 108 109 110
	}

	/*
	 * CHECK
	 */

111
	base = __gpa(0);
112
	if (test03_help(lcd, base))
113 114
		goto fail6;
	base = __gpa(1 << 30);
115
	if (test03_help(lcd, base))
116
		goto fail6;
Charles Jacobsen's avatar
Charles Jacobsen committed
117
	base = __gpa(1UL << 39);
118
	if (test03_help(lcd, base))
119 120
		goto fail6;

121 122
	ret = 0;
	goto done;
Charlie Jacobsen's avatar
Charlie Jacobsen committed
123

124
done:
125
fail6:
126
	lcd_arch_ept_unmap_range(lcd, __gpa(1UL << 39), 1024);
127
fail5:
128
	lcd_arch_ept_unmap_range(lcd, __gpa(1 << 30), 1024);
129
fail4:
130
	lcd_arch_ept_unmap_range(lcd, __gpa(0), 1024);
131
fail3:
132
	lcd_arch_destroy(lcd);
133
fail1:
134
	return ret;
Charlie Jacobsen's avatar
Charlie Jacobsen committed
135 136
}

137
static int test04(void)
138 139
{
	struct lcd_arch *lcd;
140
	struct lcd_arch_thread *t;
141
	hva_t pgd;
142 143 144 145 146
	int ret = -1;
	
	/*
	 * Init lcd
	 */
147 148
	lcd = lcd_arch_create();
	if (!lcd) {
149
		LCD_ARCH_ERR("failed to create lcd");
150 151
		goto fail1;
	}
152 153 154
	/*
	 * Map a dummy page in the lcd's guest physical address space
	 */
155 156
	pgd = __hva(__get_free_page(GFP_KERNEL));
	if (!hva_val(pgd)) {
157
		LCD_ARCH_ERR("failed to alloc page");
158 159 160 161
		goto fail2;
	}
	ret = lcd_arch_ept_map(lcd, __gpa(0), hva2hpa(pgd), 1, 0);
	if (ret) {
162
		LCD_ARCH_ERR("error mapping pgd");
163 164
		goto fail3;
	}
165 166 167
	/*
	 * Set up an lcd_thread, added to lcd
	 */
168 169
	t = lcd_arch_add_thread(lcd);
	if (!t) {
170
		LCD_ARCH_ERR("error setting up lcd_thread");
171 172
		goto fail4;
	}
173 174 175 176 177
	/*
	 * Check fields
	 */
	if (t->vpid == 0) {
		LCD_ARCH_ERR("bad vpid");
178 179
		goto fail5;
	}
180 181
	if (t->lcd_arch != lcd) {
		LCD_ARCH_ERR("wrong lcd");
182
		goto fail6;
183
	}
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
	if (list_empty(&t->lcd_arch_threads)) {
		LCD_ARCH_ERR("not in lcd arch thread list?");
		goto fail7;
	}
	/*
	 * Set up its runtime environment
	 */
	ret = lcd_arch_set_gva_root(t, __gpa(0));
	if (ret) {
		LCD_ARCH_ERR("error setting gva root");
		goto fail8;
	}
	ret = lcd_arch_set_pc(t, __gva(0));
	if (ret) {
		LCD_ARCH_ERR("error setting pc");
		goto fail9;
	}
	ret = lcd_arch_set_sp(t, __gva(0));
	if (ret) {
		LCD_ARCH_ERR("error setting sp");
		goto fail10;
	}

	if (lcd_arch_check(t)) {
		LCD_ARCH_ERR("failed a check\n");
		goto fail11;
	}
211

212 213
	ret = 0;
	goto done;
214

215
done:
216 217 218 219
fail11:
fail10:
fail9:
fail8:
220
fail7:
221 222
fail6:
fail5:
223
	lcd_arch_destroy_thread(t);
224 225 226 227 228
fail4:
	lcd_arch_ept_unmap(lcd, __gpa(0));
fail3:
	free_page(hva_val(pgd));
fail2:
229
	lcd_arch_destroy(lcd);
230 231 232 233
fail1:
	return ret;
}

234
static int test05(void)
235 236
{
	if (!vmx_addr_is_canonical(0UL)) {
237
		LCD_ARCH_ERR("failed");
238 239 240
		return -1;
	}
	if (vmx_addr_is_canonical(1UL << 63)) {
241
		LCD_ARCH_ERR("failed");
242 243 244
		return -1;
	}
	if (vmx_addr_is_canonical(0xFFFFUL << 48)) {
245
		LCD_ARCH_ERR("failed");
246 247 248
		return -1;
	}
	if (!vmx_addr_is_canonical(0xFFFF8UL << 44)) {
249
		LCD_ARCH_ERR("failed");
250 251 252
		return -1;
	}
	if (!vmx_addr_is_canonical(0x00007UL << 44)) {
253
		LCD_ARCH_ERR("failed");
254 255 256 257 258 259
		return -1;
	}
	
	return 0;
}

260
static int test06(void)
261 262 263 264 265 266
{
	u32 width;

	width = cpuid_eax(0x80000008) & 0xff;

	if (vmx_bad_phys_addr(0xff)) {
267
		LCD_ARCH_ERR("failed");
268 269 270 271
		return -1;
	}
	
	if (vmx_bad_phys_addr(1UL << (width - 1))) {
272
		LCD_ARCH_ERR("failed");
273 274 275 276
		return -1;
	}
	
	if (!vmx_bad_phys_addr(1UL << width)) {
277
		LCD_ARCH_ERR("failed");
278 279 280 281
		return -1;
	}

	if (!vmx_bad_phys_addr(-1ULL)) {
282
		LCD_ARCH_ERR("failed");
283 284 285 286
		return -1;
	}

	if (width >= 40 && vmx_bad_phys_addr(0x30682f000)) {
287
		LCD_ARCH_ERR("failed");
288 289 290
		return -1;
	}

291 292
	return 0;
}
293

294 295 296 297 298 299 300 301 302 303
static void lcd_arch_tests(void)
{
	if (test01())
		return;
	if (test02())
		return;
	if (test03())
		return;
	if (test04())
		return;
304 305 306 307
	if (test05())
		return;
	if (test06())
		return;
308
	LCD_ARCH_MSG("all tests passed!");
309 310
	return;
}