From: Peter Dinda Date: Thu, 14 Apr 2011 17:01:12 +0000 (-0500) Subject: Implementation of the host device interface + interface cleanup X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=aec065bb54946223ac3c64817408466433fd9413;p=palacios.git Implementation of the host device interface + interface cleanup --- diff --git a/palacios/include/interfaces/vmm_host_dev.h b/palacios/include/interfaces/vmm_host_dev.h index 9f7ea91..138839f 100644 --- a/palacios/include/interfaces/vmm_host_dev.h +++ b/palacios/include/interfaces/vmm_host_dev.h @@ -74,7 +74,7 @@ typedef void * v3_guest_dev_t; /* There is a notion of a bus class to which the device is attached */ -typedef enum { DIRECT, PCI } v3_bus_class_t; +typedef enum { V3_BUS_CLASS_DIRECT, V3_BUS_CLASS_PCI } v3_bus_class_t; #ifdef __V3VEE__ @@ -82,10 +82,12 @@ v3_host_dev_t v3_host_dev_open(char *impl, v3_bus_class_t bus, v3_guest_dev_t gdev); -uin64_t v3_host_dev_read_io(v3_host_dev_t hostdev, - uint16_t port, - void *dest - uint64_t len); +int v3_host_dev_close(v3_host_dev_t hdev); + +uint64_t v3_host_dev_read_io(v3_host_dev_t hostdev, + uint16_t port, + void *dest, + uint64_t len); uint64_t v3_host_dev_write_io(v3_host_dev_t hostdev, uint16_t port, @@ -102,13 +104,15 @@ uint64_t v3_host_dev_write_mem(v3_host_dev_t hostdev, void *src, uint64_t len); -int v3_host_dev_ack_irq(v3_host_dev_t hostdev, uint32_t irq); +int v3_host_dev_ack_irq(v3_host_dev_t hostdev, uint8_t irq); uint64_t v3_host_dev_config_read(v3_host_dev_t hostdev, + uint64_t offset, void *dest, uint64_t len); uint64_t v3_host_dev_config_write(v3_host_dev_t hostdev, + uint64_t offset, void *src, uint64_t len); @@ -124,6 +128,8 @@ struct v3_host_dev_hooks { v3_host_dev_t (*open)(char *impl, v3_bus_class_t bus, v3_guest_dev_t gdev); + + int (*close)(v3_host_dev_t hdev); // Read/Write from/to an IO port. The read must either // completely succeed, returning len or completely @@ -131,7 +137,7 @@ struct v3_host_dev_hooks { // Callee gets the host dev id and the port in the guest uint64_t (*read_io)(v3_host_dev_t hostdev, uint16_t port, - void *dest + void *dest, uint64_t len); uint64_t (*write_io)(v3_host_dev_t hostdev, @@ -153,15 +159,11 @@ struct v3_host_dev_hooks { void *src, uint64_t len); - // Palacis will call this when it has taken posession of the - // IRQ ad wants the host device to lower it - // This interface is unclear + // + // Palacios or the guest device will call this + // function when it has injected the irq + // requested by the guest // - // One potential use would be to allow for a palacios - // side device to raise the irq asynchronously from - // the host device. If this is permitted, then we - // need a way of informing the host device that the - // irq has actually been signalled. int (*ack_irq)(v3_host_dev_t hostdev, uint8_t irq); // Configuration space reads/writes for devices that @@ -175,11 +177,17 @@ struct v3_host_dev_hooks { // config space info. However, a read will return // the host device's config, while a write will affect // both the palacios-internal config and the hsot device's config - uint64_t (*config_read)(v3_host_dev_t hostdev, + // + // for V3_BUS_CLASS_PCI they correspond to PCI config space (e.g., BARS, etc) + // reads and writes + // + uint64_t (*read_config)(v3_host_dev_t hostdev, + uint64_t offset, void *dest, uint64_t len); - - uint64_t (*config_write)(v3_host_dev_t hostdev, + + uint64_t (*write_config)(v3_host_dev_t hostdev, + uint64_t offset, void *src, uint64_t len); diff --git a/palacios/src/interfaces/Kconfig b/palacios/src/interfaces/Kconfig index 0bd9d15..270509a 100644 --- a/palacios/src/interfaces/Kconfig +++ b/palacios/src/interfaces/Kconfig @@ -50,4 +50,13 @@ config PACKET to support the internal networking features of Palacios. +config HOST_DEVICE + bool "Host device support" + default n + help + Select this if you want to forward a guest device to a host-based decice implementation + This makes it possible for virtual devices such as the generic device and the pci_front + device to make host-based device implementations appear within the guest + + endmenu diff --git a/palacios/src/interfaces/Makefile b/palacios/src/interfaces/Makefile index 4f3a17b..df4e3dd 100644 --- a/palacios/src/interfaces/Makefile +++ b/palacios/src/interfaces/Makefile @@ -5,5 +5,6 @@ obj-$(CONFIG_CONSOLE) += vmm_console.o obj-$(CONFIG_STREAM) += vmm_stream.o obj-$(CONFIG_GRAPHICS_CONSOLE) += vmm_graphics_console.o obj-$(CONFIG_KEYED_STREAMS) += vmm_keyed_stream.o +obj-$(CONFIG_HOST_DEVICE) += vmm_host_dev.o diff --git a/palacios/src/interfaces/vmm_host_dev.c b/palacios/src/interfaces/vmm_host_dev.c new file mode 100644 index 0000000..064d17f --- /dev/null +++ b/palacios/src/interfaces/vmm_host_dev.c @@ -0,0 +1,190 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2011, Peter Dinda + * Copyright (c) 2011, The V3VEE Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + + +#include +#include +#include +#include +#include +#include + +struct v3_host_dev_hooks * host_dev_hooks = 0; + +v3_host_dev_t v3_host_dev_open(char *impl, + v3_bus_class_t bus, + v3_guest_dev_t gdev) +{ + V3_ASSERT(host_dev_hooks != NULL); + V3_ASSERT(host_dev_hooks->open != NULL); + + return host_dev_hooks->open(impl,bus,gdev); +} + +int v3_host_dev_close(v3_host_dev_t hdev) +{ + V3_ASSERT(host_dev_hooks); + V3_ASSERT(host_dev_hooks->close); + + return host_dev_hooks->close(hdev); +} + +uint64_t v3_host_dev_read_io(v3_host_dev_t hdev, + uint16_t port, + void *dst, + uint64_t len) +{ + V3_ASSERT(host_dev_hooks != NULL); + V3_ASSERT(host_dev_hooks->read_io != NULL); + + return host_dev_hooks->read_io(hdev,port,dst,len); +} + +uint64_t v3_host_dev_write_io(v3_host_dev_t hdev, + uint16_t port, + void *src, + uint64_t len) +{ + V3_ASSERT(host_dev_hooks != NULL); + V3_ASSERT(host_dev_hooks->write_io != NULL); + + return host_dev_hooks->write_io(hdev,port,src,len); +} + +uint64_t v3_host_dev_read_mem(v3_host_dev_t hdev, + addr_t gpa, + void *dst, + uint64_t len) +{ + V3_ASSERT(host_dev_hooks != NULL); + V3_ASSERT(host_dev_hooks->read_mem != NULL); + + return host_dev_hooks->read_mem(hdev,gpa,dst,len); +} + +uint64_t v3_host_dev_write_mem(v3_host_dev_t hdev, + addr_t gpa, + void *src, + uint64_t len) +{ + V3_ASSERT(host_dev_hooks != NULL); + V3_ASSERT(host_dev_hooks->write_mem != NULL); + + return host_dev_hooks->write_mem(hdev,gpa,src,len); +} + +uint64_t v3_host_dev_read_config(v3_host_dev_t hdev, + uint64_t offset, + void *dst, + uint64_t len) +{ + V3_ASSERT(host_dev_hooks != NULL); + V3_ASSERT(host_dev_hooks->read_config); + + return host_dev_hooks->read_config(hdev,offset,dst,len); +} + +uint64_t v3_host_dev_write_config(v3_host_dev_t hdev, + uint64_t offset, + void *src, + uint64_t len) +{ + V3_ASSERT(host_dev_hooks != NULL); + V3_ASSERT(host_dev_hooks->write_config); + + return host_dev_hooks->write_config(hdev,offset,src,len); + +} + + +int v3_host_dev_ack_irq(v3_host_dev_t hdev, uint8_t irq) +{ + V3_ASSERT(host_dev_hooks != NULL); + V3_ASSERT(host_dev_hooks->ack_irq); + + return host_dev_hooks->ack_irq(hdev,irq); +} + + +int v3_host_dev_raise_irq(v3_host_dev_t hostdev, + v3_guest_dev_t guest_dev, + uint8_t irq) +{ + // Make this smarter later... + + struct vm_device *dev = (struct vm_device *) guest_dev; + + if (dev && dev->vm) { + return v3_raise_irq(dev->vm,irq); + } else { + return -1; + } +} + + +uint64_t v3_host_dev_read_guest_mem(v3_host_dev_t hostdev, + v3_guest_dev_t guest_dev, + addr_t gpa, + void *dst, + uint64_t len) +{ + struct vm_device *dev = (struct vm_device *) guest_dev; + + if (!dev) { + return 0; + } else { + struct v3_vm_info *vm = dev->vm; + + if (!vm) { + return 0; + } else { + return v3_read_gpa_memory(&(vm->cores[0]), gpa, len, dst); + } + } +} + +uint64_t v3_host_dev_write_guest_mem(v3_host_dev_t hostdev, + v3_guest_dev_t guest_dev, + addr_t gpa, + void *src, + uint64_t len) +{ + struct vm_device *dev = (struct vm_device *) guest_dev; + + if (!dev) { + return 0; + } else { + struct v3_vm_info *vm = dev->vm; + + if (!vm) { + return 0; + } else { + return v3_write_gpa_memory(&(vm->cores[0]), gpa, len, src); + } + } +} + + + +void V3_Init_Host_Device_Support(struct v3_host_dev_hooks * hooks) { + host_dev_hooks = hooks; + PrintDebug("V3 host device interface inited\n"); + + return; +}