1/** 2 * \file 3 */ 4 5/* 6 * Copyright (c) 2009, ETH Zurich. 7 * All rights reserved. 8 * 9 * This file is distributed under the terms in the attached LICENSE file. 10 * If you do not find this file, copies can be found by writing to: 11 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 12 */ 13 14#ifndef GUEST_H 15#define GUEST_H 16 17#include <barrelfish/barrelfish.h> 18#include <barrelfish_kpi/vmx_encodings.h> 19#include <spawndomain/spawndomain.h> 20#include <barrelfish_kpi/vmkit.h> 21#include <dev/amd_vmcb_dev.h> 22 23struct guest { 24 // indicates whether the guest is runnable atm or waiting 25 bool runnable; 26 // Monitor endpoint for this guest 27 struct lmp_endpoint *monitor_ep; 28 // The allocator for the slot this guests uses 29 struct multi_slot_allocator slot_alloc; 30 // VMCB data 31 struct capref vmcb_cap; 32 lpaddr_t vmcb_pa; 33 lvaddr_t vmcb_va; 34 // guest control data 35 struct capref ctrl_cap; 36 struct guest_control *ctrl; 37 // IOPM data (IO port access) 38#ifdef CONFIG_SVM 39 struct capref iopm_cap; 40 lpaddr_t iopm_pa; 41 lvaddr_t iopm_va; 42#else 43 struct capref iobmp_a_cap; 44 lpaddr_t iobmp_a_pa; 45 lvaddr_t iobmp_a_va; 46 47 struct capref iobmp_b_cap; 48 lpaddr_t iobmp_b_pa; 49 lvaddr_t iobmp_b_va; 50#endif 51 // MSRPM data (MSR access) 52 struct capref msrpm_cap; 53 lpaddr_t msrpm_pa; 54 lvaddr_t msrpm_va; 55 // Mackerel data structure to VMCV 56 amd_vmcb_t vmcb; 57 // Guest dispatcher 58 struct capref dcb_cap; 59 // Guests physical address space (virtual to the domain) 60 struct vspace *vspace; 61 lpaddr_t pml4_pa; 62 // Guest physical memory 63 lvaddr_t mem_low_va; 64 lvaddr_t mem_high_va; 65 // indicates whether the guest was in emulation before the exit 66 bool emulated_before_exit; 67 // virtual hardware 68 struct hdd *hdds[8]; 69 size_t hdd_count; 70 struct console *console; 71 struct pc16550d *serial_ports[4]; 72 size_t serial_port_count; 73 struct apic *apic; 74 struct lpc *lpc; 75 struct pci *pci; 76 // some settings which belong to an upcomming CPU abstraction 77 bool a20_gate_enabled; 78}; 79 80/** 81 * \brief This enum is used to indicate the size of operands to some operations. 82 */ 83enum opsize { 84 OPSIZE_8, 85 OPSIZE_16, 86 OPSIZE_32, 87 OPSIZE_64 88}; 89 90extern lvaddr_t guest_offset; 91static inline lvaddr_t 92 host_to_guest (lvaddr_t addr) 93{ 94 return addr - guest_offset; 95} 96 97static inline lvaddr_t 98 guest_to_host (lvaddr_t addr) 99{ 100 return addr + guest_offset; 101} 102 103// REGISTER ACCESS HELPERS 104 105// RAX 106 107static inline uint64_t 108guest_get_rax (struct guest *g) 109{ 110 return amd_vmcb_rax_rd(&g->vmcb); 111} 112 113static inline void 114guest_set_rax (struct guest *g, uint64_t val) 115{ 116 amd_vmcb_rax_wr(&g->vmcb, val); 117} 118 119static inline uint32_t 120guest_get_eax (struct guest *g) 121{ 122 return amd_vmcb_rax_rd(&g->vmcb) & 0xffffffff; 123} 124 125static inline void 126guest_set_eax (struct guest *g, uint32_t val) 127{ 128 uint64_t buf = amd_vmcb_rax_rd(&g->vmcb); 129 buf = (buf & ~0xffffffff) | val; 130 amd_vmcb_rax_wr(&g->vmcb, buf); 131} 132 133static inline uint16_t 134guest_get_ax (struct guest *g) 135{ 136 return amd_vmcb_rax_rd(&g->vmcb) & 0xffff; 137} 138 139static inline void 140guest_set_ax (struct guest *g, uint16_t val) 141{ 142 uint64_t buf = amd_vmcb_rax_rd(&g->vmcb); 143 buf = (buf & ~0xffff) | val; 144 amd_vmcb_rax_wr(&g->vmcb, buf); 145} 146 147static inline uint8_t 148guest_get_ah (struct guest *g) 149{ 150 return amd_vmcb_rax_rd(&g->vmcb) >> 8; 151} 152 153static inline void 154guest_set_ah (struct guest *g, uint8_t val) 155{ 156 uint64_t buf = amd_vmcb_rax_rd(&g->vmcb); 157 buf = (buf & ~0xff00) | ((uint64_t)val) << 8; 158 amd_vmcb_rax_wr(&g->vmcb, buf); 159} 160 161static inline uint8_t 162guest_get_al (struct guest *g) 163{ 164 return amd_vmcb_rax_rd(&g->vmcb); 165} 166 167static inline void 168guest_set_al (struct guest *g, uint8_t val) 169{ 170 uint64_t buf = amd_vmcb_rax_rd(&g->vmcb); 171 buf = (buf & ~0xff) | val; 172 amd_vmcb_rax_wr(&g->vmcb, buf); 173} 174 175 176// RBX 177 178static inline uint64_t 179guest_get_rbx (struct guest *g) 180{ 181 return g->ctrl->regs.rbx; 182} 183 184static inline void 185guest_set_rbx (struct guest *g, uint64_t val) 186{ 187 g->ctrl->regs.rbx = val; 188} 189 190static inline uint32_t 191guest_get_ebx (struct guest *g) { 192 return g->ctrl->regs.rbx; 193} 194 195static inline void 196guest_set_ebx (struct guest *g, uint32_t val) { 197 uint64_t buf = g->ctrl->regs.rbx; 198 g->ctrl->regs.rbx = (buf & ~0xffffffff) | val; 199} 200 201static inline uint16_t 202guest_get_bx (struct guest *g) 203{ 204 return g->ctrl->regs.rbx & 0xffff; 205} 206 207static inline void 208guest_set_bx (struct guest *g, uint16_t val) 209{ 210 uint64_t buf = g->ctrl->regs.rbx; 211 g->ctrl->regs.rbx = (buf & ~0xffff) | val; 212} 213 214static inline uint8_t 215guest_get_bl (struct guest *g) 216{ 217 return g->ctrl->regs.rbx & 0xff; 218} 219 220static inline void 221guest_set_bl (struct guest *g, uint8_t val) 222{ 223 uint64_t buf = g->ctrl->regs.rbx; 224 g->ctrl->regs.rbx = (buf & ~0xff) | val; 225} 226 227static inline uint8_t 228guest_get_bh (struct guest *g) 229{ 230 return g->ctrl->regs.rbx >> 8; 231} 232 233static inline void 234guest_set_bh (struct guest *g, uint8_t val) 235{ 236 uint64_t buf = g->ctrl->regs.rbx; 237 g->ctrl->regs.rbx = (buf & ~0xff00) | ((uint64_t)val) << 8; 238} 239 240 241// RCX 242 243static inline uint64_t 244guest_get_rcx (struct guest *g) 245{ 246 return g->ctrl->regs.rcx; 247} 248 249static inline void 250guest_set_rcx (struct guest *g, uint64_t val) 251{ 252 g->ctrl->regs.rcx = val; 253} 254 255static inline uint32_t 256guest_get_ecx (struct guest *g) { 257 return g->ctrl->regs.rcx; 258} 259 260static inline void 261guest_set_ecx (struct guest *g, uint32_t val) { 262 uint64_t buf = g->ctrl->regs.rcx; 263 g->ctrl->regs.rcx = (buf & ~0xffffffff) | val; 264} 265 266static inline uint16_t 267guest_get_cx (struct guest *g) 268{ 269 return g->ctrl->regs.rcx & 0xffff; 270} 271 272static inline void 273guest_set_cx (struct guest *g, uint16_t val) 274{ 275 uint64_t buf = g->ctrl->regs.rcx; 276 g->ctrl->regs.rcx = (buf & ~0xffff) | val; 277} 278 279static inline uint8_t 280guest_get_ch (struct guest *g) 281{ 282 return g->ctrl->regs.rcx >> 8; 283} 284 285static inline void 286guest_set_ch (struct guest *g, uint8_t val) 287{ 288 uint64_t buf = g->ctrl->regs.rcx; 289 g->ctrl->regs.rcx = (buf & ~0xff00) | ((uint64_t)val) << 8; 290} 291 292static inline uint8_t 293guest_get_cl (struct guest *g) 294{ 295 return g->ctrl->regs.rcx; 296} 297 298static inline void 299guest_set_cl (struct guest *g, uint8_t val) 300{ 301 uint64_t buf = g->ctrl->regs.rcx; 302 buf = (buf & ~0xff) | val; 303 g->ctrl->regs.rcx = val; 304} 305 306 307// RDX 308 309static inline uint64_t 310guest_get_rdx (struct guest *g) 311{ 312 return g->ctrl->regs.rdx; 313} 314 315static inline void 316guest_set_rdx (struct guest *g, uint64_t val) 317{ 318 g->ctrl->regs.rdx = val; 319} 320 321static inline uint32_t 322guest_get_edx (struct guest *g) { 323 return g->ctrl->regs.rdx; 324} 325 326static inline void 327guest_set_edx (struct guest *g, uint32_t val) { 328 uint64_t buf = g->ctrl->regs.rdx; 329 g->ctrl->regs.rdx = (buf & ~0xffffffff) | val; 330} 331 332static inline uint8_t 333guest_get_dh (struct guest *g) 334{ 335 return g->ctrl->regs.rdx >> 8; 336} 337 338static inline void 339guest_set_dh (struct guest *g, uint8_t val) 340{ 341 uint64_t buf = g->ctrl->regs.rdx; 342 g->ctrl->regs.rdx = (buf & ~0xff00) | ((uint64_t)val) << 8; 343} 344 345static inline uint8_t 346guest_get_dl (struct guest *g) 347{ 348 return g->ctrl->regs.rdx & 0xff; 349} 350 351static inline void 352guest_set_dl (struct guest *g, uint8_t val) 353{ 354 uint64_t buf = g->ctrl->regs.rdx; 355 g->ctrl->regs.rdx = (buf & ~0xff) | val; 356} 357 358 359// RDI 360 361static inline uint64_t 362guest_get_rdi (struct guest *g) 363{ 364 return g->ctrl->regs.rdi; 365} 366 367static inline void 368guest_set_rdi (struct guest *g, uint64_t val) 369{ 370 g->ctrl->regs.rdi = val; 371} 372 373static inline uint16_t 374guest_get_di (struct guest *g) 375{ 376 return g->ctrl->regs.rdi & 0xffff; 377} 378 379static inline void 380guest_set_di (struct guest *g, uint16_t val) 381{ 382 uint64_t buf = g->ctrl->regs.rdi; 383 g->ctrl->regs.rdi = (buf & ~0xffff) | val; 384} 385 386 387// RSI 388 389static inline uint64_t 390guest_get_rsi (struct guest *g) 391{ 392 return g->ctrl->regs.rsi; 393} 394 395static inline void 396guest_set_rsi (struct guest *g, uint64_t val) 397{ 398 g->ctrl->regs.rsi = val; 399} 400 401static inline uint16_t 402guest_get_si (struct guest *g) 403{ 404 return g->ctrl->regs.rsi & 0xffff; 405} 406 407static inline void 408guest_set_si (struct guest *g, uint16_t val) 409{ 410 uint64_t buf = g->ctrl->regs.rsi; 411 g->ctrl->regs.rsi = (buf & ~0xffff) | val; 412} 413 414 415// RSP 416 417static inline uint64_t 418guest_get_rsp (struct guest *g) 419{ 420 return amd_vmcb_rsp_rd(&g->vmcb); 421} 422 423static inline void 424guest_set_rsp (struct guest *g, uint64_t val) 425{ 426 amd_vmcb_rsp_wr(&g->vmcb, val); 427} 428 429 430// RBP 431 432static inline uint64_t 433guest_get_rbp (struct guest *g) 434{ 435 return g->ctrl->regs.rbp; 436} 437 438static inline void 439guest_set_rbp (struct guest *g, uint64_t val) 440{ 441 g->ctrl->regs.rbp = val; 442} 443 444 445struct guest *guest_create (void); 446errval_t guest_make_runnable (struct guest *g, bool run); 447void guest_handle_vmexit (struct guest *g); 448void spawn_guest_domain (struct guest *self, struct spawninfo *si); 449 450#endif // GUEST_H 451