>From 39ca008b144e1e729223b1302fcdd7a435370487 Mon Sep 17 00:00:00 2001 From: Weidong Han <[EMAIL PROTECTED]> Date: Mon, 10 Nov 2008 14:33:43 +0800 Subject: [PATCH] support ioperm for vcpu hotplug
Track ioperm settings, when a new VCPU comes online, issue ioperm.
Signed-off-by: Weidong Han <[EMAIL PROTECTED]>
---
qemu/hw/device-assignment.c | 39 ++++++++++++++++++++-------------------
qemu/qemu-kvm.c | 13 +++++++++++++
qemu/qemu-kvm.h | 2 ++
3 files changed, 35 insertions(+), 19 deletions(-)
diff --git a/qemu/hw/device-assignment.c b/qemu/hw/device-assignment.c
index e1c3372..4e10ef7 100644
--- a/qemu/hw/device-assignment.c
+++ b/qemu/hw/device-assignment.c
@@ -174,10 +174,7 @@ static void assigned_dev_ioport_map(PCIDevice *pci_dev,
int region_num,
{
AssignedDevice *r_dev = (AssignedDevice *) pci_dev;
AssignedDevRegion *region = &r_dev->v_addrs[region_num];
- uint32_t old_port = region->u.r_baseport;
- uint32_t old_num = region->e_size;
- int first_map = (old_num == 0);
- struct ioperm_data data;
+ int first_map = (region->e_size == 0);
int i;
region->e_physbase = addr;
@@ -186,24 +183,25 @@ static void assigned_dev_ioport_map(PCIDevice *pci_dev,
int region_num,
DEBUG("e_phys=0x%x r_baseport=%x type=0x%x len=%d region_num=%d \n",
addr, region->u.r_baseport, type, size, region_num);
- memset(&data, 0, sizeof(data));
+ if (first_map) {
+ struct ioperm_data *data;
+
+ data = qemu_mallocz(sizeof(struct ioperm_data));
+ if (data == NULL) {
+ fprintf(stderr, "%s: Out of memory\n", __func__);
+ exit(1);
+ }
- if (!first_map) {
- data.start_port = old_port;
- data.num = old_num;
- data.turn_on = 0;
+ data->start_port = region->u.r_baseport;
+ data->num = region->r_size;
+ data->turn_on = 1;
+
+ kvm_add_ioperm_data(data);
for (i = 0; i < smp_cpus; ++i)
- kvm_ioperm(qemu_kvm_cpu_env(i), &data);
+ kvm_ioperm(qemu_kvm_cpu_env(i), data);
}
- data.start_port = region->u.r_baseport;
- data.num = size;
- data.turn_on = 1;
-
- for (i = 0; i < smp_cpus; ++i)
- kvm_ioperm(qemu_kvm_cpu_env(i), &data);
-
register_ioport_read(addr, size, 1, assigned_dev_ioport_readb,
(r_dev->v_addrs + region_num));
register_ioport_read(addr, size, 2, assigned_dev_ioport_readw,
@@ -350,12 +348,15 @@ static int assigned_dev_register_regions(PCIRegion
*io_regions,
continue;
}
/* handle port io regions */
+ pci_dev->v_addrs[i].e_physbase = cur_region->base_addr;
+ pci_dev->v_addrs[i].u.r_baseport = cur_region->base_addr;
+ pci_dev->v_addrs[i].r_size = cur_region->size;
+ pci_dev->v_addrs[i].e_size = 0;
+
pci_register_io_region((PCIDevice *) pci_dev, i,
cur_region->size, PCI_ADDRESS_SPACE_IO,
assigned_dev_ioport_map);
- pci_dev->v_addrs[i].e_physbase = cur_region->base_addr;
- pci_dev->v_addrs[i].u.r_baseport = cur_region->base_addr;
/* not relevant for port io */
pci_dev->v_addrs[i].memory_index = 0;
}
diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
index af9ad38..4cd8a2d 100644
--- a/qemu/qemu-kvm.c
+++ b/qemu/qemu-kvm.c
@@ -74,6 +74,9 @@ static int io_thread_sigfd = -1;
static int kvm_debug_stop_requested;
+/* The list of ioperm_data */
+static LIST_HEAD(, ioperm_data) ioperm_head;
+
static inline unsigned long kvm_get_thread_id(void)
{
return syscall(SYS_gettid);
@@ -441,6 +444,7 @@ static void *ap_main_loop(void *_env)
{
CPUState *env = _env;
sigset_t signals;
+ struct ioperm_data *data;
vcpu = &vcpu_info[env->cpu_index];
vcpu->env = env;
@@ -450,6 +454,10 @@ static void *ap_main_loop(void *_env)
kvm_create_vcpu(kvm_context, env->cpu_index);
kvm_qemu_init_env(env);
+ /* do ioperm for io ports of assigned devices */
+ LIST_FOREACH(data, &ioperm_head, entries)
+ on_vcpu(env, kvm_arch_do_ioperm, data);
+
/* signal VCPU creation */
pthread_mutex_lock(&qemu_mutex);
vcpu->created = 1;
@@ -1052,6 +1060,11 @@ int
qemu_kvm_unregister_coalesced_mmio(target_phys_addr_t addr,
#include <sys/io.h>
#ifdef USE_KVM_DEVICE_ASSIGNMENT
+void kvm_add_ioperm_data(struct ioperm_data *data)
+{
+ LIST_INSERT_HEAD(&ioperm_head, data, entries);
+}
+
void kvm_ioperm(CPUState *env, void *data)
{
if (kvm_enabled() && qemu_system_ready)
diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h
index 2c1dfa8..4cd4fca 100644
--- a/qemu/qemu-kvm.h
+++ b/qemu/qemu-kvm.h
@@ -107,6 +107,7 @@ int handle_powerpc_dcr_write(int vcpu,uint32_t dcrn,
uint32_t data);
#ifdef USE_KVM
#include "libkvm.h"
+#include "sys-queue.h"
extern int kvm_allowed;
extern kvm_context_t kvm_context;
@@ -115,6 +116,7 @@ struct ioperm_data {
unsigned long start_port;
unsigned long num;
int turn_on;
+ LIST_ENTRY(ioperm_data) entries;
};
#define kvm_enabled() (kvm_allowed)
--
1.5.1
0001-support-ioperm-for-vcpu-hotplug.patch
Description: 0001-support-ioperm-for-vcpu-hotplug.patch
