qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support
@ 2008-03-11 20:11 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
                   ` (24 more replies)
  0 siblings, 25 replies; 30+ messages in thread
From: Marcelo Tosatti @ 2008-03-11 20:11 UTC (permalink / raw)
  To: qemu-devel, kvm-devel; +Cc: aliguori

The following patchset allows PCI hot add/remove through ACPI (handled
by the acpiphp driver on Linux guests).

Comments are welcome.

-- 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [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] [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

* [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] Re: [kvm-devel] [patch 17/24] QEMU/KVM: add cpu_unregister_io_memory and make io mem table index dynamic
  2008-03-18 14:13       ` [Qemu-devel] " Amit Shah
@ 2008-03-18 15:22         ` Avi Kivity
  0 siblings, 0 replies; 30+ messages in thread
From: Avi Kivity @ 2008-03-18 15:22 UTC (permalink / raw)
  To: Amit Shah; +Cc: Marcelo Tosatti, kvm-devel, qemu-devel

Amit Shah wrote:
>
>
> > So does the following fix the problem?
> >
> Yes, it does. Thanks.
>

Okay, applied.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2008-03-18 15:26 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [Qemu-devel] [patch 03/24] QEMU/KVM: add pci_find_bus 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
2008-03-11 20:11 ` [Qemu-devel] [patch 05/24] QEMU/KVM: pci hotplug GPE support Marcelo Tosatti
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 ` [Qemu-devel] [patch 07/24] QEMU/KVM: dynamic nic info " Marcelo Tosatti
2008-03-11 20:11 ` [Qemu-devel] [patch 08/24] QEMU/KVM: drive removal support Marcelo Tosatti
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 ` [Qemu-devel] [patch 10/24] QEMU/KVM: move drives_opt for external use Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 11/24] QEMU/KVM: net/drive add/remove tweaks Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 12/24] QEMU/KVM: add net_client_uninit Marcelo Tosatti
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 ` [Qemu-devel] [patch 14/24] QEMU/KVM: add pci_find_device Marcelo Tosatti
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 ` [Qemu-devel] [patch 16/24] QEMU/KVM: device and disk hot-add 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
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
2008-03-18 15:22         ` [Qemu-devel] " Avi Kivity
2008-03-11 20:12 ` [Qemu-devel] [patch 18/24] QEMU/KVM: notify _EJ0 through _SEJ OperationRegion Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 19/24] QEMU/KVM: handle SEJ notifications Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 20/24] QEMU/KVM: add qemu_free_irqs Marcelo Tosatti
2008-03-11 20:12 ` [Qemu-devel] [patch 21/24] QEMU/KVM: add pci_unregister_device Marcelo Tosatti
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 ` [Qemu-devel] [patch 23/24] QEMU/KVM: zero ioport_opaque on isa_unassign_ioport 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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).