* [Qemu-devel] [patch 01/24] QEMU/KVM: add devices to represent PCI slots with _EJ0 method
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
@ 2008-03-11 20:11 ` Marcelo Tosatti
2008-03-11 20:11 ` [Qemu-devel] [patch 02/24] QEMU/KVM: add OperationRegion and GPE handler for add/removal notification Marcelo Tosatti
` (23 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:11 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: devicehotplug.1 --]
[-- Type: text/plain, Size: 5434 bytes --]
Presence of _EJ0 method indicates that slots are hot-pluggable.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/bios/acpi-dsdt.dsl
===================================================================
--- kvm-userspace.hotplug2.orig/bios/acpi-dsdt.dsl
+++ kvm-userspace.hotplug2/bios/acpi-dsdt.dsl
@@ -407,6 +407,161 @@ DefinitionBlock (
Package() {0x001fffff, 3, LNKB, 0},
})
+ Device (S1) { // Slot 1
+ Name (_ADR, 0x00010000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S2) { // Slot 2
+ Name (_ADR, 0x00020000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S3) { // Slot 3
+ Name (_ADR, 0x00030000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S4) { // Slot 4
+ Name (_ADR, 0x00040000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S5) { // Slot 5
+ Name (_ADR, 0x00050000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S6) { // Slot 6
+ Name (_ADR, 0x00060000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S7) { // Slot 7
+ Name (_ADR, 0x00070000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S8) { // Slot 8
+ Name (_ADR, 0x00080000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S9) { // Slot 9
+ Name (_ADR, 0x00090000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S10) { // Slot 10
+ Name (_ADR, 0x000A0000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S11) { // Slot 11
+ Name (_ADR, 0x000B0000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S12) { // Slot 12
+ Name (_ADR, 0x000C0000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S13) { // Slot 13
+ Name (_ADR, 0x000D0000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S14) { // Slot 14
+ Name (_ADR, 0x000E0000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S15) { // Slot 15
+ Name (_ADR, 0x000F0000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S16) { // Slot 16
+ Name (_ADR, 0x00100000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S17) { // Slot 17
+ Name (_ADR, 0x00110000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S18) { // Slot 18
+ Name (_ADR, 0x00120000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S19) { // Slot 19
+ Name (_ADR, 0x00130000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S20) { // Slot 20
+ Name (_ADR, 0x00140000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S21) { // Slot 21
+ Name (_ADR, 0x00150000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S22) { // Slot 22
+ Name (_ADR, 0x00160000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S23) { // Slot 23
+ Name (_ADR, 0x00170000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S24) { // Slot 24
+ Name (_ADR, 0x00180000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S25) { // Slot 25
+ Name (_ADR, 0x00190000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S26) { // Slot 26
+ Name (_ADR, 0x001A0000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S27) { // Slot 27
+ Name (_ADR, 0x001B0000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S28) { // Slot 28
+ Name (_ADR, 0x001C0000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S29) { // Slot 29
+ Name (_ADR, 0x001D0000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S30) { // Slot 30
+ Name (_ADR, 0x001E0000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
+ Device (S31) { // Slot 31
+ Name (_ADR, 0x001F0000)
+ Method (_EJ0,1) { Return (0x0) }
+ }
+
Method (_CRS, 0, NotSerialized)
{
Name (MEMP, ResourceTemplate ()
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 02/24] QEMU/KVM: add OperationRegion and GPE handler for add/removal notification
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
2008-03-11 20:11 ` [Qemu-devel] [patch 01/24] QEMU/KVM: add devices to represent PCI slots with _EJ0 method Marcelo Tosatti
@ 2008-03-11 20:11 ` Marcelo Tosatti
2008-03-11 20:11 ` [Qemu-devel] [patch 03/24] QEMU/KVM: add pci_find_bus Marcelo Tosatti
` (22 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:11 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: devicehotplug.2 --]
[-- Type: text/plain, Size: 7727 bytes --]
Use GPE _L01 to notify OSPM.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/bios/acpi-dsdt.dsl
===================================================================
--- kvm-userspace.hotplug2.orig/bios/acpi-dsdt.dsl
+++ kvm-userspace.hotplug2/bios/acpi-dsdt.dsl
@@ -407,6 +407,13 @@ DefinitionBlock (
Package() {0x001fffff, 3, LNKB, 0},
})
+ OperationRegion(PCST, SystemIO, 0xae00, 0x08)
+ Field (PCST, DWordAcc, NoLock, WriteAsZeros)
+ {
+ PCIU, 32,
+ PCID, 32,
+ }
+
Device (S1) { // Slot 1
Name (_ADR, 0x00010000)
Method (_EJ0,1) { Return (0x0) }
@@ -1142,6 +1149,256 @@ DefinitionBlock (
Return(0x01)
}
Method(_L01) {
+ /* Up status */
+ If (And(\_SB.PCI0.PCIU, 0x2)) {
+ Notify(\_SB.PCI0.S1, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x4)) {
+ Notify(\_SB.PCI0.S2, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x8)) {
+ Notify(\_SB.PCI0.S3, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x10)) {
+ Notify(\_SB.PCI0.S4, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x20)) {
+ Notify(\_SB.PCI0.S5, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x40)) {
+ Notify(\_SB.PCI0.S6, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x80)) {
+ Notify(\_SB.PCI0.S7, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x0100)) {
+ Notify(\_SB.PCI0.S8, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x0200)) {
+ Notify(\_SB.PCI0.S9, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x0400)) {
+ Notify(\_SB.PCI0.S10, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x0800)) {
+ Notify(\_SB.PCI0.S11, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x1000)) {
+ Notify(\_SB.PCI0.S12, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x2000)) {
+ Notify(\_SB.PCI0.S13, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x4000)) {
+ Notify(\_SB.PCI0.S14, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x8000)) {
+ Notify(\_SB.PCI0.S15, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x10000)) {
+ Notify(\_SB.PCI0.S16, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x20000)) {
+ Notify(\_SB.PCI0.S17, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x40000)) {
+ Notify(\_SB.PCI0.S18, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x80000)) {
+ Notify(\_SB.PCI0.S19, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x100000)) {
+ Notify(\_SB.PCI0.S20, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x200000)) {
+ Notify(\_SB.PCI0.S21, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x400000)) {
+ Notify(\_SB.PCI0.S22, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x800000)) {
+ Notify(\_SB.PCI0.S23, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x1000000)) {
+ Notify(\_SB.PCI0.S24, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x2000000)) {
+ Notify(\_SB.PCI0.S25, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x4000000)) {
+ Notify(\_SB.PCI0.S26, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x8000000)) {
+ Notify(\_SB.PCI0.S27, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x10000000)) {
+ Notify(\_SB.PCI0.S28, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x20000000)) {
+ Notify(\_SB.PCI0.S29, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x40000000)) {
+ Notify(\_SB.PCI0.S30, 0x1)
+ }
+
+ If (And(\_SB.PCI0.PCIU, 0x80000000)) {
+ Notify(\_SB.PCI0.S31, 0x1)
+ }
+
+ /* Down status */
+ If (And(\_SB.PCI0.PCID, 0x2)) {
+ Notify(\_SB.PCI0.S1, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x4)) {
+ Notify(\_SB.PCI0.S2, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x8)) {
+ Notify(\_SB.PCI0.S3, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x10)) {
+ Notify(\_SB.PCI0.S4, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x20)) {
+ Notify(\_SB.PCI0.S5, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x40)) {
+ Notify(\_SB.PCI0.S6, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x80)) {
+ Notify(\_SB.PCI0.S7, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x0100)) {
+ Notify(\_SB.PCI0.S8, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x0200)) {
+ Notify(\_SB.PCI0.S9, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x0400)) {
+ Notify(\_SB.PCI0.S10, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x0800)) {
+ Notify(\_SB.PCI0.S11, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x1000)) {
+ Notify(\_SB.PCI0.S12, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x2000)) {
+ Notify(\_SB.PCI0.S13, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x4000)) {
+ Notify(\_SB.PCI0.S14, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x8000)) {
+ Notify(\_SB.PCI0.S15, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x10000)) {
+ Notify(\_SB.PCI0.S16, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x20000)) {
+ Notify(\_SB.PCI0.S17, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x40000)) {
+ Notify(\_SB.PCI0.S18, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x80000)) {
+ Notify(\_SB.PCI0.S19, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x100000)) {
+ Notify(\_SB.PCI0.S20, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x200000)) {
+ Notify(\_SB.PCI0.S21, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x400000)) {
+ Notify(\_SB.PCI0.S22, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x800000)) {
+ Notify(\_SB.PCI0.S23, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x1000000)) {
+ Notify(\_SB.PCI0.S24, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x2000000)) {
+ Notify(\_SB.PCI0.S25, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x4000000)) {
+ Notify(\_SB.PCI0.S26, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x8000000)) {
+ Notify(\_SB.PCI0.S27, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x10000000)) {
+ Notify(\_SB.PCI0.S28, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x20000000)) {
+ Notify(\_SB.PCI0.S29, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x40000000)) {
+ Notify(\_SB.PCI0.S30, 0x3)
+ }
+
+ If (And(\_SB.PCI0.PCID, 0x80000000)) {
+ Notify(\_SB.PCI0.S31, 0x3)
+ }
+
Return(0x01)
}
Method(_L02) {
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 03/24] QEMU/KVM: add pci_find_bus
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
2008-03-11 20:11 ` [Qemu-devel] [patch 01/24] QEMU/KVM: add devices to represent PCI slots with _EJ0 method Marcelo Tosatti
2008-03-11 20:11 ` [Qemu-devel] [patch 02/24] QEMU/KVM: add OperationRegion and GPE handler for add/removal notification Marcelo Tosatti
@ 2008-03-11 20:11 ` Marcelo Tosatti
2008-03-11 20:11 ` [Qemu-devel] [patch 04/24] QEMU/KVM: return PCIDevice on net device init and record devfn Marcelo Tosatti
` (21 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:11 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: pcibus --]
[-- Type: text/plain, Size: 1379 bytes --]
Return PCIBus pointer from bus number integer.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/hw/pci.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/pci.c
+++ kvm-userspace.hotplug2/qemu/hw/pci.c
@@ -675,6 +675,16 @@ static void pci_bridge_write_config(PCID
pci_default_write_config(d, address, val, len);
}
+PCIBus *pci_find_bus(int bus_num)
+{
+ PCIBus *bus = first_bus;
+
+ while (bus && bus->bus_num != bus_num)
+ bus = bus->next;
+
+ return bus;
+}
+
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
pci_map_irq_fn map_irq, const char *name)
{
Index: kvm-userspace.hotplug2/qemu/hw/pci.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/pci.h
+++ kvm-userspace.hotplug2/qemu/hw/pci.h
@@ -3,6 +3,7 @@
/* PCI includes legacy ISA access. */
#include "isa.h"
+#include <linux/pci.h>
/* PCI bus */
@@ -91,6 +92,7 @@ void pci_data_write(void *opaque, uint32
uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
int pci_bus_num(PCIBus *s);
void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
+PCIBus *pci_find_bus(int bus_num);
void pci_info(void);
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 04/24] QEMU/KVM: return PCIDevice on net device init and record devfn
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (2 preceding siblings ...)
2008-03-11 20:11 ` [Qemu-devel] [patch 03/24] QEMU/KVM: add pci_find_bus Marcelo Tosatti
@ 2008-03-11 20:11 ` Marcelo Tosatti
2008-03-11 20:11 ` [Qemu-devel] [patch 05/24] QEMU/KVM: pci hotplug GPE support Marcelo Tosatti
` (20 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:11 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: return-pcidev --]
[-- Type: text/plain, Size: 9822 bytes --]
Change the PCI network drivers init functions to return the PCIDev, to
inform which slot has been hot-plugged.
Also record devfn on the NICInfo structure to locate for release
on hot-removal.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/hw/e1000.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/e1000.c
+++ kvm-userspace.hotplug2/qemu/hw/e1000.c
@@ -930,7 +930,7 @@ e1000_mmio_map(PCIDevice *pci_dev, int r
cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
}
-void
+PCIDevice *
pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
{
E1000State *d;
@@ -994,4 +994,6 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd,
d->nd->macaddr[3], d->nd->macaddr[4], d->nd->macaddr[5]);
register_savevm(info_str, d->instance, 1, nic_save, nic_load, d);
+
+ return (PCIDevice *)d;
}
Index: kvm-userspace.hotplug2/qemu/hw/eepro100.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/eepro100.c
+++ kvm-userspace.hotplug2/qemu/hw/eepro100.c
@@ -1742,7 +1742,7 @@ static void nic_save(QEMUFile * f, void
qemu_put_buffer(f, s->configuration, sizeof(s->configuration));
}
-static void nic_init(PCIBus * bus, NICInfo * nd,
+static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd,
const char *name, uint32_t device)
{
PCIEEPRO100State *d;
@@ -1794,22 +1794,23 @@ static void nic_init(PCIBus * bus, NICIn
/* XXX: instance number ? */
register_savevm(name, 0, 3, nic_save, nic_load, s);
+ return (PCIDevice *)d;
}
-void pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn)
+PCIDevice *pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn)
{
- nic_init(bus, nd, "i82551", i82551);
+ return nic_init(bus, nd, "i82551", i82551);
//~ uint8_t *pci_conf = d->dev.config;
}
-void pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn)
+PCIDevice *pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn)
{
- nic_init(bus, nd, "i82557b", i82557B);
+ return nic_init(bus, nd, "i82557b", i82557B);
}
-void pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn)
+PCIDevice *pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn)
{
- nic_init(bus, nd, "i82559er", i82559ER);
+ return nic_init(bus, nd, "i82559er", i82559ER);
}
/* eof */
Index: kvm-userspace.hotplug2/qemu/hw/ne2000.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/ne2000.c
+++ kvm-userspace.hotplug2/qemu/hw/ne2000.c
@@ -786,7 +786,7 @@ static void ne2000_map(PCIDevice *pci_de
register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
}
-void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
+PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
{
PCINE2000State *d;
NE2000State *s;
@@ -827,4 +827,6 @@ void pci_ne2000_init(PCIBus *bus, NICInf
/* XXX: instance number ? */
register_savevm("ne2000", ne2000_id++, 3, ne2000_save, ne2000_load, s);
+
+ return (PCIDevice *)d;
}
Index: kvm-userspace.hotplug2/qemu/hw/pc.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/pc.h
+++ kvm-userspace.hotplug2/qemu/hw/pc.h
@@ -146,7 +146,7 @@ void isa_ne2000_init(int base, qemu_irq
/* virtio-net.c */
-void *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn);
void virtio_net_poll(void);
/* virtio-blk.h */
Index: kvm-userspace.hotplug2/qemu/hw/pci.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/pci.c
+++ kvm-userspace.hotplug2/qemu/hw/pci.c
@@ -625,24 +625,26 @@ void pci_info(void)
}
/* Initialize a PCI NIC. */
-void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn)
+PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn)
{
+ PCIDevice *pci_dev;
+
if (strcmp(nd->model, "ne2k_pci") == 0) {
- pci_ne2000_init(bus, nd, devfn);
+ pci_dev = pci_ne2000_init(bus, nd, devfn);
} else if (strcmp(nd->model, "i82551") == 0) {
- pci_i82551_init(bus, nd, devfn);
+ pci_dev = pci_i82551_init(bus, nd, devfn);
} else if (strcmp(nd->model, "i82557b") == 0) {
- pci_i82557b_init(bus, nd, devfn);
+ pci_dev = pci_i82557b_init(bus, nd, devfn);
} else if (strcmp(nd->model, "i82559er") == 0) {
- pci_i82559er_init(bus, nd, devfn);
+ pci_dev = pci_i82559er_init(bus, nd, devfn);
} else if (strcmp(nd->model, "rtl8139") == 0) {
- pci_rtl8139_init(bus, nd, devfn);
+ pci_dev = pci_rtl8139_init(bus, nd, devfn);
} else if (strcmp(nd->model, "e1000") == 0) {
- pci_e1000_init(bus, nd, devfn);
+ pci_dev = pci_e1000_init(bus, nd, devfn);
} else if (strcmp(nd->model, "pcnet") == 0) {
- pci_pcnet_init(bus, nd, devfn);
+ pci_dev = pci_pcnet_init(bus, nd, devfn);
} else if (strcmp(nd->model, "virtio") == 0) {
- virtio_net_init(bus, nd, devfn);
+ pci_dev = virtio_net_init(bus, nd, devfn);
} else if (strcmp(nd->model, "?") == 0) {
fprintf(stderr, "qemu: Supported PCI NICs: i82551 i82557b i82559er"
" ne2k_pci pcnet rtl8139 e1000 virtio\n");
@@ -651,6 +653,8 @@ void pci_nic_init(PCIBus *bus, NICInfo *
fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
exit (1);
}
+ nd->devfn = pci_dev->devfn;
+ return pci_dev;
}
typedef struct {
Index: kvm-userspace.hotplug2/qemu/hw/pci.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/pci.h
+++ kvm-userspace.hotplug2/qemu/hw/pci.h
@@ -87,7 +87,7 @@ typedef int (*pci_map_irq_fn)(PCIDevice
PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
qemu_irq *pic, int devfn_min, int nirq);
-void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn);
void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len);
uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
int pci_bus_num(PCIBus *s);
@@ -116,23 +116,23 @@ void usb_ohci_init_pci(struct PCIBus *bu
/* eepro100.c */
-void pci_i82551_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pci_i82557b_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pci_i82559er_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_i82551_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_i82557b_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_i82559er_init(PCIBus *bus, NICInfo *nd, int devfn);
/* ne2000.c */
-void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn);
/* rtl8139.c */
-void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn);
/* e1000.c */
-void pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn);
/* pcnet.c */
-void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn);
/* prep_pci.c */
PCIBus *pci_prep_init(qemu_irq *pic);
Index: kvm-userspace.hotplug2/qemu/hw/pcnet.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/pcnet.c
+++ kvm-userspace.hotplug2/qemu/hw/pcnet.c
@@ -1958,7 +1958,7 @@ static void pci_physical_memory_read(voi
cpu_physical_memory_read(addr, buf, len);
}
-void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
+PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
{
PCNetState *d;
uint8_t *pci_conf;
@@ -2006,6 +2006,7 @@ void pci_pcnet_init(PCIBus *bus, NICInfo
d->pci_dev = &d->dev;
pcnet_common_init(d, nd, "pcnet");
+ return (PCIDevice *)d;
}
/* SPARC32 interface */
Index: kvm-userspace.hotplug2/qemu/hw/rtl8139.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/rtl8139.c
+++ kvm-userspace.hotplug2/qemu/hw/rtl8139.c
@@ -3410,7 +3410,7 @@ static void rtl8139_timer(void *opaque)
}
#endif /* RTL8139_ONBOARD_TIMER */
-void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
+PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
{
PCIRTL8139State *d;
RTL8139State *s;
@@ -3474,5 +3474,6 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
qemu_mod_timer(s->timer,
rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock)));
#endif /* RTL8139_ONBOARD_TIMER */
+ return (PCIDevice *)d;
}
Index: kvm-userspace.hotplug2/qemu/hw/virtio-net.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/virtio-net.c
+++ kvm-userspace.hotplug2/qemu/hw/virtio-net.c
@@ -279,7 +279,7 @@ static void virtio_net_tx_timer(void *op
virtio_net_flush_tx(n, n->tx_vq);
}
-void *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
+PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
{
VirtIONet *n;
@@ -306,5 +306,5 @@ void *virtio_net_init(PCIBus *bus, NICIn
n->tx_timer = qemu_new_timer(vm_clock, virtio_net_tx_timer, n);
n->tx_timer_active = 0;
- return &n->vdev;
+ return (PCIDevice *)n;
}
Index: kvm-userspace.hotplug2/qemu/net.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/net.h
+++ kvm-userspace.hotplug2/qemu/net.h
@@ -45,6 +45,7 @@ struct NICInfo {
uint8_t macaddr[6];
const char *model;
VLANState *vlan;
+ int devfn;
};
extern int nb_nics;
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 05/24] QEMU/KVM: pci hotplug GPE support
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (3 preceding siblings ...)
2008-03-11 20:11 ` [Qemu-devel] [patch 04/24] QEMU/KVM: return PCIDevice on net device init and record devfn Marcelo Tosatti
@ 2008-03-11 20:11 ` Marcelo Tosatti
2008-03-11 20:11 ` [Qemu-devel] [patch 06/24] QEMU/KVM: dynamic drive/drive_opt index allocation Marcelo Tosatti
` (19 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:11 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: acpi --]
[-- Type: text/plain, Size: 2876 bytes --]
Enable the corresponding bit on the PCIST region and trigger the SCI.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/hw/acpi.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/acpi.c
+++ kvm-userspace.hotplug2/qemu/hw/acpi.c
@@ -538,6 +538,7 @@ void qemu_system_powerdown(void)
#endif
#define GPE_BASE 0xafe0
#define PROC_BASE 0xaf00
+#define PCI_BASE 0xae00
struct gpe_regs {
uint16_t sts; /* status */
@@ -546,7 +547,13 @@ struct gpe_regs {
uint8_t down;
};
+struct pci_status {
+ uint32_t up;
+ uint32_t down;
+};
+
static struct gpe_regs gpe;
+static struct pci_status pci0_status;
static uint32_t gpe_readb(void *opaque, uint32_t addr)
{
@@ -614,6 +621,45 @@ static void gpe_writeb(void *opaque, uin
#endif
}
+static uint32_t pcihotplug_read(void *opaque, uint32_t addr)
+{
+ uint32_t val = 0;
+ struct pci_status *g = opaque;
+ switch (addr) {
+ case PCI_BASE:
+ val = g->up;
+ break;
+ case PCI_BASE + 4:
+ val = g->down;
+ break;
+ default:
+ break;
+ }
+
+#if defined(DEBUG)
+ printf("pcihotplug read %lx == %lx\n", addr, val);
+#endif
+ return val;
+}
+
+static void pcihotplug_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ struct pci_status *g = opaque;
+ switch (addr) {
+ case PCI_BASE:
+ g->up = val;
+ break;
+ case PCI_BASE + 4:
+ g->down = val;
+ break;
+ }
+
+#if defined(DEBUG)
+ printf("pcihotplug write %lx <== %d\n", addr, val);
+#endif
+}
+
+
static char *model;
void qemu_system_hot_add_init(char *cpu_model)
@@ -624,6 +670,9 @@ void qemu_system_hot_add_init(char *cpu_
register_ioport_write(PROC_BASE, 4, 1, gpe_writeb, &gpe);
register_ioport_read(PROC_BASE, 4, 1, gpe_readb, &gpe);
+ register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status);
+ register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, &pci0_status);
+
model = cpu_model;
}
@@ -665,3 +714,29 @@ void qemu_system_cpu_hot_add(int cpu, in
disable_processor(&gpe, cpu);
qemu_set_irq(pm_state->irq, 0);
}
+
+static void enable_device(struct pci_status *p, struct gpe_regs *g, int slot)
+{
+ g->sts |= 2;
+ g->en |= 2;
+ p->up |= (1 << slot);
+}
+
+static void disable_device(struct pci_status *p, struct gpe_regs *g, int slot)
+{
+ g->sts |= 2;
+ g->en |= 2;
+ p->down |= (1 << slot);
+}
+
+void qemu_system_device_hot_add(int slot, int state)
+{
+ qemu_set_irq(pm_state->irq, 1);
+ pci0_status.up = 0;
+ pci0_status.down = 0;
+ if (state)
+ enable_device(&pci0_status, &gpe, slot);
+ else
+ disable_device(&pci0_status, &gpe, slot);
+ qemu_set_irq(pm_state->irq, 0);
+}
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 06/24] QEMU/KVM: dynamic drive/drive_opt index allocation
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (4 preceding siblings ...)
2008-03-11 20:11 ` [Qemu-devel] [patch 05/24] QEMU/KVM: pci hotplug GPE support Marcelo Tosatti
@ 2008-03-11 20:11 ` Marcelo Tosatti
2008-03-11 20:11 ` [Qemu-devel] [patch 07/24] QEMU/KVM: dynamic nic info " Marcelo Tosatti
` (18 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:11 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: dynamic-indexing --]
[-- Type: text/plain, Size: 4034 bytes --]
Dynamically allocate drive options and drive table index, so to
reused indexes when devices are removed.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/sysemu.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -139,6 +139,7 @@ typedef struct DriveInfo {
BlockInterfaceType type;
int bus;
int unit;
+ int used;
} DriveInfo;
#define MAX_IDE_DEVS 2
Index: kvm-userspace.hotplug2/qemu/vl.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -254,6 +254,7 @@ int nb_drives_opt;
struct drive_opt {
const char *file;
char opt[1024];
+ int used;
} drives_opt[MAX_DRIVES];
static CPUState *cur_cpu;
@@ -4952,22 +4953,50 @@ void do_info_network(void)
#define MTD_ALIAS "if=mtd"
#define SD_ALIAS "index=0,if=sd"
+static int drive_opt_get_free_idx(void)
+{
+ int index;
+
+ for (index = 0; index < MAX_DRIVES; index++)
+ if (!drives_opt[index].used) {
+ drives_opt[index].used = 1;
+ return index;
+ }
+
+ return -1;
+}
+
+static int drive_get_free_idx(void)
+{
+ int index;
+
+ for (index = 0; index < MAX_DRIVES; index++)
+ if (!drives_table[index].used) {
+ drives_table[index].used = 1;
+ return index;
+ }
+
+ return -1;
+}
+
static int drive_add(const char *file, const char *fmt, ...)
{
va_list ap;
+ int index = drive_opt_get_free_idx();
- if (nb_drives_opt >= MAX_DRIVES) {
+ if (nb_drives_opt >= MAX_DRIVES || index == -1) {
fprintf(stderr, "qemu: too many drives\n");
exit(1);
}
- drives_opt[nb_drives_opt].file = file;
+ drives_opt[index].file = file;
va_start(ap, fmt);
- vsnprintf(drives_opt[nb_drives_opt].opt,
+ vsnprintf(drives_opt[index].opt,
sizeof(drives_opt[0].opt), fmt, ap);
va_end(ap);
- return nb_drives_opt++;
+ nb_drives_opt++;
+ return index;
}
int drive_get_index(BlockInterfaceType type, int bus, int unit)
@@ -4976,10 +5005,11 @@ int drive_get_index(BlockInterfaceType t
/* seek interface, bus and unit */
- for (index = 0; index < nb_drives; index++)
+ for (index = 0; index < MAX_DRIVES; index++)
if (drives_table[index].type == type &&
drives_table[index].bus == bus &&
- drives_table[index].unit == unit)
+ drives_table[index].unit == unit &&
+ drives_table[index].used)
return index;
return -1;
@@ -5015,6 +5045,7 @@ static int drive_init(struct drive_opt *
int index;
int cache;
int bdrv_flags;
+ int drives_table_idx;
char *str = arg->opt;
char *params[] = { "bus", "unit", "if", "index", "cyls", "heads",
"secs", "trans", "media", "snapshot", "file",
@@ -5266,10 +5297,11 @@ static int drive_init(struct drive_opt *
snprintf(buf, sizeof(buf), "%s%s%i",
devname, mediastr, unit_id);
bdrv = bdrv_new(buf);
- drives_table[nb_drives].bdrv = bdrv;
- drives_table[nb_drives].type = type;
- drives_table[nb_drives].bus = bus_id;
- drives_table[nb_drives].unit = unit_id;
+ drives_table_idx = drive_get_free_idx();
+ drives_table[drives_table_idx].bdrv = bdrv;
+ drives_table[drives_table_idx].type = type;
+ drives_table[drives_table_idx].bus = bus_id;
+ drives_table[drives_table_idx].unit = unit_id;
nb_drives++;
switch(type) {
@@ -9578,8 +9610,10 @@ int main(int argc, char **argv)
if (nb_drives_opt < MAX_DRIVES)
drive_add(NULL, SD_ALIAS);
- /* open the virtual block devices */
-
+ /* open the virtual block devices
+ * note that migration with device
+ * hot add/remove is broken.
+ */
for(i = 0; i < nb_drives_opt; i++)
if (drive_init(&drives_opt[i], snapshot, machine) == -1)
exit(1);
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 07/24] QEMU/KVM: dynamic nic info index allocation
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (5 preceding siblings ...)
2008-03-11 20:11 ` [Qemu-devel] [patch 06/24] QEMU/KVM: dynamic drive/drive_opt index allocation Marcelo Tosatti
@ 2008-03-11 20:11 ` Marcelo Tosatti
2008-03-11 20:11 ` [Qemu-devel] [patch 08/24] QEMU/KVM: drive removal support Marcelo Tosatti
` (17 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:11 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: net-dynamic-idx --]
[-- Type: text/plain, Size: 1936 bytes --]
The same, but for nics.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/net.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/net.h
+++ kvm-userspace.hotplug2/qemu/net.h
@@ -46,6 +46,7 @@ struct NICInfo {
const char *model;
VLANState *vlan;
int devfn;
+ int used;
};
extern int nb_nics;
Index: kvm-userspace.hotplug2/qemu/vl.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -4791,6 +4791,15 @@ static int check_params(char *buf, int b
return 0;
}
+static int nic_get_free_idx(void)
+{
+ int index;
+
+ for (index = 0; index < MAX_NICS; index++)
+ if (!nd_table[index].used)
+ return index;
+ return -1;
+}
static int net_client_init(const char *str)
{
@@ -4823,19 +4832,20 @@ static int net_client_init(const char *s
if (!strcmp(device, "nic")) {
NICInfo *nd;
uint8_t *macaddr;
+ int idx = nic_get_free_idx();
- if (nb_nics >= MAX_NICS) {
+ if (idx == -1 || nb_nics >= MAX_NICS) {
fprintf(stderr, "Too Many NICs\n");
return -1;
}
- nd = &nd_table[nb_nics];
+ nd = &nd_table[idx];
macaddr = nd->macaddr;
macaddr[0] = 0x52;
macaddr[1] = 0x54;
macaddr[2] = 0x00;
macaddr[3] = 0x12;
macaddr[4] = 0x34;
- macaddr[5] = 0x56 + nb_nics;
+ macaddr[5] = 0x56 + idx;
if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
if (parse_macaddr(macaddr, buf) < 0) {
@@ -4847,6 +4857,7 @@ static int net_client_init(const char *s
nd->model = strdup(buf);
}
nd->vlan = vlan;
+ nd->used = 1;
nb_nics++;
vlan->nb_guest_devs++;
ret = 0;
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 08/24] QEMU/KVM: drive removal support
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (6 preceding siblings ...)
2008-03-11 20:11 ` [Qemu-devel] [patch 07/24] QEMU/KVM: dynamic nic info " Marcelo Tosatti
@ 2008-03-11 20:11 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 09/24] QEMU/KVM: record devfn on block driver instance Marcelo Tosatti
` (16 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:11 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: device-removal --]
[-- Type: text/plain, Size: 2131 bytes --]
To be used by hot-remove.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/vl.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -5010,6 +5010,12 @@ static int drive_add(const char *file, c
return index;
}
+void drive_remove(int index)
+{
+ drives_opt[index].used = 0;
+ nb_drives_opt--;
+}
+
int drive_get_index(BlockInterfaceType type, int bus, int unit)
{
int index;
@@ -5040,6 +5046,20 @@ int drive_get_max_bus(BlockInterfaceType
return max_bus;
}
+void drive_uninit(BlockDriverState *bdrv)
+{
+ int i;
+
+ for (i = 0; i < MAX_DRIVES; i++)
+ if (drives_table[i].bdrv == bdrv) {
+ drives_table[i].bdrv = NULL;
+ drives_table[i].used = 0;
+ drive_remove(drives_table[i].drive_opt_idx);
+ nb_drives--;
+ break;
+ }
+}
+
static int drive_init(struct drive_opt *arg, int snapshot,
QEMUMachine *machine)
{
@@ -5313,6 +5333,7 @@ static int drive_init(struct drive_opt *
drives_table[drives_table_idx].type = type;
drives_table[drives_table_idx].bus = bus_id;
drives_table[drives_table_idx].unit = unit_id;
+ drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
nb_drives++;
switch(type) {
Index: kvm-userspace.hotplug2/qemu/sysemu.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -140,6 +140,7 @@ typedef struct DriveInfo {
int bus;
int unit;
int used;
+ int drive_opt_idx;
} DriveInfo;
#define MAX_IDE_DEVS 2
@@ -153,6 +154,9 @@ int extboot_drive;
extern int drive_get_index(BlockInterfaceType type, int bus, int unit);
extern int drive_get_max_bus(BlockInterfaceType type);
+extern void drive_uninit(BlockDriverState *bdrv);
+extern void drive_remove(int index);
+
/* acpi */
void qemu_system_cpu_hot_add(int cpu, int state);
void qemu_system_hot_add_init(char *cpu_model);
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 09/24] QEMU/KVM: record devfn on block driver instance
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (7 preceding siblings ...)
2008-03-11 20:11 ` [Qemu-devel] [patch 08/24] QEMU/KVM: drive removal support Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 10/24] QEMU/KVM: move drives_opt for external use Marcelo Tosatti
` (15 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: pci-info --]
[-- Type: text/plain, Size: 2869 bytes --]
Record devfn on the BlockDriverState structure to locate for release
on hot-removal.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/block_int.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/block_int.h
+++ kvm-userspace.hotplug2/qemu/block_int.h
@@ -129,6 +129,8 @@ struct BlockDriverState {
int cyls, heads, secs, translation;
int type;
char device_name[32];
+ /* PCI devfn of parent */
+ int devfn;
BlockDriverState *next;
};
Index: kvm-userspace.hotplug2/qemu/hw/lsi53c895a.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/lsi53c895a.c
+++ kvm-userspace.hotplug2/qemu/hw/lsi53c895a.c
@@ -13,6 +13,7 @@
#include "hw.h"
#include "pci.h"
#include "scsi-disk.h"
+#include "block_int.h"
//#define DEBUG_LSI
//#define DEBUG_LSI_REG
@@ -1845,6 +1846,7 @@ void lsi_scsi_attach(void *opaque, Block
s->scsi_dev[id] = scsi_generic_init(bd, 1, lsi_command_complete, s);
if (s->scsi_dev[id] == NULL)
s->scsi_dev[id] = scsi_disk_init(bd, 1, lsi_command_complete, s);
+ bd->devfn = s->pci_dev.devfn;
}
void *lsi_scsi_init(PCIBus *bus, int devfn)
Index: kvm-userspace.hotplug2/qemu/hw/virtio-blk.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/virtio-blk.c
+++ kvm-userspace.hotplug2/qemu/hw/virtio-blk.c
@@ -13,6 +13,7 @@
#include "virtio.h"
#include "block.h"
+#include "block_int.h"
#include "pc.h"
/* from Linux's linux/virtio_blk.h */
@@ -156,6 +157,7 @@ void *virtio_blk_init(PCIBus *bus, uint1
s->vdev.update_config = virtio_blk_update_config;
s->vdev.get_features = virtio_blk_get_features;
s->bs = bs;
+ bs->devfn = s->vdev.pci_dev.devfn;
virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
Index: kvm-userspace.hotplug2/qemu/hw/ide.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/ide.c
+++ kvm-userspace.hotplug2/qemu/hw/ide.c
@@ -28,6 +28,7 @@
#include "scsi-disk.h"
#include "pcmcia.h"
#include "block.h"
+#include "block_int.h"
#include "qemu-timer.h"
#include "sysemu.h"
#include "ppc_mac.h"
@@ -2938,6 +2939,7 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
{
PCIIDEState *d;
uint8_t *pci_conf;
+ int i;
/* register a function 1 of PIIX3 */
d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
@@ -2966,6 +2968,10 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+ for (i = 0; i < 4; i++)
+ if (hd_table[i])
+ hd_table[i]->devfn = d->dev.devfn;
+
register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
}
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 10/24] QEMU/KVM: move drives_opt for external use
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (8 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 09/24] QEMU/KVM: record devfn on block driver instance Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 11/24] QEMU/KVM: net/drive add/remove tweaks Marcelo Tosatti
` (14 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: drive_opt --]
[-- Type: text/plain, Size: 1259 bytes --]
Device hotplug will use that structure from a separate
file.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/sysemu.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -157,6 +157,15 @@ extern int drive_get_max_bus(BlockInterf
extern void drive_uninit(BlockDriverState *bdrv);
extern void drive_remove(int index);
+struct drive_opt {
+ const char *file;
+ char opt[1024];
+ int used;
+};
+
+extern struct drive_opt drives_opt[MAX_DRIVES];
+extern int nb_drives_opt;
+
/* acpi */
void qemu_system_cpu_hot_add(int cpu, int state);
void qemu_system_hot_add_init(char *cpu_model);
Index: kvm-userspace.hotplug2/qemu/vl.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -251,11 +251,7 @@ unsigned int nb_prom_envs = 0;
const char *prom_envs[MAX_PROM_ENVS];
#endif
int nb_drives_opt;
-struct drive_opt {
- const char *file;
- char opt[1024];
- int used;
-} drives_opt[MAX_DRIVES];
+struct drive_opt drives_opt[MAX_DRIVES];
static CPUState *cur_cpu;
static CPUState *next_cpu;
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 11/24] QEMU/KVM: net/drive add/remove tweaks
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (9 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 10/24] QEMU/KVM: move drives_opt for external use Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 12/24] QEMU/KVM: add net_client_uninit Marcelo Tosatti
` (13 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: drive_init_ret --]
[-- Type: text/plain, Size: 3355 bytes --]
Export net/drive add/remove functions for device hotplug usage.
Return the table index on add.
Return failure instead of exiting if limit has been reached
on drive_add.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/vl.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -4797,7 +4797,7 @@ static int nic_get_free_idx(void)
return -1;
}
-static int net_client_init(const char *str)
+int net_client_init(const char *str)
{
const char *p;
char *q;
@@ -4856,7 +4856,7 @@ static int net_client_init(const char *s
nd->used = 1;
nb_nics++;
vlan->nb_guest_devs++;
- ret = 0;
+ ret = idx;
} else
if (!strcmp(device, "none")) {
/* does nothing. It is needed to signal that no network cards
@@ -4986,14 +4986,14 @@ static int drive_get_free_idx(void)
return -1;
}
-static int drive_add(const char *file, const char *fmt, ...)
+int drive_add(const char *file, const char *fmt, ...)
{
va_list ap;
int index = drive_opt_get_free_idx();
if (nb_drives_opt >= MAX_DRIVES || index == -1) {
fprintf(stderr, "qemu: too many drives\n");
- exit(1);
+ return -1;
}
drives_opt[index].file = file;
@@ -5056,9 +5056,10 @@ void drive_uninit(BlockDriverState *bdrv
}
}
-static int drive_init(struct drive_opt *arg, int snapshot,
- QEMUMachine *machine)
+int drive_init(struct drive_opt *arg, int snapshot,
+ void *opaque)
{
+ QEMUMachine *machine = opaque;
char buf[128];
char file[1024];
char devname[128];
@@ -5311,7 +5312,7 @@ static int drive_init(struct drive_opt *
*/
if (drive_get_index(type, bus_id, unit_id) != -1)
- return 0;
+ return -2;
/* init */
@@ -5359,7 +5360,7 @@ static int drive_init(struct drive_opt *
break;
}
if (!file[0])
- return 0;
+ return -2;
bdrv_flags = 0;
if (snapshot)
bdrv_flags |= BDRV_O_SNAPSHOT;
@@ -5370,7 +5371,7 @@ static int drive_init(struct drive_opt *
file);
return -1;
}
- return 0;
+ return drives_table_idx;
}
/***********************************************************/
Index: kvm-userspace.hotplug2/qemu/net.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/net.h
+++ kvm-userspace.hotplug2/qemu/net.h
@@ -37,6 +37,8 @@ void do_info_network(void);
/* virtio hack for zero copy receive */
int hack_around_tap(void *opaque);
+int net_client_init(const char *str);
+
/* NIC info */
#define MAX_NICS 8
Index: kvm-userspace.hotplug2/qemu/sysemu.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -166,6 +166,9 @@ struct drive_opt {
extern struct drive_opt drives_opt[MAX_DRIVES];
extern int nb_drives_opt;
+extern int drive_add(const char *file, const char *fmt, ...);
+extern int drive_init(struct drive_opt *arg, int snapshot, void *machine);
+
/* acpi */
void qemu_system_cpu_hot_add(int cpu, int state);
void qemu_system_hot_add_init(char *cpu_model);
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 12/24] QEMU/KVM: add net_client_uninit
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (10 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 11/24] QEMU/KVM: net/drive add/remove tweaks Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 13/24] QEMU/KVM: export get_param_value/check_params Marcelo Tosatti
` (12 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: net-dev-removal --]
[-- Type: text/plain, Size: 925 bytes --]
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/net.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/net.h
+++ kvm-userspace.hotplug2/qemu/net.h
@@ -38,6 +38,7 @@ void do_info_network(void);
int hack_around_tap(void *opaque);
int net_client_init(const char *str);
+void net_client_uninit(NICInfo *nd);
/* NIC info */
Index: kvm-userspace.hotplug2/qemu/vl.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -4937,6 +4937,14 @@ int net_client_init(const char *str)
return ret;
}
+void net_client_uninit(NICInfo *nd)
+{
+ nd->vlan->nb_guest_devs--; /* XXX: free vlan on last reference */
+ nb_nics--;
+ nd->used = 0;
+ free(nd->model);
+}
+
void do_info_network(void)
{
VLANState *vlan;
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 13/24] QEMU/KVM: export get_param_value/check_params
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (11 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 12/24] QEMU/KVM: add net_client_uninit Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 14/24] QEMU/KVM: add pci_find_device Marcelo Tosatti
` (11 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: export-getparams --]
[-- Type: text/plain, Size: 1470 bytes --]
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/sysemu.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -57,6 +57,10 @@ int qemu_live_loadvm_state(QEMUFile *f);
void main_loop_wait(int timeout);
+int check_params(char *buf, int buf_size, char **params, const char *str);
+int get_param_value(char *buf, int buf_size, const char *tag,
+ const char *str);
+
/* Polling handling */
/* return TRUE if no sleep should be done afterwards */
Index: kvm-userspace.hotplug2/qemu/vl.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -4737,8 +4737,8 @@ static const char *get_opt_value(char *b
return p;
}
-static int get_param_value(char *buf, int buf_size,
- const char *tag, const char *str)
+int get_param_value(char *buf, int buf_size,
+ const char *tag, const char *str)
{
const char *p;
char option[128];
@@ -4762,8 +4762,8 @@ static int get_param_value(char *buf, in
return 0;
}
-static int check_params(char *buf, int buf_size,
- char **params, const char *str)
+int check_params(char *buf, int buf_size,
+ char **params, const char *str)
{
const char *p;
int i;
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 14/24] QEMU/KVM: add pci_find_device
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (12 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 13/24] QEMU/KVM: export get_param_value/check_params Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 15/24] QEMU/KVM: virtio_blk_init return PCIDevice pointer Marcelo Tosatti
` (10 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: pci-find-device --]
[-- Type: text/plain, Size: 1386 bytes --]
Return PCIDevice from bus number and slot.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug/qemu/hw/pci.c
===================================================================
--- kvm-userspace.hotplug.orig/qemu/hw/pci.c
+++ kvm-userspace.hotplug/qemu/hw/pci.c
@@ -689,6 +689,23 @@ PCIBus *pci_find_bus(int bus_num)
return bus;
}
+PCIDevice *pci_find_device(int bus_num, int slot)
+{
+ int devfn;
+ PCIDevice *d;
+ PCIBus *bus = pci_find_bus(bus_num);
+
+ if (!bus)
+ return NULL;
+
+ for(devfn = 0; devfn < 256; devfn++) {
+ d = bus->devices[devfn];
+ if (d && PCI_SLOT(devfn) == slot)
+ return d;
+ }
+ return NULL;
+}
+
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
pci_map_irq_fn map_irq, const char *name)
{
Index: kvm-userspace.hotplug/qemu/hw/pci.h
===================================================================
--- kvm-userspace.hotplug.orig/qemu/hw/pci.h
+++ kvm-userspace.hotplug/qemu/hw/pci.h
@@ -93,6 +93,7 @@ uint32_t pci_data_read(void *opaque, uin
int pci_bus_num(PCIBus *s);
void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
PCIBus *pci_find_bus(int bus_num);
+PCIDevice *pci_find_device(int bus_num, int slot);
void pci_info(void);
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 15/24] QEMU/KVM: virtio_blk_init return PCIDevice pointer
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (13 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 14/24] QEMU/KVM: add pci_find_device Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 16/24] QEMU/KVM: device and disk hot-add Marcelo Tosatti
` (9 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: virtio-blk --]
[-- Type: text/plain, Size: 448 bytes --]
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/hw/virtio-blk.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/virtio-blk.c
+++ kvm-userspace.hotplug2/qemu/hw/virtio-blk.c
@@ -161,5 +161,5 @@ void *virtio_blk_init(PCIBus *bus, uint1
virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
- return &s->vdev;
+ return s;
}
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 16/24] QEMU/KVM: device and disk hot-add
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (14 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 15/24] QEMU/KVM: virtio_blk_init return PCIDevice pointer Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 17/24] QEMU/KVM: add cpu_unregister_io_memory and make io mem table index dynamic Marcelo Tosatti
` (8 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: monitor --]
[-- Type: text/plain, Size: 8247 bytes --]
Add monitor command to hot-add PCI devices (nic and storage).
Syntax is:
pci_add pcibus nic|storage params
It returns the bus slot and function for the newly added device on success.
It is possible to attach a disk to a device after PCI initialization via
the drive_add command. If so, a manual scan of the SCSI bus on the guest
is necessary.
Save QEMUMachine necessary for drive_init.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/Makefile.target
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/Makefile.target
+++ kvm-userspace.hotplug2/qemu/Makefile.target
@@ -579,6 +579,8 @@ OBJS+= hypercall.o
# virtio devices
OBJS += virtio.o virtio-net.o virtio-blk.o
+OBJS += device-hotplug.o
+
ifeq ($(TARGET_BASE_ARCH), i386)
# Hardware support
OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
Index: kvm-userspace.hotplug2/qemu/hw/device-hotplug.c
===================================================================
--- /dev/null
+++ kvm-userspace.hotplug2/qemu/hw/device-hotplug.c
@@ -0,0 +1,158 @@
+#include "hw.h"
+#include "boards.h"
+#include "pci.h"
+#include "net.h"
+#include "sysemu.h"
+#include "pc.h"
+#include "console.h"
+
+static PCIDevice *qemu_system_hot_add_nic(const char *opts, int bus_nr)
+{
+ int ret;
+ char buf[4096];
+ PCIBus *pci_bus;
+
+ pci_bus = pci_find_bus (bus_nr);
+ if (!pci_bus) {
+ term_printf ("Can't find pci_bus %d\n", bus_nr);
+ return NULL;
+ }
+
+ memset (buf, 0, sizeof (buf));
+
+ strcpy (buf, "nic,");
+ strncat (buf, opts, sizeof (buf) - strlen (buf) - 1);
+
+ ret = net_client_init (buf);
+ if (ret < 0 || !nd_table[ret].model)
+ return NULL;
+ return pci_nic_init (pci_bus, &nd_table[ret], -1);
+}
+
+static int add_init_drive(const char *opts)
+{
+ int drive_opt_idx, drive_idx;
+ int ret = -1;
+
+ drive_opt_idx = drive_add(NULL, "%s", opts);
+ if (!drive_opt_idx)
+ return ret;
+
+ drive_idx = drive_init(&drives_opt[drive_opt_idx], 0, current_machine);
+ if (drive_idx == -1) {
+ drive_remove(drive_opt_idx);
+ return ret;
+ }
+
+ return drive_idx;
+}
+
+void drive_hot_add(int pcibus, const char *devfn_string, const char *opts)
+{
+ int drive_idx, type, bus;
+ int devfn;
+ int success = 0;
+ PCIDevice *dev;
+
+ devfn = strtoul(devfn_string, NULL, 0);
+
+ dev = pci_find_device(pcibus, PCI_SLOT(devfn));
+ if (!dev) {
+ term_printf("no pci device with devfn %d (slot %d)\n", devfn,
+ PCI_SLOT(devfn));
+ return;
+ }
+
+ drive_idx = add_init_drive(opts);
+ if (drive_idx < 0)
+ return;
+ type = drives_table[drive_idx].type;
+ bus = drive_get_max_bus (type);
+
+ switch (type) {
+ case IF_SCSI:
+ success = 1;
+ lsi_scsi_attach (dev, drives_table[drive_idx].bdrv,
+ drives_table[drive_idx].unit);
+ break;
+ default:
+ term_printf("Can't hot-add drive to type %d\n", type);
+ }
+
+ if (success)
+ term_printf("OK bus %d, unit %d\n", drives_table[drive_idx].bus,
+ drives_table[drive_idx].unit);
+ return;
+}
+
+static PCIDevice *qemu_system_hot_add_storage(const char *opts, int bus_nr)
+{
+ void *opaque = NULL;
+ PCIBus *pci_bus;
+ int type = -1, drive_idx = -1;
+ char buf[128];
+
+ pci_bus = pci_find_bus(bus_nr);
+ if (!pci_bus) {
+ term_printf("Can't find pci_bus %d\n", bus_nr);
+ return NULL;
+ }
+
+ if (get_param_value(buf, sizeof(buf), "if", opts)) {
+ if (!strcmp(buf, "scsi"))
+ type = IF_SCSI;
+ else if (!strcmp(buf, "virtio")) {
+ type = IF_VIRTIO;
+ }
+ } else {
+ term_printf("no if= specified\n");
+ return NULL;
+ }
+
+ if (get_param_value(buf, sizeof(buf), "file", opts)) {
+ drive_idx = add_init_drive(opts);
+ if (drive_idx < 0)
+ return NULL;
+ } else if (type == IF_VIRTIO) {
+ term_printf("virtio requires a backing file/device.\n");
+ return NULL;
+ }
+
+ switch (type) {
+ case IF_SCSI:
+ opaque = lsi_scsi_init (pci_bus, -1);
+ if (drive_idx >= 0)
+ lsi_scsi_attach (opaque, drives_table[drive_idx].bdrv,
+ drives_table[drive_idx].unit);
+ break;
+ case IF_VIRTIO:
+ opaque = virtio_blk_init (pci_bus, 0x1AF4, 0x1001,
+ drives_table[drive_idx].bdrv);
+ break;
+ default:
+ term_printf ("type %s not a hotpluggable PCI device.\n", buf);
+ }
+
+ return opaque;
+}
+
+void device_hot_add(int pcibus, const char *type, const char *opts)
+{
+ PCIDevice *dev = NULL;
+
+ if (strcmp(type, "nic") == 0)
+ dev = qemu_system_hot_add_nic(opts, pcibus);
+ else if (strcmp(type, "storage") == 0)
+ dev = qemu_system_hot_add_storage(opts, pcibus);
+ else
+ term_printf("invalid type: %s\n", type);
+
+ if (dev) {
+ qemu_system_device_hot_add(PCI_SLOT(dev->devfn), 1);
+ term_printf("OK bus %d, slot %d, function %d (devfn %d)\n",
+ pci_bus_num(dev->bus), PCI_SLOT(dev->devfn),
+ PCI_FUNC(dev->devfn), dev->devfn);
+ } else
+ term_printf("failed to add %s\n", opts);
+}
+
Index: kvm-userspace.hotplug2/qemu/monitor.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/monitor.c
+++ kvm-userspace.hotplug2/qemu/monitor.c
@@ -1359,6 +1359,12 @@ static term_cmd_t term_cmds[] = {
{ "migrate_set_speed", "s", do_migrate_set_speed,
"value", "set maximum speed (in bytes) for migrations" },
{ "cpu_set", "is", do_cpu_set_nr, "cpu [online|offline]", "change cpu state" },
+ { "drive_add", "iss", drive_hot_add, "pcibus pcidevfn [file=file][,if=type][,bus=n]\n"
+ "[,unit=m][,media=d][index=i]\n"
+ "[,cyls=c,heads=h,secs=s[,trans=t]]\n"
+ "[snapshot=on|off][,cache=on|off]",
+ "add drive to PCI storage controller" },
+ { "pci_add", "iss", device_hot_add, "bus nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]...", "hot-add PCI device" },
{ NULL, NULL, },
};
Index: kvm-userspace.hotplug2/qemu/hw/boards.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/boards.h
+++ kvm-userspace.hotplug2/qemu/hw/boards.h
@@ -19,6 +19,8 @@ typedef struct QEMUMachine {
int qemu_register_machine(QEMUMachine *m);
+extern QEMUMachine *current_machine;
+
/* Axis ETRAX. */
extern QEMUMachine bareetraxfs_machine;
Index: kvm-userspace.hotplug2/qemu/sysemu.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -176,6 +176,11 @@ extern int drive_init(struct drive_opt *
/* acpi */
void qemu_system_cpu_hot_add(int cpu, int state);
void qemu_system_hot_add_init(char *cpu_model);
+void qemu_system_device_hot_add(int slot, int state);
+
+/* device-hotplug */
+void device_hot_add(int pcibus, const char *type, const char *opts);
+void drive_hot_add(int pcibus, const char *devfn_string, const char *opts);
/* vmchannel devices */
Index: kvm-userspace.hotplug2/qemu/vl.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -7610,6 +7610,7 @@ void qemu_bh_delete(QEMUBH *bh)
/* machine registration */
QEMUMachine *first_machine = NULL;
+QEMUMachine *current_machine = NULL;
int qemu_register_machine(QEMUMachine *m)
{
@@ -9767,6 +9768,8 @@ int main(int argc, char **argv)
machine->init(ram_size, vga_ram_size, boot_devices, ds,
kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
+ current_machine = machine;
+
/* init USB devices */
if (usb_enabled) {
for(i = 0; i < usb_devices_index; i++) {
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 17/24] QEMU/KVM: add cpu_unregister_io_memory and make io mem table index dynamic
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (15 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 16/24] QEMU/KVM: device and disk hot-add Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-18 12:32 ` [Qemu-devel] Re: [kvm-devel] " Amit Shah
2008-03-11 20:12 ` [Qemu-devel] [patch 18/24] QEMU/KVM: notify _EJ0 through _SEJ OperationRegion Marcelo Tosatti
` (7 subsequent siblings)
24 siblings, 1 reply; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: mem-io-unregister --]
[-- Type: text/plain, Size: 3142 bytes --]
So drivers can clear their mem io table entries on exit back to unassigned
state.
Also make the io mem index allocation dynamic.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/cpu-all.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/cpu-all.h
+++ kvm-userspace.hotplug2/qemu/cpu-all.h
@@ -837,6 +837,7 @@ int cpu_register_io_memory(int io_index,
CPUReadMemoryFunc **mem_read,
CPUWriteMemoryFunc **mem_write,
void *opaque);
+void cpu_unregister_io_memory(int table_address);
CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
Index: kvm-userspace.hotplug2/qemu/exec.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/exec.c
+++ kvm-userspace.hotplug2/qemu/exec.c
@@ -158,7 +158,7 @@ PhysPageDesc **l1_phys_map;
CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-static int io_mem_nb;
+char io_mem_used[IO_MEM_NB_ENTRIES];
#if defined(CONFIG_SOFTMMU)
static int io_mem_watch;
#endif
@@ -2498,12 +2498,28 @@ static void *subpage_init (target_phys_a
return mmio;
}
+static int get_free_io_mem_idx(void)
+{
+ int i;
+
+ for (i = 0; i<IO_MEM_NB_ENTRIES; i++)
+ if (!io_mem_used[i]) {
+ io_mem_used[i] = 1;
+ return i;
+ }
+
+ return -1;
+}
+
static void io_mem_init(void)
{
+ int i;
+
cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read, unassigned_mem_write, NULL);
cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, notdirty_mem_write, NULL);
- io_mem_nb = 5;
+ for (i=0; i<5; i++)
+ io_mem_used[i] = 0;
#if defined(CONFIG_SOFTMMU)
io_mem_watch = cpu_register_io_memory(-1, watch_mem_read,
@@ -2530,9 +2546,9 @@ int cpu_register_io_memory(int io_index,
int i, subwidth = 0;
if (io_index <= 0) {
- if (io_mem_nb >= IO_MEM_NB_ENTRIES)
- return -1;
- io_index = io_mem_nb++;
+ io_index = get_free_io_mem_idx();
+ if (io_index == -1)
+ return io_index;
} else {
if (io_index >= IO_MEM_NB_ENTRIES)
return -1;
@@ -2548,6 +2564,19 @@ int cpu_register_io_memory(int io_index,
return (io_index << IO_MEM_SHIFT) | subwidth;
}
+void cpu_unregister_io_memory(int io_table_address)
+{
+ int i;
+ int io_index = io_table_address >> IO_MEM_SHIFT;
+
+ for (i=0;i < 3; i++) {
+ io_mem_read[io_index][i] = unassigned_mem_read[i];
+ io_mem_write[io_index][i] = unassigned_mem_write[i];
+ }
+ io_mem_opaque[io_index] = NULL;
+ io_mem_used[io_index] = 0;
+}
+
CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
{
return io_mem_write[io_index >> IO_MEM_SHIFT];
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] Re: [kvm-devel] [patch 17/24] QEMU/KVM: add cpu_unregister_io_memory and make io mem table index dynamic
2008-03-11 20:12 ` [Qemu-devel] [patch 17/24] QEMU/KVM: add cpu_unregister_io_memory and make io mem table index dynamic Marcelo Tosatti
@ 2008-03-18 12:32 ` Amit Shah
2008-03-18 13:54 ` Marcelo Tosatti
0 siblings, 1 reply; 30+ messages in thread
From: Amit Shah @ 2008-03-18 12:32 UTC (permalink / raw)
To: kvm-devel; +Cc: Avi Kivity, Marcelo Tosatti, qemu-devel
This patch broke -no-kvm-irqchip:
* On Wednesday 12 March 2008 01:42:08 Marcelo Tosatti wrote:
> So drivers can clear their mem io table entries on exit back to unassigned
> state.
>
> Also make the io mem index allocation dynamic.
>
> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
>
> Index: kvm-userspace.hotplug2/qemu/cpu-all.h
> ===================================================================
> --- kvm-userspace.hotplug2.orig/qemu/cpu-all.h
> +++ kvm-userspace.hotplug2/qemu/cpu-all.h
> @@ -837,6 +837,7 @@ int cpu_register_io_memory(int io_index,
> CPUReadMemoryFunc **mem_read,
> CPUWriteMemoryFunc **mem_write,
> void *opaque);
> +void cpu_unregister_io_memory(int table_address);
> CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
> CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
>
> Index: kvm-userspace.hotplug2/qemu/exec.c
> ===================================================================
> --- kvm-userspace.hotplug2.orig/qemu/exec.c
> +++ kvm-userspace.hotplug2/qemu/exec.c
> @@ -158,7 +158,7 @@ PhysPageDesc **l1_phys_map;
> CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
> CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
> void *io_mem_opaque[IO_MEM_NB_ENTRIES];
> -static int io_mem_nb;
> +char io_mem_used[IO_MEM_NB_ENTRIES];
> #if defined(CONFIG_SOFTMMU)
> static int io_mem_watch;
> #endif
> @@ -2498,12 +2498,28 @@ static void *subpage_init (target_phys_a
> return mmio;
> }
>
> +static int get_free_io_mem_idx(void)
> +{
> + int i;
> +
> + for (i = 0; i<IO_MEM_NB_ENTRIES; i++)
> + if (!io_mem_used[i]) {
> + io_mem_used[i] = 1;
> + return i;
> + }
> +
> + return -1;
> +}
> +
> static void io_mem_init(void)
> {
> + int i;
> +
> cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read,
> unassigned_mem_write, NULL); cpu_register_io_memory(IO_MEM_UNASSIGNED >>
> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
> cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read,
> notdirty_mem_write, NULL); - io_mem_nb = 5;
> + for (i=0; i<5; i++)
> + io_mem_used[i] = 0;
The remaining bits (5..IO_MEM_NB_ENTRIES) aren't initialised.
>
> #if defined(CONFIG_SOFTMMU)
> io_mem_watch = cpu_register_io_memory(-1, watch_mem_read,
> @@ -2530,9 +2546,9 @@ int cpu_register_io_memory(int io_index,
> int i, subwidth = 0;
>
> if (io_index <= 0) {
> - if (io_mem_nb >= IO_MEM_NB_ENTRIES)
> - return -1;
> - io_index = io_mem_nb++;
> + io_index = get_free_io_mem_idx();
> + if (io_index == -1)
> + return io_index;
io_mem_nb was initialised to 5 earlier; we now trample over the first 0..4
bits.
This fixes the issue; please check for correctness.
From: Amit Shah <amit.shah@qumranet.com>
Date: Tue, 18 Mar 2008 18:01:05 +0530
Subject: [PATCH] QEMU/KVM: fix initialization of IO memory regions
Signed-off-by: Amit Shah <amit.shah@qumranet.com>
---
qemu/exec.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/qemu/exec.c b/qemu/exec.c
index edeb21a..be15433 100644
--- a/qemu/exec.c
+++ b/qemu/exec.c
@@ -2502,7 +2502,7 @@ static int get_free_io_mem_idx(void)
{
int i;
- for (i = 0; i<IO_MEM_NB_ENTRIES; i++)
+ for (i = 5; i<IO_MEM_NB_ENTRIES; i++)
if (!io_mem_used[i]) {
io_mem_used[i] = 1;
return i;
@@ -2518,7 +2518,7 @@ static void io_mem_init(void)
cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read,
unassigned_mem_write, NULL);
cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT,
unassigned_mem_read, unassigned_mem_write, NULL);
cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read,
notdirty_mem_write, NULL);
- for (i=0; i<5; i++)
+ for (i=5; i<IO_MEM_NB_ENTRIES; i++)
io_mem_used[i] = 0;
#if defined(CONFIG_SOFTMMU)
--
1.4.4.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [Qemu-devel] Re: [kvm-devel] [patch 17/24] QEMU/KVM: add cpu_unregister_io_memory and make io mem table index dynamic
2008-03-18 12:32 ` [Qemu-devel] Re: [kvm-devel] " Amit Shah
@ 2008-03-18 13:54 ` Marcelo Tosatti
2008-03-18 14:13 ` [Qemu-devel] " Amit Shah
0 siblings, 1 reply; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-18 13:54 UTC (permalink / raw)
To: Amit Shah; +Cc: kvm-devel, Avi Kivity, qemu-devel
On Tue, Mar 18, 2008 at 06:02:10PM +0530, Amit Shah wrote:
> This patch broke -no-kvm-irqchip:
>
> * On Wednesday 12 March 2008 01:42:08 Marcelo Tosatti wrote:
> > So drivers can clear their mem io table entries on exit back to unassigned
> > state.
> >
> > Also make the io mem index allocation dynamic.
> >
> > Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
> >
> > Index: kvm-userspace.hotplug2/qemu/cpu-all.h
> > ===================================================================
> > --- kvm-userspace.hotplug2.orig/qemu/cpu-all.h
> > +++ kvm-userspace.hotplug2/qemu/cpu-all.h
> > @@ -837,6 +837,7 @@ int cpu_register_io_memory(int io_index,
> > CPUReadMemoryFunc **mem_read,
> > CPUWriteMemoryFunc **mem_write,
> > void *opaque);
> > +void cpu_unregister_io_memory(int table_address);
> > CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
> > CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
> >
> > Index: kvm-userspace.hotplug2/qemu/exec.c
> > ===================================================================
> > --- kvm-userspace.hotplug2.orig/qemu/exec.c
> > +++ kvm-userspace.hotplug2/qemu/exec.c
> > @@ -158,7 +158,7 @@ PhysPageDesc **l1_phys_map;
> > CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
> > CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
> > void *io_mem_opaque[IO_MEM_NB_ENTRIES];
> > -static int io_mem_nb;
> > +char io_mem_used[IO_MEM_NB_ENTRIES];
> > #if defined(CONFIG_SOFTMMU)
> > static int io_mem_watch;
> > #endif
> > @@ -2498,12 +2498,28 @@ static void *subpage_init (target_phys_a
> > return mmio;
> > }
> >
> > +static int get_free_io_mem_idx(void)
> > +{
> > + int i;
> > +
> > + for (i = 0; i<IO_MEM_NB_ENTRIES; i++)
> > + if (!io_mem_used[i]) {
> > + io_mem_used[i] = 1;
> > + return i;
> > + }
> > +
> > + return -1;
> > +}
> > +
> > static void io_mem_init(void)
> > {
> > + int i;
> > +
> > cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read,
> > unassigned_mem_write, NULL); cpu_register_io_memory(IO_MEM_UNASSIGNED >>
> > IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
> > cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read,
> > notdirty_mem_write, NULL); - io_mem_nb = 5;
> > + for (i=0; i<5; i++)
> > + io_mem_used[i] = 0;
>
> The remaining bits (5..IO_MEM_NB_ENTRIES) aren't initialised.
>
> >
> > #if defined(CONFIG_SOFTMMU)
> > io_mem_watch = cpu_register_io_memory(-1, watch_mem_read,
> > @@ -2530,9 +2546,9 @@ int cpu_register_io_memory(int io_index,
> > int i, subwidth = 0;
> >
> > if (io_index <= 0) {
> > - if (io_mem_nb >= IO_MEM_NB_ENTRIES)
> > - return -1;
> > - io_index = io_mem_nb++;
> > + io_index = get_free_io_mem_idx();
> > + if (io_index == -1)
> > + return io_index;
>
> io_mem_nb was initialised to 5 earlier; we now trample over the first 0..4
> bits.
>
> This fixes the issue; please check for correctness.
>
> From: Amit Shah <amit.shah@qumranet.com>
> Date: Tue, 18 Mar 2008 18:01:05 +0530
> Subject: [PATCH] QEMU/KVM: fix initialization of IO memory regions
>
> Signed-off-by: Amit Shah <amit.shah@qumranet.com>
> ---
> qemu/exec.c | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/qemu/exec.c b/qemu/exec.c
> index edeb21a..be15433 100644
> --- a/qemu/exec.c
> +++ b/qemu/exec.c
> @@ -2502,7 +2502,7 @@ static int get_free_io_mem_idx(void)
> {
> int i;
>
> - for (i = 0; i<IO_MEM_NB_ENTRIES; i++)
> + for (i = 5; i<IO_MEM_NB_ENTRIES; i++)
> if (!io_mem_used[i]) {
> io_mem_used[i] = 1;
> return i;
> @@ -2518,7 +2518,7 @@ static void io_mem_init(void)
> cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read,
> unassigned_mem_write, NULL);
> cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT,
> unassigned_mem_read, unassigned_mem_write, NULL);
> cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read,
> notdirty_mem_write, NULL);
> - for (i=0; i<5; i++)
> + for (i=5; i<IO_MEM_NB_ENTRIES; i++)
> io_mem_used[i] = 0;
>
> #if defined(CONFIG_SOFTMMU)
Hi Amit,
There is no need to zero io_mem_used since its in the BSS. The loop in
io_mem_init() was meant to allocate the slots from 0 to 4, not free
them.
So does the following fix the problem?
diff --git a/qemu/exec.c b/qemu/exec.c
index edeb21a..e5199cf 100644
--- a/qemu/exec.c
+++ b/qemu/exec.c
@@ -2519,7 +2519,7 @@ static void io_mem_init(void)
cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_re cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, not for (i=0; i<5; i++)
- io_mem_used[i] = 0;
+ io_mem_used[i] = 1;
#if defined(CONFIG_SOFTMMU)
io_mem_watch = cpu_register_io_memory(-1, watch_mem_read,
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [Qemu-devel] RE: [kvm-devel] [patch 17/24] QEMU/KVM: add cpu_unregister_io_memory and make io mem table index dynamic
2008-03-18 13:54 ` Marcelo Tosatti
@ 2008-03-18 14:13 ` Amit Shah
2008-03-18 15:22 ` [Qemu-devel] " Avi Kivity
0 siblings, 1 reply; 30+ messages in thread
From: Amit Shah @ 2008-03-18 14:13 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: kvm-devel, Avi Kivity, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 926 bytes --]
* Marcelo Tosatti wrote:
> On Tue, Mar 18, 2008 at 06:02:10PM +0530, Amit Shah wrote:
> > This patch broke -no-kvm-irqchip:
...
> Hi Amit,
>
> There is no need to zero io_mem_used since its in the BSS. The loop in
> io_mem_init() was meant to allocate the slots from 0 to 4, not free
> them.
Of course.
> So does the following fix the problem?
>
> diff --git a/qemu/exec.c b/qemu/exec.c
> index edeb21a..e5199cf 100644
> --- a/qemu/exec.c
> +++ b/qemu/exec.c
> @@ -2519,7 +2519,7 @@ static void io_mem_init(void)
> cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT,
> unassigned_mem_re cpu_register_io_memory(IO_MEM_NOTDIRTY >>
> IO_MEM_SHIFT, error_mem_read, not for (i=0; i<5; i++) -
> io_mem_used[i] = 0;
> + io_mem_used[i] = 1;
>
> #if defined(CONFIG_SOFTMMU)
> io_mem_watch = cpu_register_io_memory(-1, watch_mem_read,
Yes, it does. Thanks.
[-- Attachment #2: Type: text/html, Size: 1748 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 18/24] QEMU/KVM: notify _EJ0 through _SEJ OperationRegion
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (16 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 17/24] QEMU/KVM: add cpu_unregister_io_memory and make io mem table index dynamic Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 19/24] QEMU/KVM: handle SEJ notifications Marcelo Tosatti
` (6 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: acpi-ost --]
[-- Type: text/plain, Size: 9564 bytes --]
The _EJ0 method is executed by the OS once it has successfully finished
device removal. Inform that event through IO port space so QEMU
can free the associated data.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/bios/acpi-dsdt.dsl
===================================================================
--- kvm-userspace.hotplug2.orig/bios/acpi-dsdt.dsl
+++ kvm-userspace.hotplug2/bios/acpi-dsdt.dsl
@@ -414,159 +414,258 @@ DefinitionBlock (
PCID, 32,
}
+ OperationRegion(SEJ, SystemIO, 0xae08, 0x04)
+ Field (SEJ, DWordAcc, NoLock, WriteAsZeros)
+ {
+ B0EJ, 32,
+ }
+
Device (S1) { // Slot 1
Name (_ADR, 0x00010000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x2, B0EJ)
+ Return (0x0)
+ }
}
Device (S2) { // Slot 2
Name (_ADR, 0x00020000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x4, B0EJ)
+ Return (0x0)
+ }
}
Device (S3) { // Slot 3
Name (_ADR, 0x00030000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store (0x8, B0EJ)
+ Return (0x0)
+ }
}
Device (S4) { // Slot 4
Name (_ADR, 0x00040000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x10, B0EJ)
+ Return (0x0)
+ }
}
Device (S5) { // Slot 5
Name (_ADR, 0x00050000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x20, B0EJ)
+ Return (0x0)
+ }
}
Device (S6) { // Slot 6
Name (_ADR, 0x00060000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x40, B0EJ)
+ Return (0x0)
+ }
}
Device (S7) { // Slot 7
Name (_ADR, 0x00070000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x80, B0EJ)
+ Return (0x0)
+ }
}
Device (S8) { // Slot 8
Name (_ADR, 0x00080000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x100, B0EJ)
+ Return (0x0)
+ }
}
Device (S9) { // Slot 9
Name (_ADR, 0x00090000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x200, B0EJ)
+ Return (0x0)
+ }
}
Device (S10) { // Slot 10
Name (_ADR, 0x000A0000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x400, B0EJ)
+ Return (0x0)
+ }
}
Device (S11) { // Slot 11
Name (_ADR, 0x000B0000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x800, B0EJ)
+ Return (0x0)
+ }
}
Device (S12) { // Slot 12
Name (_ADR, 0x000C0000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x1000, B0EJ)
+ Return (0x0)
+ }
}
Device (S13) { // Slot 13
Name (_ADR, 0x000D0000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x2000, B0EJ)
+ Return (0x0)
+ }
}
Device (S14) { // Slot 14
Name (_ADR, 0x000E0000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x4000, B0EJ)
+ Return (0x0)
+ }
}
Device (S15) { // Slot 15
Name (_ADR, 0x000F0000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x8000, B0EJ)
+ Return (0x0)
+ }
}
Device (S16) { // Slot 16
Name (_ADR, 0x00100000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x10000, B0EJ)
+ Return (0x0)
+ }
}
Device (S17) { // Slot 17
Name (_ADR, 0x00110000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x20000, B0EJ)
+ Return (0x0)
+ }
}
Device (S18) { // Slot 18
Name (_ADR, 0x00120000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x40000, B0EJ)
+ Return (0x0)
+ }
}
Device (S19) { // Slot 19
Name (_ADR, 0x00130000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x80000, B0EJ)
+ Return (0x0)
+ }
}
Device (S20) { // Slot 20
Name (_ADR, 0x00140000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x100000, B0EJ)
+ Return (0x0)
+ }
}
Device (S21) { // Slot 21
Name (_ADR, 0x00150000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x200000, B0EJ)
+ Return (0x0)
+ }
}
Device (S22) { // Slot 22
Name (_ADR, 0x00160000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x400000, B0EJ)
+ Return (0x0)
+ }
}
Device (S23) { // Slot 23
Name (_ADR, 0x00170000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x800000, B0EJ)
+ Return (0x0)
+ }
}
Device (S24) { // Slot 24
Name (_ADR, 0x00180000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x1000000, B0EJ)
+ Return (0x0)
+ }
}
Device (S25) { // Slot 25
Name (_ADR, 0x00190000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x2000000, B0EJ)
+ Return (0x0)
+ }
}
Device (S26) { // Slot 26
Name (_ADR, 0x001A0000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x4000000, B0EJ)
+ Return (0x0)
+ }
}
Device (S27) { // Slot 27
Name (_ADR, 0x001B0000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x8000000, B0EJ)
+ Return (0x0)
+ }
}
Device (S28) { // Slot 28
Name (_ADR, 0x001C0000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x10000000, B0EJ)
+ Return (0x0)
+ }
}
Device (S29) { // Slot 29
Name (_ADR, 0x001D0000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x20000000, B0EJ)
+ Return (0x0)
+ }
}
Device (S30) { // Slot 30
Name (_ADR, 0x001E0000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x40000000, B0EJ)
+ Return (0x0)
+ }
}
Device (S31) { // Slot 31
Name (_ADR, 0x001F0000)
- Method (_EJ0,1) { Return (0x0) }
+ Method (_EJ0,1) {
+ Store(0x80000000, B0EJ)
+ Return (0x0)
+ }
}
Method (_CRS, 0, NotSerialized)
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 19/24] QEMU/KVM: handle SEJ notifications
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (17 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 18/24] QEMU/KVM: notify _EJ0 through _SEJ OperationRegion Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 20/24] QEMU/KVM: add qemu_free_irqs Marcelo Tosatti
` (5 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: acpi-ej0 --]
[-- Type: text/plain, Size: 1433 bytes --]
Handle the _EJ0 notifications.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/hw/acpi.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/acpi.c
+++ kvm-userspace.hotplug2/qemu/hw/acpi.c
@@ -26,6 +26,7 @@
#ifdef USE_KVM
#include "qemu-kvm.h"
#endif
+#include "string.h"
//#define DEBUG
@@ -539,6 +540,7 @@ void qemu_system_powerdown(void)
#define GPE_BASE 0xafe0
#define PROC_BASE 0xaf00
#define PCI_BASE 0xae00
+#define PCI_EJ_BASE 0xae08
struct gpe_regs {
uint16_t sts; /* status */
@@ -659,6 +661,23 @@ static void pcihotplug_write(void *opaqu
#endif
}
+static uint32_t pciej_read(void *opaque, uint32_t addr)
+{
+#if defined(DEBUG)
+ printf("pciej read %lx == %lx\n", addr, val);
+#endif
+ return 0;
+}
+
+static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ int slot = ffs(val) - 1;
+
+#if defined(DEBUG)
+ printf("pciej write %lx <== %d\n", addr, val);
+#endif
+}
+
static char *model;
@@ -673,6 +692,9 @@ void qemu_system_hot_add_init(char *cpu_
register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status);
register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, &pci0_status);
+ register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, NULL);
+ register_ioport_read(PCI_EJ_BASE, 4, 4, pciej_read, NULL);
+
model = cpu_model;
}
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 20/24] QEMU/KVM: add qemu_free_irqs
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (18 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 19/24] QEMU/KVM: handle SEJ notifications Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 21/24] QEMU/KVM: add pci_unregister_device Marcelo Tosatti
` (4 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: qemu-free-irqs --]
[-- Type: text/plain, Size: 1024 bytes --]
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/hw/irq.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/irq.c
+++ kvm-userspace.hotplug2/qemu/hw/irq.c
@@ -56,6 +56,12 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_ha
return s;
}
+void qemu_free_irqs(qemu_irq *s)
+{
+ qemu_free(s[0]);
+ qemu_free(s);
+}
+
static void qemu_notirq(void *opaque, int line, int level)
{
struct IRQState *irq = opaque;
Index: kvm-userspace.hotplug2/qemu/hw/irq.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/irq.h
+++ kvm-userspace.hotplug2/qemu/hw/irq.h
@@ -28,6 +28,8 @@ static inline void qemu_irq_pulse(qemu_i
/* Returns an array of N IRQs. */
qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
+void qemu_free_irqs(qemu_irq *s);
+
/* Returns a new IRQ with opposite polarity. */
qemu_irq qemu_irq_invert(qemu_irq irq);
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 21/24] QEMU/KVM: add pci_unregister_device
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (19 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 20/24] QEMU/KVM: add qemu_free_irqs Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 22/24] QEMU/KVM: LSI SCSI and e1000 unregister callbacks Marcelo Tosatti
` (3 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: pci-remove --]
[-- Type: text/plain, Size: 3309 bytes --]
Unregister the pci device, unassign its IO and memory regions, and free
associated data.
Add a callback so drivers can free device state.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/hw/pci.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/pci.c
+++ kvm-userspace.hotplug2/qemu/hw/pci.c
@@ -185,6 +185,48 @@ PCIDevice *pci_register_device(PCIBus *b
return pci_dev;
}
+static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
+{
+ return addr + pci_mem_base;
+}
+
+static void pci_unregister_io_regions(PCIDevice *pci_dev)
+{
+ PCIIORegion *r;
+ int i;
+
+ for(i = 0; i < PCI_NUM_REGIONS; i++) {
+ r = &pci_dev->io_regions[i];
+ if (!r->size)
+ continue;
+ if (r->type == PCI_ADDRESS_SPACE_IO) {
+ isa_unassign_ioport(r->addr, r->size);
+ } else {
+ cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
+ r->size,
+ IO_MEM_UNASSIGNED);
+ }
+ }
+}
+
+int pci_unregister_device(PCIDevice *pci_dev)
+{
+ int ret = 0;
+
+ if (pci_dev->unregister)
+ ret = pci_dev->unregister(pci_dev);
+ if (ret)
+ return ret;
+
+ pci_unregister_io_regions(pci_dev);
+
+ qemu_free_irqs(pci_dev->irq);
+ pci_irq_index--;
+ pci_dev->bus->devices[pci_dev->devfn] = NULL;
+ qemu_free(pci_dev);
+ return 0;
+}
+
void pci_register_io_region(PCIDevice *pci_dev, int region_num,
uint32_t size, int type,
PCIMapIORegionFunc *map_func)
@@ -207,10 +249,6 @@ void pci_register_io_region(PCIDevice *p
*(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
}
-static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
-{
- return addr + pci_mem_base;
-}
static void pci_update_mappings(PCIDevice *d)
{
Index: kvm-userspace.hotplug2/qemu/hw/pci.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/pci.h
+++ kvm-userspace.hotplug2/qemu/hw/pci.h
@@ -15,6 +15,7 @@ typedef uint32_t PCIConfigReadFunc(PCIDe
uint32_t address, int len);
typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type);
+typedef int PCIUnregisterFunc(PCIDevice *pci_dev);
#define PCI_ADDRESS_SPACE_MEM 0x00
#define PCI_ADDRESS_SPACE_IO 0x01
@@ -56,6 +57,7 @@ struct PCIDevice {
/* do not access the following fields */
PCIConfigReadFunc *config_read;
PCIConfigWriteFunc *config_write;
+ PCIUnregisterFunc *unregister;
/* ??? This is a PC-specific hack, and should be removed. */
int irq_index;
@@ -71,6 +73,8 @@ PCIDevice *pci_register_device(PCIBus *b
PCIConfigReadFunc *config_read,
PCIConfigWriteFunc *config_write);
+int pci_unregister_device(PCIDevice *pci_dev);
+
void pci_register_io_region(PCIDevice *pci_dev, int region_num,
uint32_t size, int type,
PCIMapIORegionFunc *map_func);
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 22/24] QEMU/KVM: LSI SCSI and e1000 unregister callbacks
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (20 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 21/24] QEMU/KVM: add pci_unregister_device Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 23/24] QEMU/KVM: zero ioport_opaque on isa_unassign_ioport Marcelo Tosatti
` (2 subsequent siblings)
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: lsi-unregister --]
[-- Type: text/plain, Size: 1760 bytes --]
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/hw/lsi53c895a.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/lsi53c895a.c
+++ kvm-userspace.hotplug2/qemu/hw/lsi53c895a.c
@@ -1849,6 +1849,18 @@ void lsi_scsi_attach(void *opaque, Block
bd->devfn = s->pci_dev.devfn;
}
+int lsi_scsi_uninit(PCIDevice *d)
+{
+ LSIState *s = (LSIState *) d;
+
+ cpu_unregister_io_memory(s->mmio_io_addr);
+ cpu_unregister_io_memory(s->ram_io_addr);
+
+ qemu_free(s->queue);
+
+ return 0;
+}
+
void *lsi_scsi_init(PCIBus *bus, int devfn)
{
LSIState *s;
@@ -1881,6 +1893,7 @@ void *lsi_scsi_init(PCIBus *bus, int dev
s->queue = qemu_malloc(sizeof(lsi_queue));
s->queue_len = 1;
s->active_commands = 0;
+ s->pci_dev.unregister = lsi_scsi_uninit;
lsi_soft_reset(s);
Index: kvm-userspace.hotplug2/qemu/hw/e1000.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/e1000.c
+++ kvm-userspace.hotplug2/qemu/hw/e1000.c
@@ -930,6 +930,16 @@ e1000_mmio_map(PCIDevice *pci_dev, int r
cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
}
+static int
+pci_e1000_uninit(PCIDevice *dev)
+{
+ E1000State *d = (E1000State *) dev;
+
+ cpu_unregister_io_memory(d->mmio_index);
+
+ return 0;
+}
+
PCIDevice *
pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
{
@@ -994,6 +1004,7 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd,
d->nd->macaddr[3], d->nd->macaddr[4], d->nd->macaddr[5]);
register_savevm(info_str, d->instance, 1, nic_save, nic_load, d);
+ d->dev.unregister = pci_e1000_uninit;
return (PCIDevice *)d;
}
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 23/24] QEMU/KVM: zero ioport_opaque on isa_unassign_ioport
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (21 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 22/24] QEMU/KVM: LSI SCSI and e1000 unregister callbacks Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 24/24] QEMU/KVM: device hot-remove Marcelo Tosatti
2008-03-16 12:30 ` [Qemu-devel] Re: [kvm-devel] [patch 00/24] QEMU ACPI PCI hotplug support Avi Kivity
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: isa-unassign-opaque --]
[-- Type: text/plain, Size: 609 bytes --]
If the io port is unassigned, the previous private pointer is
meaningless.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/vl.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -399,6 +399,8 @@ void isa_unassign_ioport(int start, int
ioport_write_table[0][i] = default_ioport_writeb;
ioport_write_table[1][i] = default_ioport_writew;
ioport_write_table[2][i] = default_ioport_writel;
+
+ ioport_opaque[i] = NULL;
}
}
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [patch 24/24] QEMU/KVM: device hot-remove
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (22 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 23/24] QEMU/KVM: zero ioport_opaque on isa_unassign_ioport Marcelo Tosatti
@ 2008-03-11 20:12 ` Marcelo Tosatti
2008-03-16 12:30 ` [Qemu-devel] Re: [kvm-devel] [patch 00/24] QEMU ACPI PCI hotplug support Avi Kivity
24 siblings, 0 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:12 UTC (permalink / raw)
To: qemu-devel, kvm-devel; +Cc: aliguori, Marcelo Tosatti
[-- Attachment #1: monitor-remove --]
[-- Type: text/plain, Size: 4701 bytes --]
Add monitor command to hot-remove devices.
Remove device data on _EJ0 notification.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Index: kvm-userspace.hotplug2/qemu/monitor.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/monitor.c
+++ kvm-userspace.hotplug2/qemu/monitor.c
@@ -1365,6 +1365,7 @@ static term_cmd_t term_cmds[] = {
"[snapshot=on|off][,cache=on|off]",
"add drive to PCI storage controller" },
{ "pci_add", "iss", device_hot_add, "bus nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]...", "hot-add PCI device" },
+ { "pci_del", "ii", device_hot_remove, "bus slot-number", "hot remove PCI device" },
{ NULL, NULL, },
};
Index: kvm-userspace.hotplug2/qemu/hw/device-hotplug.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/device-hotplug.c
+++ kvm-userspace.hotplug2/qemu/hw/device-hotplug.c
@@ -5,6 +5,8 @@
#include "sysemu.h"
#include "pc.h"
#include "console.h"
+#include "block_int.h"
+#include <linux/pci_ids.h>
static PCIDevice *qemu_system_hot_add_nic(const char *opts, int bus_nr)
{
@@ -148,7 +150,7 @@ void device_hot_add(int pcibus, const ch
term_printf("invalid type: %s\n", type);
if (dev) {
- qemu_system_device_hot_add(PCI_SLOT(dev->devfn), 1);
+ qemu_system_device_hot_add(pcibus, PCI_SLOT(dev->devfn), 1);
term_printf("OK bus %d, slot %d, function %d (devfn %d)\n",
pci_bus_num(dev->bus), PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), dev->devfn);
@@ -156,3 +158,67 @@ void device_hot_add(int pcibus, const ch
term_printf("failed to add %s\n", opts);
}
+void device_hot_remove(int pcibus, int slot)
+{
+ PCIDevice *d = pci_find_device(pcibus, slot);
+
+ if (!d) {
+ term_printf("invalid slot %d\n", slot);
+ return;
+ }
+
+ qemu_system_device_hot_add(pcibus, slot, 0);
+}
+
+static void destroy_nic(int slot)
+{
+ int i;
+
+ for (i = 0; i < MAX_NICS; i++)
+ if (nd_table[i].used &&
+ PCI_SLOT(nd_table[i].devfn) == slot)
+ net_client_uninit(&nd_table[i]);
+}
+
+static void destroy_bdrvs(int slot)
+{
+ int i;
+ struct BlockDriverState *bs;
+
+ for (i = 0; i <= MAX_DRIVES; i++) {
+ bs = drives_table[i].bdrv;
+ if (bs && (PCI_SLOT(bs->devfn) == slot)) {
+ drive_uninit(bs);
+ bdrv_delete(bs);
+ }
+ }
+}
+
+/*
+ * OS has executed _EJ0 method, we now can remove the device
+ */
+void device_hot_remove_success(int pcibus, int slot)
+{
+ PCIDevice *d = pci_find_device(pcibus, slot);
+ int class_code;
+
+ if (!d) {
+ term_printf("invalid slot %d\n", slot);
+ return;
+ }
+
+ class_code = d->config_read(d, PCI_CLASS_DEVICE+1, 1);
+
+ pci_unregister_device(d);
+
+ switch(class_code) {
+ case PCI_BASE_CLASS_STORAGE:
+ destroy_bdrvs(slot);
+ break;
+ case PCI_BASE_CLASS_NETWORK:
+ destroy_nic(slot);
+ break;
+ }
+
+}
+
Index: kvm-userspace.hotplug2/qemu/sysemu.h
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -176,11 +176,13 @@ extern int drive_init(struct drive_opt *
/* acpi */
void qemu_system_cpu_hot_add(int cpu, int state);
void qemu_system_hot_add_init(char *cpu_model);
-void qemu_system_device_hot_add(int slot, int state);
+void qemu_system_device_hot_add(int pcibus, int slot, int state);
/* device-hotplug */
void device_hot_add(int pcibus, const char *type, const char *opts);
void drive_hot_add(int pcibus, const char *devfn_string, const char *opts);
+void device_hot_remove(int pcibus, int slot);
+void device_hot_remove_success(int pcibus, int slot);
/* vmchannel devices */
Index: kvm-userspace.hotplug2/qemu/hw/acpi.c
===================================================================
--- kvm-userspace.hotplug2.orig/qemu/hw/acpi.c
+++ kvm-userspace.hotplug2/qemu/hw/acpi.c
@@ -673,6 +673,8 @@ static void pciej_write(void *opaque, ui
{
int slot = ffs(val) - 1;
+ device_hot_remove_success(0, slot);
+
#if defined(DEBUG)
printf("pciej write %lx <== %d\n", addr, val);
#endif
@@ -751,7 +753,7 @@ static void disable_device(struct pci_st
p->down |= (1 << slot);
}
-void qemu_system_device_hot_add(int slot, int state)
+void qemu_system_device_hot_add(int pcibus, int slot, int state)
{
qemu_set_irq(pm_state->irq, 1);
pci0_status.up = 0;
--
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] Re: [kvm-devel] [patch 00/24] QEMU ACPI PCI hotplug support
2008-03-11 20:11 [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support Marcelo Tosatti
` (23 preceding siblings ...)
2008-03-11 20:12 ` [Qemu-devel] [patch 24/24] QEMU/KVM: device hot-remove Marcelo Tosatti
@ 2008-03-16 12:30 ` Avi Kivity
24 siblings, 0 replies; 30+ messages in thread
From: Avi Kivity @ 2008-03-16 12:30 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: kvm-devel, qemu-devel
Marcelo Tosatti wrote:
> The following patchset allows PCI hot add/remove through ACPI (handled
> by the acpiphp driver on Linux guests).
>
> Comments are welcome.
>
>
Applied all, thanks.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 30+ messages in thread