mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-16 19:41:50 +00:00
Merge branch 's390-next' of git://repo.or.cz/qemu/agraf
* 's390-next' of git://repo.or.cz/qemu/agraf: s390: fix cpu hotplug / cpu activity on interrupts s390x: add TR function for EXECUTE Expose drive_add on all architectures Add generic drive hotplugging Compile device-hotplug on all targets [S390] Add hotplug support
This commit is contained in:
commit
14763ec873
@ -220,12 +220,15 @@ ifeq ($(CONFIG_KVM), y)
|
|||||||
endif
|
endif
|
||||||
obj-$(CONFIG_IVSHMEM) += ivshmem.o
|
obj-$(CONFIG_IVSHMEM) += ivshmem.o
|
||||||
|
|
||||||
|
# Generic hotplugging
|
||||||
|
obj-y += device-hotplug.o
|
||||||
|
|
||||||
# Hardware support
|
# Hardware support
|
||||||
obj-i386-y += vga.o
|
obj-i386-y += vga.o
|
||||||
obj-i386-y += mc146818rtc.o pc.o
|
obj-i386-y += mc146818rtc.o pc.o
|
||||||
obj-i386-y += cirrus_vga.o sga.o apic.o ioapic.o piix_pci.o
|
obj-i386-y += cirrus_vga.o sga.o apic.o ioapic.o piix_pci.o
|
||||||
obj-i386-y += vmport.o
|
obj-i386-y += vmport.o
|
||||||
obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
|
obj-i386-y += pci-hotplug.o smbios.o wdt_ib700.o
|
||||||
obj-i386-y += debugcon.o multiboot.o
|
obj-i386-y += debugcon.o multiboot.o
|
||||||
obj-i386-y += pc_piix.o
|
obj-i386-y += pc_piix.o
|
||||||
obj-i386-$(CONFIG_KVM) += kvmclock.o
|
obj-i386-$(CONFIG_KVM) += kvmclock.o
|
||||||
|
@ -846,7 +846,6 @@ STEXI
|
|||||||
Snapshot device, using snapshot file as target if provided
|
Snapshot device, using snapshot file as target if provided
|
||||||
ETEXI
|
ETEXI
|
||||||
|
|
||||||
#if defined(TARGET_I386)
|
|
||||||
{
|
{
|
||||||
.name = "drive_add",
|
.name = "drive_add",
|
||||||
.args_type = "pci_addr:s,opts:s",
|
.args_type = "pci_addr:s,opts:s",
|
||||||
@ -859,7 +858,6 @@ ETEXI
|
|||||||
.help = "add drive to PCI storage controller",
|
.help = "add drive to PCI storage controller",
|
||||||
.mhandler.cmd = drive_hot_add,
|
.mhandler.cmd = drive_hot_add,
|
||||||
},
|
},
|
||||||
#endif
|
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
@item drive_add
|
@item drive_add
|
||||||
|
@ -26,6 +26,9 @@
|
|||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "blockdev.h"
|
#include "blockdev.h"
|
||||||
|
#include "qemu-config.h"
|
||||||
|
#include "sysemu.h"
|
||||||
|
#include "monitor.h"
|
||||||
|
|
||||||
DriveInfo *add_init_drive(const char *optstr)
|
DriveInfo *add_init_drive(const char *optstr)
|
||||||
{
|
{
|
||||||
@ -44,3 +47,47 @@ DriveInfo *add_init_drive(const char *optstr)
|
|||||||
|
|
||||||
return dinfo;
|
return dinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(TARGET_I386)
|
||||||
|
int pci_drive_hot_add(Monitor *mon, const QDict *qdict,
|
||||||
|
DriveInfo *dinfo, int type)
|
||||||
|
{
|
||||||
|
/* On non-x86 we don't do PCI hotplug */
|
||||||
|
monitor_printf(mon, "Can't hot-add drive to type %d\n", type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void drive_hot_add(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
DriveInfo *dinfo = NULL;
|
||||||
|
const char *opts = qdict_get_str(qdict, "opts");
|
||||||
|
|
||||||
|
dinfo = add_init_drive(opts);
|
||||||
|
if (!dinfo) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (dinfo->devaddr) {
|
||||||
|
monitor_printf(mon, "Parameter addr not supported\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
type = dinfo->type;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case IF_NONE:
|
||||||
|
monitor_printf(mon, "OK\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (pci_drive_hot_add(mon, qdict, dinfo, type)) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (dinfo) {
|
||||||
|
drive_put_ref(dinfo);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@ -104,24 +104,13 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drive_hot_add(Monitor *mon, const QDict *qdict)
|
int pci_drive_hot_add(Monitor *mon, const QDict *qdict,
|
||||||
|
DriveInfo *dinfo, int type)
|
||||||
{
|
{
|
||||||
int dom, pci_bus;
|
int dom, pci_bus;
|
||||||
unsigned slot;
|
unsigned slot;
|
||||||
int type;
|
|
||||||
PCIDevice *dev;
|
PCIDevice *dev;
|
||||||
DriveInfo *dinfo = NULL;
|
|
||||||
const char *pci_addr = qdict_get_str(qdict, "pci_addr");
|
const char *pci_addr = qdict_get_str(qdict, "pci_addr");
|
||||||
const char *opts = qdict_get_str(qdict, "opts");
|
|
||||||
|
|
||||||
dinfo = add_init_drive(opts);
|
|
||||||
if (!dinfo)
|
|
||||||
goto err;
|
|
||||||
if (dinfo->devaddr) {
|
|
||||||
monitor_printf(mon, "Parameter addr not supported\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
type = dinfo->type;
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case IF_SCSI:
|
case IF_SCSI:
|
||||||
@ -138,19 +127,14 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IF_NONE:
|
|
||||||
monitor_printf(mon, "OK\n");
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
monitor_printf(mon, "Can't hot-add drive to type %d\n", type);
|
monitor_printf(mon, "Can't hot-add drive to type %d\n", type);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
err:
|
err:
|
||||||
if (dinfo)
|
return -1;
|
||||||
drive_put_ref(dinfo);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
|
static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
|
||||||
|
@ -82,12 +82,24 @@ VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
|
|||||||
bus->dev_offs = bus->dev_page;
|
bus->dev_offs = bus->dev_page;
|
||||||
bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
|
bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
|
||||||
|
|
||||||
|
/* Enable hotplugging */
|
||||||
|
_bus->allow_hotplug = 1;
|
||||||
|
|
||||||
/* Allocate RAM for VirtIO device pages (descriptors, queues, rings) */
|
/* Allocate RAM for VirtIO device pages (descriptors, queues, rings) */
|
||||||
*ram_size += S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
|
*ram_size += S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
|
||||||
|
|
||||||
return bus;
|
return bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void s390_virtio_irq(CPUState *env, int config_change, uint64_t token)
|
||||||
|
{
|
||||||
|
if (kvm_enabled()) {
|
||||||
|
kvm_s390_virtio_irq(env, config_change, token);
|
||||||
|
} else {
|
||||||
|
cpu_inject_ext(env, VIRTIO_EXT_CODE, config_change, token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
|
static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
|
||||||
{
|
{
|
||||||
VirtIOS390Bus *bus;
|
VirtIOS390Bus *bus;
|
||||||
@ -109,6 +121,11 @@ static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
|
|||||||
dev->host_features = vdev->get_features(vdev, dev->host_features);
|
dev->host_features = vdev->get_features(vdev, dev->host_features);
|
||||||
s390_virtio_device_sync(dev);
|
s390_virtio_device_sync(dev);
|
||||||
|
|
||||||
|
if (dev->qdev.hotplugged) {
|
||||||
|
CPUState *env = s390_cpu_addr2state(0);
|
||||||
|
s390_virtio_irq(env, VIRTIO_PARAM_DEV_ADD, dev->dev_offs);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,11 +327,7 @@ static void virtio_s390_notify(void *opaque, uint16_t vector)
|
|||||||
uint64_t token = s390_virtio_device_vq_token(dev, vector);
|
uint64_t token = s390_virtio_device_vq_token(dev, vector);
|
||||||
CPUState *env = s390_cpu_addr2state(0);
|
CPUState *env = s390_cpu_addr2state(0);
|
||||||
|
|
||||||
if (kvm_enabled()) {
|
s390_virtio_irq(env, 0, token);
|
||||||
kvm_s390_virtio_irq(env, 0, token);
|
|
||||||
} else {
|
|
||||||
cpu_inject_ext(env, VIRTIO_EXT_CODE, 0, token);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned virtio_s390_get_features(void *opaque)
|
static unsigned virtio_s390_get_features(void *opaque)
|
||||||
@ -382,6 +395,7 @@ static void s390_virtio_bus_register_withprop(VirtIOS390DeviceInfo *info)
|
|||||||
{
|
{
|
||||||
info->qdev.init = s390_virtio_busdev_init;
|
info->qdev.init = s390_virtio_busdev_init;
|
||||||
info->qdev.bus_info = &s390_virtio_bus_info;
|
info->qdev.bus_info = &s390_virtio_bus_info;
|
||||||
|
info->qdev.unplug = qdev_simple_unplug_cb;
|
||||||
|
|
||||||
assert(info->qdev.size >= sizeof(VirtIOS390Device));
|
assert(info->qdev.size >= sizeof(VirtIOS390Device));
|
||||||
qdev_register(&info->qdev);
|
qdev_register(&info->qdev);
|
||||||
|
@ -35,6 +35,11 @@
|
|||||||
#define VIRTIO_RING_LEN (TARGET_PAGE_SIZE * 3)
|
#define VIRTIO_RING_LEN (TARGET_PAGE_SIZE * 3)
|
||||||
#define S390_DEVICE_PAGES 512
|
#define S390_DEVICE_PAGES 512
|
||||||
|
|
||||||
|
#define VIRTIO_PARAM_MASK 0xff
|
||||||
|
#define VIRTIO_PARAM_VRING_INTERRUPT 0x0
|
||||||
|
#define VIRTIO_PARAM_CONFIG_CHANGED 0x1
|
||||||
|
#define VIRTIO_PARAM_DEV_ADD 0x2
|
||||||
|
|
||||||
typedef struct VirtIOS390Device {
|
typedef struct VirtIOS390Device {
|
||||||
DeviceState qdev;
|
DeviceState qdev;
|
||||||
ram_addr_t dev_offs;
|
ram_addr_t dev_offs;
|
||||||
|
6
sysemu.h
6
sysemu.h
@ -143,9 +143,13 @@ extern unsigned int nb_prom_envs;
|
|||||||
|
|
||||||
/* pci-hotplug */
|
/* pci-hotplug */
|
||||||
void pci_device_hot_add(Monitor *mon, const QDict *qdict);
|
void pci_device_hot_add(Monitor *mon, const QDict *qdict);
|
||||||
void drive_hot_add(Monitor *mon, const QDict *qdict);
|
int pci_drive_hot_add(Monitor *mon, const QDict *qdict,
|
||||||
|
DriveInfo *dinfo, int type);
|
||||||
void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
|
void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
|
||||||
|
|
||||||
|
/* generic hotplug */
|
||||||
|
void drive_hot_add(Monitor *mon, const QDict *qdict);
|
||||||
|
|
||||||
/* pcie aer error injection */
|
/* pcie aer error injection */
|
||||||
void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
|
void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
|
||||||
int do_pcie_aer_inject_error(Monitor *mon,
|
int do_pcie_aer_inject_error(Monitor *mon,
|
||||||
|
@ -185,9 +185,6 @@ void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s390_add_running_cpu(env);
|
|
||||||
qemu_cpu_kick(env);
|
|
||||||
|
|
||||||
kvmint.type = type;
|
kvmint.type = type;
|
||||||
kvmint.parm = parm;
|
kvmint.parm = parm;
|
||||||
kvmint.parm64 = parm64;
|
kvmint.parm64 = parm64;
|
||||||
|
@ -636,6 +636,9 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
|
|||||||
case 0x700:
|
case 0x700:
|
||||||
cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2));
|
cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2));
|
||||||
break;
|
break;
|
||||||
|
case 0xc00:
|
||||||
|
helper_tr(l, get_address(0, b1, d1), get_address(0, b2, d2));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
goto abort;
|
goto abort;
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user