int vm_install_tk1_usb_passthrough_device(vm_t* vm) { /* Add the device */ void *addr = map_vm_device(vm, dev_usb.pstart, dev_usb.pstart, seL4_AllRights); if (addr == NULL) { ZF_LOGE("map_vm_device returned NULL"); return -1; } void *vmm_addr = vspace_share_mem(vm_get_vspace(vm), vm_get_vmm_vspace(vm), addr, 1, seL4_PageBits, seL4_AllRights, 0); if (vmm_addr == NULL) { ZF_LOGE("vspace_share_mem returned NULL"); return -1; } int err = vm_add_device(vm, &dev_usb); if (err) { ZF_LOGE("vm_add_device returned error: %d", err); return -1; } err = vm_register_reboot_callback(vm, usb_vm_reboot_hook, vmm_addr); if (err) { ZF_LOGE("vm_register_reboot_callback returned error: %d", err); return -1; } return 0; }
static int handle_page_fault(vm_t* vm, fault_t* fault) { struct device* d; /* See if the device is already in our address space */ d = vm_find_device_by_ipa(vm, fault_get_address(fault)); if (d != NULL) { if (d->devid == DEV_RAM) { DRAMFAULT("[%s] %s fault @ 0x%x from 0x%x\n", d->name, (fault_is_read(fault)) ? "read" : "write", fault_get_address(fault), fault_get_ctx(fault)->pc); } else { DDEVFAULT("[%s] %s fault @ 0x%x from 0x%x\n", d->name, (fault_is_read(fault)) ? "read" : "write", fault_get_address(fault), fault_get_ctx(fault)->pc); } return d->handle_page_fault(d, vm, fault); } else { #ifdef CONFIG_ONDEMAND_DEVICE_INSTALL uintptr_t addr = fault_get_address(fault) & ~0xfff; void* mapped; switch (addr) { case 0: printf("VM fault on IPA 0x%08x\n", 0); print_fault(fault); return -1; default: mapped = map_vm_device(vm, addr, addr, seL4_AllRights); if (mapped) { DVM("WARNING: Blindly mapped device @ 0x%x for PC 0x%x\n", fault_get_address(fault), fault_get_ctx(fault)->pc); restart_fault(fault); return 0; } mapped = map_vm_ram(vm, addr); if (mapped) { DVM("WARNING: Mapped RAM for device @ 0x%x for PC 0%x\n", fault_get_address(fault), fault_get_ctx(fault)->pc); restart_fault(fault); return 0; } DVM("Unhandled fault on address 0x%x\n", (uint32_t)addr); } #endif print_fault(fault); abandon_fault(fault); return -1; } }