blob: 75c602d8d1ba67a0dfa3bef3628f23670e0b592b [file] [log] [blame]
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <parlib/arch/arch.h>
#include <parlib/ros_debug.h>
#include <unistd.h>
#include <errno.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <ros/syscall.h>
#include <sys/mman.h>
#include <vmm/coreboot_tables.h>
#include <ros/common.h>
#include <vmm/vmm.h>
#include <vmm/virtio.h>
#include <vmm/virtio_mmio.h>
#include <vmm/virtio_ids.h>
#include <ros/arch/vmx.h>
#include <vmm/sched.h>
#include <vmm/util.h>
#include <ros/arch/mmu.h>
#include <ros/arch/trapframe.h>
char *vmxexit[] = {
VMX_EXIT_REASONS
};
void showstatus(FILE *f, struct guest_thread *vm_thread)
{
struct vm_trapframe *vm_tf = gth_to_vmtf(vm_thread);
int shutdown = vm_tf->tf_exit_reason;
char *when = shutdown & VMX_EXIT_REASONS_FAILED_VMENTRY ? "entry"
: "exit";
char *reason = "UNKNOWN";
shutdown &= ~VMX_EXIT_REASONS_FAILED_VMENTRY;
if (shutdown < COUNT_OF(vmxexit) && vmxexit[shutdown])
reason = vmxexit[shutdown];
fprintf(f, "Shutdown: core %d, %s due to %s(0x%x); ret code 0x%x\n",
vm_tf->tf_guest_pcoreid, when, reason, shutdown,
vm_tf->tf_exit_reason);
fprintf_vm_tf(f, vm_tf);
backtrace_guest_thread(f, vm_thread);
}
/* Convert a guest virtual address to physical address. */
int gva2gpa(struct guest_thread *vm_thread, uint64_t va, uint64_t *pa)
{
assert(vm_thread != NULL);
struct vm_trapframe *vm_tf = gth_to_vmtf(vm_thread);
uint64_t *ptptr = (uint64_t *)vm_tf->tf_cr3;
uint64_t entry;
for (int shift = PML4_SHIFT;
shift >= PML1_SHIFT;
shift -= BITS_PER_PML) {
entry = ptptr[PMLx(va, shift)];
/* bit 63 can be NX. Bits 62:52 are ignored (for PML4) */
entry &= 0x000fffffffffffff;
if (!PAGE_PRESENT(entry))
return -1;
if ((entry & PTE_PS) != 0) {
uint64_t bitmask = ((1 << shift) - 1);
*pa = (((uint64_t)va & bitmask) | (entry & ~bitmask));
return 0;
}
ptptr = (uint64_t *)PG_ADDR(entry);
}
*pa = ((uint64_t)va & 0xfff) | (uint64_t)ptptr;
return 0;
}
/* Get the RIP as a physical address. */
int rippa(struct guest_thread *vm_thread, uint64_t *pa)
{
assert(vm_thread != NULL);
return gva2gpa(vm_thread, gth_to_vmtf(vm_thread)->tf_rip, pa);
}