summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2013-11-04 23:25:07 +0000
committerneel <neel@FreeBSD.org>2013-11-04 23:25:07 +0000
commit94bdd999bb990eb9d14b55fa8a90bfd8e4005a8e (patch)
treed45082a0e89ad14ce2aad9849e86936e1c8fd491
parentfefbe5ab0a495d58849a7fe9d9908d64840bdc2c (diff)
downloadFreeBSD-src-94bdd999bb990eb9d14b55fa8a90bfd8e4005a8e.zip
FreeBSD-src-94bdd999bb990eb9d14b55fa8a90bfd8e4005a8e.tar.gz
Remove the 'vdev' abstraction that was meant to sit on top of device models
in the kernel. This abstraction was redundant because the only device emulated inside vmm.ko is the local apic and it is always at a fixed guest physical address. Discussed with: grehan
-rw-r--r--sys/amd64/vmm/io/vdev.c270
-rw-r--r--sys/amd64/vmm/io/vdev.h84
-rw-r--r--sys/amd64/vmm/io/vlapic.c56
-rw-r--r--sys/amd64/vmm/io/vlapic.h13
-rw-r--r--sys/amd64/vmm/vmm_lapic.c8
-rw-r--r--sys/modules/vmm/Makefile1
6 files changed, 12 insertions, 420 deletions
diff --git a/sys/amd64/vmm/io/vdev.c b/sys/amd64/vmm/io/vdev.c
deleted file mode 100644
index cd6c5d1..0000000
--- a/sys/amd64/vmm/io/vdev.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*-
- * Copyright (c) 2011 NetApp, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-
-#include "vdev.h"
-
-struct vdev {
- SLIST_ENTRY(vdev) entry;
- struct vdev_ops *ops;
- void *dev;
-};
-static SLIST_HEAD(, vdev) vdev_head;
-static int vdev_count;
-
-struct vdev_region {
- SLIST_ENTRY(vdev_region) entry;
- struct vdev_ops *ops;
- void *dev;
- struct io_region *io;
-};
-static SLIST_HEAD(, vdev_region) region_head;
-static int region_count;
-
-static MALLOC_DEFINE(M_VDEV, "vdev", "vdev");
-
-#define VDEV_INIT (0)
-#define VDEV_RESET (1)
-#define VDEV_HALT (2)
-
-// static const char* vdev_event_str[] = {"VDEV_INIT", "VDEV_RESET", "VDEV_HALT"};
-
-static int
-vdev_system_event(int event)
-{
- struct vdev *vd;
- int rc;
-
- // TODO: locking
- SLIST_FOREACH(vd, &vdev_head, entry) {
- // printf("%s : %s Device %s\n", __func__, vdev_event_str[event], vd->ops->name);
- switch (event) {
- case VDEV_INIT:
- rc = vd->ops->init(vd->dev);
- break;
- case VDEV_RESET:
- rc = vd->ops->reset(vd->dev);
- break;
- case VDEV_HALT:
- rc = vd->ops->halt(vd->dev);
- break;
- default:
- break;
- }
- if (rc) {
- printf("vdev %s init failed rc=%d\n",
- vd->ops->name, rc);
- return rc;
- }
- }
- return 0;
-}
-
-int
-vdev_init(void)
-{
- return vdev_system_event(VDEV_INIT);
-}
-
-int
-vdev_reset(void)
-{
- return vdev_system_event(VDEV_RESET);
-}
-
-int
-vdev_halt(void)
-{
- return vdev_system_event(VDEV_HALT);
-}
-
-void
-vdev_vm_init(void)
-{
- SLIST_INIT(&vdev_head);
- vdev_count = 0;
-
- SLIST_INIT(&region_head);
- region_count = 0;
-}
-void
-vdev_vm_cleanup(void)
-{
- struct vdev *vd;
-
- // TODO: locking
- while (!SLIST_EMPTY(&vdev_head)) {
- vd = SLIST_FIRST(&vdev_head);
- SLIST_REMOVE_HEAD(&vdev_head, entry);
- free(vd, M_VDEV);
- vdev_count--;
- }
-}
-
-int
-vdev_register(struct vdev_ops *ops, void *dev)
-{
- struct vdev *vd;
- vd = malloc(sizeof(*vd), M_VDEV, M_WAITOK | M_ZERO);
- vd->ops = ops;
- vd->dev = dev;
-
- // TODO: locking
- SLIST_INSERT_HEAD(&vdev_head, vd, entry);
- vdev_count++;
- return 0;
-}
-
-void
-vdev_unregister(void *dev)
-{
- struct vdev *vd, *found;
-
- found = NULL;
- // TODO: locking
- SLIST_FOREACH(vd, &vdev_head, entry) {
- if (vd->dev == dev) {
- found = vd;
- }
- }
-
- if (found) {
- SLIST_REMOVE(&vdev_head, found, vdev, entry);
- free(found, M_VDEV);
- }
-}
-
-#define IN_RANGE(val, start, end) \
- (((val) >= (start)) && ((val) < (end)))
-
-static struct vdev_region*
-vdev_find_region(struct io_region *io, void *dev)
-{
- struct vdev_region *region, *found;
- uint64_t region_base;
- uint64_t region_end;
-
- found = NULL;
-
- // TODO: locking
- // FIXME: we should verify we are in the context the current
- // vcpu here as well.
- SLIST_FOREACH(region, &region_head, entry) {
- region_base = region->io->base;
- region_end = region_base + region->io->len;
- if (IN_RANGE(io->base, region_base, region_end) &&
- IN_RANGE(io->base+io->len, region_base, region_end+1) &&
- (dev && dev == region->dev)) {
- found = region;
- break;
- }
- }
- return found;
-}
-
-int
-vdev_register_region(struct vdev_ops *ops, void *dev, struct io_region *io)
-{
- struct vdev_region *region;
-
- region = vdev_find_region(io, dev);
- if (region) {
- return -EEXIST;
- }
-
- region = malloc(sizeof(*region), M_VDEV, M_WAITOK | M_ZERO);
- region->io = io;
- region->ops = ops;
- region->dev = dev;
-
- // TODO: locking
- SLIST_INSERT_HEAD(&region_head, region, entry);
- region_count++;
-
- return 0;
-}
-
-void
-vdev_unregister_region(void *dev, struct io_region *io)
-{
- struct vdev_region *region;
-
- region = vdev_find_region(io, dev);
-
- if (region) {
- SLIST_REMOVE(&region_head, region, vdev_region, entry);
- free(region, M_VDEV);
- region_count--;
- }
-}
-
-static int
-vdev_memrw(uint64_t gpa, opsize_t size, uint64_t *data, int read)
-{
- struct vdev_region *region;
- struct io_region io;
- region_attr_t attr;
- int rc;
-
- io.base = gpa;
- io.len = size;
-
- region = vdev_find_region(&io, NULL);
- if (!region)
- return -EINVAL;
-
- attr = (read) ? MMIO_READ : MMIO_WRITE;
- if (!(region->io->attr & attr))
- return -EPERM;
-
- if (read)
- rc = region->ops->memread(region->dev, gpa, size, data);
- else
- rc = region->ops->memwrite(region->dev, gpa, size, *data);
-
- return rc;
-}
-
-int
-vdev_memread(uint64_t gpa, opsize_t size, uint64_t *data)
-{
- return vdev_memrw(gpa, size, data, 1);
-}
-
-int
-vdev_memwrite(uint64_t gpa, opsize_t size, uint64_t data)
-{
- return vdev_memrw(gpa, size, &data, 0);
-}
diff --git a/sys/amd64/vmm/io/vdev.h b/sys/amd64/vmm/io/vdev.h
deleted file mode 100644
index 6feeba8..0000000
--- a/sys/amd64/vmm/io/vdev.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*-
- * Copyright (c) 2011 NetApp, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _VDEV_H_
-#define _VDEV_H_
-
-typedef enum {
- BYTE = 1,
- WORD = 2,
- DWORD = 4,
- QWORD = 8,
-} opsize_t;
-
-typedef enum {
- MMIO_READ = 1,
- MMIO_WRITE = 2,
-} region_attr_t;
-
-struct io_region {
- uint64_t base;
- uint64_t len;
- region_attr_t attr;
- int vcpu;
-};
-
-typedef int (*vdev_init_t)(void* dev);
-typedef int (*vdev_reset_t)(void* dev);
-typedef int (*vdev_halt_t)(void* dev);
-typedef int (*vdev_memread_t)(void* dev, uint64_t gpa, opsize_t size, uint64_t *data);
-typedef int (*vdev_memwrite_t)(void* dev, uint64_t gpa, opsize_t size, uint64_t data);
-
-
-struct vdev_ops {
- const char *name;
- vdev_init_t init;
- vdev_reset_t reset;
- vdev_halt_t halt;
- vdev_memread_t memread;
- vdev_memwrite_t memwrite;
-};
-
-
-void vdev_vm_init(void);
-void vdev_vm_cleanup(void);
-
-int vdev_register(struct vdev_ops *ops, void *dev);
-void vdev_unregister(void *dev);
-
-int vdev_register_region(struct vdev_ops *ops, void *dev, struct io_region *io);
-void vdev_unregister_region(void *dev, struct io_region *io);
-
-int vdev_init(void);
-int vdev_reset(void);
-int vdev_halt(void);
-int vdev_memread(uint64_t gpa, opsize_t size, uint64_t *data);
-int vdev_memwrite(uint64_t gpa, opsize_t size, uint64_t data);
-
-#endif /* _VDEV_H_ */
-
diff --git a/sys/amd64/vmm/io/vlapic.c b/sys/amd64/vmm/io/vlapic.c
index 6411ba9..3061465 100644
--- a/sys/amd64/vmm/io/vlapic.c
+++ b/sys/amd64/vmm/io/vlapic.c
@@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$");
#include "vmm_stat.h"
#include "vmm_lapic.h"
#include "vmm_ktr.h"
-#include "vdev.h"
#include "vlapic.h"
#define VLAPIC_CTR0(vlapic, format) \
@@ -100,8 +99,6 @@ struct vlapic {
struct vm *vm;
int vcpuid;
- struct io_region *mmio;
- struct vdev_ops *ops;
struct LAPIC apic;
int esr_update;
@@ -195,9 +192,8 @@ vlapic_init_ipi(struct vlapic *vlapic)
}
static int
-vlapic_op_reset(void* dev)
+vlapic_reset(struct vlapic *vlapic)
{
- struct vlapic *vlapic = (struct vlapic*)dev;
struct LAPIC *lapic = &vlapic->apic;
memset(lapic, 0, sizeof(*lapic));
@@ -214,23 +210,6 @@ vlapic_op_reset(void* dev)
}
-static int
-vlapic_op_init(void* dev)
-{
- struct vlapic *vlapic = (struct vlapic*)dev;
- vdev_register_region(vlapic->ops, vlapic, vlapic->mmio);
- return vlapic_op_reset(dev);
-}
-
-static int
-vlapic_op_halt(void* dev)
-{
- struct vlapic *vlapic = (struct vlapic*)dev;
- vdev_unregister_region(vlapic, vlapic->mmio);
- return 0;
-
-}
-
void
vlapic_set_intr_ready(struct vlapic *vlapic, int vector)
{
@@ -594,11 +573,9 @@ vlapic_intr_accepted(struct vlapic *vlapic, int vector)
}
int
-vlapic_op_mem_read(void* dev, uint64_t gpa, opsize_t size, uint64_t *data)
+vlapic_read(struct vlapic *vlapic, uint64_t offset, uint64_t *data)
{
- struct vlapic *vlapic = (struct vlapic*)dev;
struct LAPIC *lapic = &vlapic->apic;
- uint64_t offset = gpa & ~(PAGE_SIZE);
uint32_t *reg;
int i;
@@ -686,11 +663,9 @@ vlapic_op_mem_read(void* dev, uint64_t gpa, opsize_t size, uint64_t *data)
}
int
-vlapic_op_mem_write(void* dev, uint64_t gpa, opsize_t size, uint64_t data)
+vlapic_write(struct vlapic *vlapic, uint64_t offset, uint64_t data)
{
- struct vlapic *vlapic = (struct vlapic*)dev;
struct LAPIC *lapic = &vlapic->apic;
- uint64_t offset = gpa & ~(PAGE_SIZE);
uint32_t *reg;
int retval;
@@ -832,16 +807,6 @@ restart:
return (0);
}
-struct vdev_ops vlapic_dev_ops = {
- .name = "vlapic",
- .init = vlapic_op_init,
- .reset = vlapic_op_reset,
- .halt = vlapic_op_halt,
- .memread = vlapic_op_mem_read,
- .memwrite = vlapic_op_mem_write,
-};
-static struct io_region vlapic_mmio[VM_MAXCPU];
-
struct vlapic *
vlapic_init(struct vm *vm, int vcpuid)
{
@@ -856,17 +821,7 @@ vlapic_init(struct vm *vm, int vcpuid)
if (vcpuid == 0)
vlapic->msr_apicbase |= APICBASE_BSP;
- vlapic->ops = &vlapic_dev_ops;
-
- vlapic->mmio = vlapic_mmio + vcpuid;
- vlapic->mmio->base = DEFAULT_APIC_BASE;
- vlapic->mmio->len = PAGE_SIZE;
- vlapic->mmio->attr = MMIO_READ|MMIO_WRITE;
- vlapic->mmio->vcpu = vcpuid;
-
- vdev_register(&vlapic_dev_ops, vlapic);
-
- vlapic_op_init(vlapic);
+ vlapic_reset(vlapic);
return (vlapic);
}
@@ -874,8 +829,7 @@ vlapic_init(struct vm *vm, int vcpuid)
void
vlapic_cleanup(struct vlapic *vlapic)
{
- vlapic_op_halt(vlapic);
- vdev_unregister(vlapic);
+
free(vlapic, M_VLAPIC);
}
diff --git a/sys/amd64/vmm/io/vlapic.h b/sys/amd64/vmm/io/vlapic.h
index 00de019..402cb79 100644
--- a/sys/amd64/vmm/io/vlapic.h
+++ b/sys/amd64/vmm/io/vlapic.h
@@ -29,10 +29,8 @@
#ifndef _VLAPIC_H_
#define _VLAPIC_H_
-#include "vdev.h"
-
struct vm;
-
+
/*
* Map of APIC Registers: Offset Description Access
*/
@@ -92,13 +90,8 @@ enum x2apic_state;
struct vlapic *vlapic_init(struct vm *vm, int vcpuid);
void vlapic_cleanup(struct vlapic *vlapic);
-
-int vlapic_op_mem_write(void* dev, uint64_t gpa,
- opsize_t size, uint64_t data);
-
-int vlapic_op_mem_read(void* dev, uint64_t gpa,
- opsize_t size, uint64_t *data);
-
+int vlapic_write(struct vlapic *vlapic, uint64_t offset, uint64_t data);
+int vlapic_read(struct vlapic *vlapic, uint64_t offset, uint64_t *data);
int vlapic_pending_intr(struct vlapic *vlapic);
void vlapic_intr_accepted(struct vlapic *vlapic, int vector);
void vlapic_set_intr_ready(struct vlapic *vlapic, int vector);
diff --git a/sys/amd64/vmm/vmm_lapic.c b/sys/amd64/vmm/vmm_lapic.c
index d024b71..b893ba4 100644
--- a/sys/amd64/vmm/vmm_lapic.c
+++ b/sys/amd64/vmm/vmm_lapic.c
@@ -130,7 +130,7 @@ lapic_rdmsr(struct vm *vm, int cpu, u_int msr, uint64_t *rval)
error = 0;
} else {
offset = x2apic_msr_to_regoff(msr);
- error = vlapic_op_mem_read(vlapic, offset, DWORD, rval);
+ error = vlapic_read(vlapic, offset, rval);
}
return (error);
@@ -150,7 +150,7 @@ lapic_wrmsr(struct vm *vm, int cpu, u_int msr, uint64_t val)
error = 0;
} else {
offset = x2apic_msr_to_regoff(msr);
- error = vlapic_op_mem_write(vlapic, offset, DWORD, val);
+ error = vlapic_write(vlapic, offset, val);
}
return (error);
@@ -174,7 +174,7 @@ lapic_mmio_write(void *vm, int cpu, uint64_t gpa, uint64_t wval, int size,
return (EINVAL);
vlapic = vm_lapic(vm, cpu);
- error = vlapic_op_mem_write(vlapic, off, DWORD, wval);
+ error = vlapic_write(vlapic, off, wval);
return (error);
}
@@ -196,6 +196,6 @@ lapic_mmio_read(void *vm, int cpu, uint64_t gpa, uint64_t *rval, int size,
return (EINVAL);
vlapic = vm_lapic(vm, cpu);
- error = vlapic_op_mem_read(vlapic, off, DWORD, rval);
+ error = vlapic_read(vlapic, off, rval);
return (error);
}
diff --git a/sys/modules/vmm/Makefile b/sys/modules/vmm/Makefile
index 959f128..e1a6e2d 100644
--- a/sys/modules/vmm/Makefile
+++ b/sys/modules/vmm/Makefile
@@ -27,7 +27,6 @@ SRCS+= vmm.c \
.PATH: ${.CURDIR}/../../amd64/vmm/io
SRCS+= iommu.c \
ppt.c \
- vdev.c \
vlapic.c
# intel-specific files
OpenPOWER on IntegriCloud