aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-07-14 12:16:09 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-07-14 12:16:09 +0100
commit6c6076662d98c068059983d411cb2a8987ba5670 (patch)
treeb3a180eb5eab8474c5557b8a77c2589faa980f8e /hw
parent7d367e7002c3ca78531653105bd4fccd55e426a8 (diff)
parent68c761e19c2ea453f880dbbd04e867d34d1468b8 (diff)
downloadqemu-6c6076662d98c068059983d411cb2a8987ba5670.zip
qemu-6c6076662d98c068059983d411cb2a8987ba5670.tar.gz
qemu-6c6076662d98c068059983d411cb2a8987ba5670.tar.bz2
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* gdbstub fixes (Alex) * IOMMU MemoryRegion subclass (Alexey) * Chardev hotswap (Anton) * NBD_OPT_GO support (Eric) * Misc bugfixes * DEFINE_PROP_LINK (minus the ARM patches - Fam) * MAINTAINERS updates (Philippe) # gpg: Signature made Fri 14 Jul 2017 11:06:27 BST # gpg: using RSA key 0xBFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (55 commits) spapr_rng: Convert to DEFINE_PROP_LINK cpu: Convert to DEFINE_PROP_LINK mips_cmgcr: Convert to DEFINE_PROP_LINK ivshmem: Convert to DEFINE_PROP_LINK dimm: Convert to DEFINE_PROP_LINK virtio-crypto: Convert to DEFINE_PROP_LINK virtio-rng: Convert to DEFINE_PROP_LINK virtio-scsi: Convert to DEFINE_PROP_LINK virtio-blk: Convert to DEFINE_PROP_LINK qdev: Add const qualifier to PropertyInfo definitions qmp: Use ObjectProperty.type if present qdev: Introduce DEFINE_PROP_LINK qdev: Introduce PropertyInfo.create qom: enforce readonly nature of link's check callback translate-all: remove redundant !tcg_enabled check in dump_exec_info vl: fix breakage of -tb-size nbd: Implement NBD_INFO_BLOCK_SIZE on client nbd: Implement NBD_INFO_BLOCK_SIZE on server nbd: Implement NBD_OPT_GO on client nbd: Implement NBD_OPT_GO on server ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/alpha/typhoon.c31
-rw-r--r--hw/arm/pxa2xx.c3
-rw-r--r--hw/arm/strongarm.c4
-rw-r--r--hw/block/virtio-blk.c6
-rw-r--r--hw/char/bcm2835_aux.c2
-rw-r--r--hw/char/cadence_uart.c4
-rw-r--r--hw/char/debugcon.c4
-rw-r--r--hw/char/digic-uart.c2
-rw-r--r--hw/char/escc.c8
-rw-r--r--hw/char/etraxfs_ser.c2
-rw-r--r--hw/char/exynos4210_uart.c4
-rw-r--r--hw/char/grlib_apbuart.c4
-rw-r--r--hw/char/imx_serial.c2
-rw-r--r--hw/char/ipoctal232.c4
-rw-r--r--hw/char/lm32_juart.c2
-rw-r--r--hw/char/lm32_uart.c2
-rw-r--r--hw/char/mcf_uart.c2
-rw-r--r--hw/char/milkymist-uart.c2
-rw-r--r--hw/char/parallel.c8
-rw-r--r--hw/char/pl011.c2
-rw-r--r--hw/char/sclpconsole-lm.c4
-rw-r--r--hw/char/sclpconsole.c4
-rw-r--r--hw/char/serial.c63
-rw-r--r--hw/char/sh_serial.c4
-rw-r--r--hw/char/spapr_vty.c4
-rw-r--r--hw/char/stm32f2xx_usart.c3
-rw-r--r--hw/char/terminal3270.c4
-rw-r--r--hw/char/virtio-console.c35
-rw-r--r--hw/char/xen_console.c4
-rw-r--r--hw/char/xilinx_uartlite.c2
-rw-r--r--hw/core/qdev-properties-system.c8
-rw-r--r--hw/core/qdev-properties.c63
-rw-r--r--hw/core/qdev.c31
-rw-r--r--hw/display/xlnx_dp.c2
-rw-r--r--hw/dma/rc4030.c34
-rw-r--r--hw/i386/amd_iommu.c33
-rw-r--r--hw/i386/amd_iommu.h5
-rw-r--r--hw/i386/intel_iommu.c42
-rw-r--r--hw/i386/kvmvapic.c85
-rw-r--r--hw/ipmi/ipmi.c2
-rw-r--r--hw/ipmi/ipmi_bmc_extern.c4
-rw-r--r--hw/mem/pc-dimm.c30
-rw-r--r--hw/mips/boston.c2
-rw-r--r--hw/mips/mips_jazz.c2
-rw-r--r--hw/mips/mips_malta.c2
-rw-r--r--hw/misc/ivshmem.c30
-rw-r--r--hw/misc/mips_cmgcr.c16
-rw-r--r--hw/pci-host/apb.c29
-rw-r--r--hw/ppc/spapr_iommu.c42
-rw-r--r--hw/ppc/spapr_rng.c8
-rw-r--r--hw/s390x/css.c4
-rw-r--r--hw/s390x/s390-pci-bus.c31
-rw-r--r--hw/s390x/s390-pci-bus.h3
-rw-r--r--hw/s390x/s390-pci-inst.c11
-rw-r--r--hw/s390x/virtio-ccw.c9
-rw-r--r--hw/scsi/virtio-scsi.c13
-rw-r--r--hw/usb/ccid-card-passthru.c6
-rw-r--r--hw/usb/dev-serial.c7
-rw-r--r--hw/usb/redirect.c7
-rw-r--r--hw/vfio/common.c12
-rw-r--r--hw/vfio/spapr.c3
-rw-r--r--hw/virtio/virtio-crypto-pci.c2
-rw-r--r--hw/virtio/virtio-crypto.c27
-rw-r--r--hw/virtio/virtio-pci.c6
-rw-r--r--hw/virtio/virtio-rng.c12
65 files changed, 475 insertions, 373 deletions
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index c1cf780..ae11e01 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -17,6 +17,7 @@
#define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost"
+#define TYPE_TYPHOON_IOMMU_MEMORY_REGION "typhoon-iommu-memory-region"
typedef struct TyphoonCchip {
MemoryRegion region;
@@ -41,7 +42,7 @@ typedef struct TyphoonPchip {
MemoryRegion reg_conf;
AddressSpace iommu_as;
- MemoryRegion iommu;
+ IOMMUMemoryRegion iommu;
uint64_t ctl;
TyphoonWindow win[4];
@@ -663,7 +664,8 @@ static bool window_translate(TyphoonWindow *win, hwaddr addr,
/* Handle PCI-to-system address translation. */
/* TODO: A translation failure here ought to set PCI error codes on the
Pchip and generate a machine check interrupt. */
-static IOMMUTLBEntry typhoon_translate_iommu(MemoryRegion *iommu, hwaddr addr,
+static IOMMUTLBEntry typhoon_translate_iommu(IOMMUMemoryRegion *iommu,
+ hwaddr addr,
IOMMUAccessFlags flag)
{
TyphoonPchip *pchip = container_of(iommu, TyphoonPchip, iommu);
@@ -724,10 +726,6 @@ static IOMMUTLBEntry typhoon_translate_iommu(MemoryRegion *iommu, hwaddr addr,
return ret;
}
-static const MemoryRegionIOMMUOps typhoon_iommu_ops = {
- .translate = typhoon_translate_iommu,
-};
-
static AddressSpace *typhoon_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
{
TyphoonState *s = opaque;
@@ -891,9 +889,11 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
qdev_init_nofail(dev);
/* Host memory as seen from the PCI side, via the IOMMU. */
- memory_region_init_iommu(&s->pchip.iommu, OBJECT(s), &typhoon_iommu_ops,
+ memory_region_init_iommu(&s->pchip.iommu, sizeof(s->pchip.iommu),
+ TYPE_TYPHOON_IOMMU_MEMORY_REGION, OBJECT(s),
"iommu-typhoon", UINT64_MAX);
- address_space_init(&s->pchip.iommu_as, &s->pchip.iommu, "pchip0-pci");
+ address_space_init(&s->pchip.iommu_as, MEMORY_REGION(&s->pchip.iommu),
+ "pchip0-pci");
pci_setup_iommu(b, typhoon_pci_dma_iommu, s);
/* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB. */
@@ -951,9 +951,24 @@ static const TypeInfo typhoon_pcihost_info = {
.class_init = typhoon_pcihost_class_init,
};
+static void typhoon_iommu_memory_region_class_init(ObjectClass *klass,
+ void *data)
+{
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
+
+ imrc->translate = typhoon_translate_iommu;
+}
+
+static const TypeInfo typhoon_iommu_memory_region_info = {
+ .parent = TYPE_IOMMU_MEMORY_REGION,
+ .name = TYPE_TYPHOON_IOMMU_MEMORY_REGION,
+ .class_init = typhoon_iommu_memory_region_class_init,
+};
+
static void typhoon_register_types(void)
{
type_register_static(&typhoon_pcihost_info);
+ type_register_static(&typhoon_iommu_memory_region_info);
}
type_init(typhoon_register_types)
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 629e6c6..731ed08 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1970,7 +1970,8 @@ static void pxa2xx_fir_realize(DeviceState *dev, Error **errp)
PXA2xxFIrState *s = PXA2XX_FIR(dev);
qemu_chr_fe_set_handlers(&s->chr, pxa2xx_fir_is_empty,
- pxa2xx_fir_rx, pxa2xx_fir_event, s, NULL, true);
+ pxa2xx_fir_rx, pxa2xx_fir_event, NULL, s, NULL,
+ true);
}
static bool pxa2xx_fir_vmstate_validate(void *opaque, int version_id)
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index 7683edc..6a45dcc 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -1106,7 +1106,7 @@ static void strongarm_uart_tx(void *opaque)
if (s->utcr3 & UTCR3_LBM) /* loopback */ {
strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
- } else if (qemu_chr_fe_get_driver(&s->chr)) {
+ } else if (qemu_chr_fe_backend_connected(&s->chr)) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
qemu_chr_fe_write_all(&s->chr, &s->tx_fifo[s->tx_start], 1);
@@ -1247,7 +1247,7 @@ static void strongarm_uart_realize(DeviceState *dev, Error **errp)
strongarm_uart_can_receive,
strongarm_uart_receive,
strongarm_uart_event,
- s, NULL, true);
+ NULL, s, NULL, true);
}
static void strongarm_uart_reset(DeviceState *dev)
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index c0bd247..b750bd8 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -983,10 +983,6 @@ static void virtio_blk_instance_init(Object *obj)
{
VirtIOBlock *s = VIRTIO_BLK(obj);
- object_property_add_link(obj, "iothread", TYPE_IOTHREAD,
- (Object **)&s->conf.iothread,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
device_add_bootindex_property(obj, &s->conf.conf.bootindex,
"bootindex", "/disk@0,0",
DEVICE(obj), NULL);
@@ -1014,6 +1010,8 @@ static Property virtio_blk_properties[] = {
DEFINE_PROP_BIT("request-merging", VirtIOBlock, conf.request_merging, 0,
true),
DEFINE_PROP_UINT16("num-queues", VirtIOBlock, conf.num_queues, 1),
+ DEFINE_PROP_LINK("iothread", VirtIOBlock, conf.iothread, TYPE_IOTHREAD,
+ IOThread *),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c
index 4d46ad6..370dc7e 100644
--- a/hw/char/bcm2835_aux.c
+++ b/hw/char/bcm2835_aux.c
@@ -279,7 +279,7 @@ static void bcm2835_aux_realize(DeviceState *dev, Error **errp)
BCM2835AuxState *s = BCM2835_AUX(dev);
qemu_chr_fe_set_handlers(&s->chr, bcm2835_aux_can_receive,
- bcm2835_aux_receive, NULL, s, NULL, true);
+ bcm2835_aux_receive, NULL, NULL, s, NULL, true);
}
static Property bcm2835_aux_props[] = {
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index 4a2c124..6143494 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -279,7 +279,7 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond,
int ret;
/* instant drain the fifo when there's no back-end */
- if (!qemu_chr_fe_get_driver(&s->chr)) {
+ if (!qemu_chr_fe_backend_connected(&s->chr)) {
s->tx_count = 0;
return FALSE;
}
@@ -485,7 +485,7 @@ static void cadence_uart_realize(DeviceState *dev, Error **errp)
fifo_trigger_update, s);
qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
- uart_event, s, NULL, true);
+ uart_event, NULL, s, NULL, true);
}
static void cadence_uart_init(Object *obj)
diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 762e3d8..95ccec6 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -87,12 +87,12 @@ static const MemoryRegionOps debugcon_ops = {
static void debugcon_realize_core(DebugconState *s, Error **errp)
{
- if (!qemu_chr_fe_get_driver(&s->chr)) {
+ if (!qemu_chr_fe_backend_connected(&s->chr)) {
error_setg(errp, "Can't create debugcon device, empty char device");
return;
}
- qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, s, NULL, true);
+ qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL, s, NULL, true);
}
static void debugcon_isa_realizefn(DeviceState *dev, Error **errp)
diff --git a/hw/char/digic-uart.c b/hw/char/digic-uart.c
index 34306e1..6ebcb87 100644
--- a/hw/char/digic-uart.c
+++ b/hw/char/digic-uart.c
@@ -146,7 +146,7 @@ static void digic_uart_realize(DeviceState *dev, Error **errp)
DigicUartState *s = DIGIC_UART(dev);
qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
- uart_event, s, NULL, true);
+ uart_event, NULL, s, NULL, true);
}
static void digic_uart_init(Object *obj)
diff --git a/hw/char/escc.c b/hw/char/escc.c
index 3f78763..89ae9eb 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -417,7 +417,7 @@ static void escc_update_parameters(ChannelState *s)
int speed, parity, data_bits, stop_bits;
QEMUSerialSetParams ssp;
- if (!qemu_chr_fe_get_driver(&s->chr) || s->type != ser)
+ if (!qemu_chr_fe_backend_connected(&s->chr) || s->type != ser)
return;
if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
@@ -557,7 +557,7 @@ static void escc_mem_write(void *opaque, hwaddr addr,
trace_escc_mem_writeb_data(CHN_C(s), val);
s->tx = val;
if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
- if (qemu_chr_fe_get_driver(&s->chr)) {
+ if (qemu_chr_fe_backend_connected(&s->chr)) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
qemu_chr_fe_write_all(&s->chr, &s->tx, 1);
@@ -1013,10 +1013,10 @@ static void escc_realize(DeviceState *dev, Error **errp)
ESCC_SIZE << s->it_shift);
for (i = 0; i < 2; i++) {
- if (qemu_chr_fe_get_driver(&s->chn[i].chr)) {
+ if (qemu_chr_fe_backend_connected(&s->chn[i].chr)) {
s->chn[i].clock = s->frequency / 2;
qemu_chr_fe_set_handlers(&s->chn[i].chr, serial_can_receive,
- serial_receive1, serial_event,
+ serial_receive1, serial_event, NULL,
&s->chn[i], NULL, true);
}
}
diff --git a/hw/char/etraxfs_ser.c b/hw/char/etraxfs_ser.c
index c1fba9f..a184026 100644
--- a/hw/char/etraxfs_ser.c
+++ b/hw/char/etraxfs_ser.c
@@ -233,7 +233,7 @@ static void etraxfs_ser_realize(DeviceState *dev, Error **errp)
qemu_chr_fe_set_handlers(&s->chr,
serial_can_receive, serial_receive,
- serial_event, s, NULL, true);
+ serial_event, NULL, s, NULL, true);
}
static void etraxfs_ser_class_init(ObjectClass *klass, void *data)
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index b51d44a..3957e78 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -380,7 +380,7 @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
break;
case UTXH:
- if (qemu_chr_fe_get_driver(&s->chr)) {
+ if (qemu_chr_fe_backend_connected(&s->chr)) {
s->reg[I_(UTRSTAT)] &= ~(UTRSTAT_TRANSMITTER_EMPTY |
UTRSTAT_Tx_BUFFER_EMPTY);
ch = (uint8_t)val;
@@ -645,7 +645,7 @@ static void exynos4210_uart_realize(DeviceState *dev, Error **errp)
qemu_chr_fe_set_handlers(&s->chr, exynos4210_uart_can_receive,
exynos4210_uart_receive, exynos4210_uart_event,
- s, NULL, true);
+ NULL, s, NULL, true);
}
static Property exynos4210_uart_properties[] = {
diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c
index 32d98ed..bac11be 100644
--- a/hw/char/grlib_apbuart.c
+++ b/hw/char/grlib_apbuart.c
@@ -201,7 +201,7 @@ static void grlib_apbuart_write(void *opaque, hwaddr addr,
case DATA_OFFSET:
case DATA_OFFSET + 3: /* When only one byte write */
/* Transmit when character device available and transmitter enabled */
- if (qemu_chr_fe_get_driver(&uart->chr) &&
+ if (qemu_chr_fe_backend_connected(&uart->chr) &&
(uart->control & UART_TRANSMIT_ENABLE)) {
c = value & 0xFF;
/* XXX this blocks entire thread. Rewrite to use
@@ -247,7 +247,7 @@ static int grlib_apbuart_init(SysBusDevice *dev)
grlib_apbuart_can_receive,
grlib_apbuart_receive,
grlib_apbuart_event,
- uart, NULL, true);
+ NULL, uart, NULL, true);
sysbus_init_irq(dev, &uart->irq);
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index af25030..70405cc 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -315,7 +315,7 @@ static void imx_serial_realize(DeviceState *dev, Error **errp)
DPRINTF("char dev for uart: %p\n", qemu_chr_fe_get_driver(&s->chr));
qemu_chr_fe_set_handlers(&s->chr, imx_can_receive, imx_receive,
- imx_event, s, NULL, true);
+ imx_event, NULL, s, NULL, true);
}
static void imx_serial_init(Object *obj)
diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c
index 337a3e56..5e09caf 100644
--- a/hw/char/ipoctal232.c
+++ b/hw/char/ipoctal232.c
@@ -542,10 +542,10 @@ static void ipoctal_realize(DeviceState *dev, Error **errp)
ch->ipoctal = s;
/* Redirect IP-Octal channels to host character devices */
- if (qemu_chr_fe_get_driver(&ch->dev)) {
+ if (qemu_chr_fe_backend_connected(&ch->dev)) {
qemu_chr_fe_set_handlers(&ch->dev, hostdev_can_receive,
hostdev_receive, hostdev_event,
- ch, NULL, true);
+ NULL, ch, NULL, true);
DPRINTF("Redirecting channel %u to %s\n", i, ch->dev->label);
} else {
DPRINTF("Could not redirect channel %u, no chardev set\n", i);
diff --git a/hw/char/lm32_juart.c b/hw/char/lm32_juart.c
index 3948dcd..d75c835 100644
--- a/hw/char/lm32_juart.c
+++ b/hw/char/lm32_juart.c
@@ -119,7 +119,7 @@ static void lm32_juart_realize(DeviceState *dev, Error **errp)
LM32JuartState *s = LM32_JUART(dev);
qemu_chr_fe_set_handlers(&s->chr, juart_can_rx, juart_rx,
- juart_event, s, NULL, true);
+ juart_event, NULL, s, NULL, true);
}
static const VMStateDescription vmstate_lm32_juart = {
diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c
index cff8c38..c4a3b9b 100644
--- a/hw/char/lm32_uart.c
+++ b/hw/char/lm32_uart.c
@@ -266,7 +266,7 @@ static void lm32_uart_realize(DeviceState *dev, Error **errp)
LM32UartState *s = LM32_UART(dev);
qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
- uart_event, s, NULL, true);
+ uart_event, NULL, s, NULL, true);
}
static const VMStateDescription vmstate_lm32_uart = {
diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c
index fe12ad5..56fa402 100644
--- a/hw/char/mcf_uart.c
+++ b/hw/char/mcf_uart.c
@@ -305,7 +305,7 @@ static void mcf_uart_realize(DeviceState *dev, Error **errp)
mcf_uart_state *s = MCF_UART(dev);
qemu_chr_fe_set_handlers(&s->chr, mcf_uart_can_receive, mcf_uart_receive,
- mcf_uart_event, s, NULL, true);
+ mcf_uart_event, NULL, s, NULL, true);
}
static Property mcf_uart_properties[] = {
diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c
index e19d0f6..548ee27 100644
--- a/hw/char/milkymist-uart.c
+++ b/hw/char/milkymist-uart.c
@@ -199,7 +199,7 @@ static void milkymist_uart_realize(DeviceState *dev, Error **errp)
MilkymistUartState *s = MILKYMIST_UART(dev);
qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
- uart_event, s, NULL, true);
+ uart_event, NULL, s, NULL, true);
}
static void milkymist_uart_init(Object *obj)
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index 75a1a2f..f79dc76 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -503,6 +503,10 @@ static const VMStateDescription vmstate_parallel_isa = {
}
};
+static int parallel_can_receive(void *opaque)
+{
+ return 1;
+}
static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
{
@@ -513,7 +517,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
int base;
uint8_t dummy;
- if (!qemu_chr_fe_get_driver(&s->chr)) {
+ if (!qemu_chr_fe_backend_connected(&s->chr)) {
error_setg(errp, "Can't create parallel device, empty char device");
return;
}
@@ -535,6 +539,8 @@ static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
isa_init_irq(isadev, &s->irq, isa->isairq);
qemu_register_reset(parallel_reset, s);
+ qemu_chr_fe_set_handlers(&s->chr, parallel_can_receive, NULL,
+ NULL, NULL, s, NULL, true);
if (qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
s->hw_driver = 1;
s->status = dummy;
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index 33802f0..2aa277f 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -329,7 +329,7 @@ static void pl011_realize(DeviceState *dev, Error **errp)
PL011State *s = PL011(dev);
qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive,
- pl011_event, s, NULL, true);
+ pl011_event, NULL, s, NULL, true);
}
static void pl011_class_init(ObjectClass *oc, void *data)
diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c
index 1b15046..c500bda 100644
--- a/hw/char/sclpconsole-lm.c
+++ b/hw/char/sclpconsole-lm.c
@@ -195,7 +195,7 @@ static int write_console_data(SCLPEvent *event, const uint8_t *buf, int len)
{
SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);
- if (!qemu_chr_fe_get_driver(&scon->chr)) {
+ if (!qemu_chr_fe_backend_connected(&scon->chr)) {
/* If there's no backend, we can just say we consumed all data. */
return len;
}
@@ -313,7 +313,7 @@ static int console_init(SCLPEvent *event)
console_available = true;
qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
- chr_read, NULL, scon, NULL, true);
+ chr_read, NULL, NULL, scon, NULL, true);
return 0;
}
diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
index 4a107a2..d0265df 100644
--- a/hw/char/sclpconsole.c
+++ b/hw/char/sclpconsole.c
@@ -163,7 +163,7 @@ static ssize_t write_console_data(SCLPEvent *event, const uint8_t *buf,
{
SCLPConsole *scon = SCLP_CONSOLE(event);
- if (!qemu_chr_fe_get_driver(&scon->chr)) {
+ if (!qemu_chr_fe_backend_connected(&scon->chr)) {
/* If there's no backend, we can just say we consumed all data. */
return len;
}
@@ -228,7 +228,7 @@ static int console_init(SCLPEvent *event)
}
console_available = true;
qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
- chr_read, NULL, scon, NULL, true);
+ chr_read, NULL, NULL, scon, NULL, true);
return 0;
}
diff --git a/hw/char/serial.c b/hw/char/serial.c
index e1f1250..9aec6c6 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -312,6 +312,24 @@ static void serial_write_fcr(SerialState *s, uint8_t val)
}
}
+static void serial_update_tiocm(SerialState *s)
+{
+ int flags;
+
+ qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
+
+ flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR);
+
+ if (s->mcr & UART_MCR_RTS) {
+ flags |= CHR_TIOCM_RTS;
+ }
+ if (s->mcr & UART_MCR_DTR) {
+ flags |= CHR_TIOCM_DTR;
+ }
+
+ qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
+}
+
static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
@@ -426,24 +444,13 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
break;
case 4:
{
- int flags;
int old_mcr = s->mcr;
s->mcr = val & 0x1f;
if (val & UART_MCR_LOOP)
break;
if (s->poll_msl >= 0 && old_mcr != s->mcr) {
-
- qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
-
- flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR);
-
- if (val & UART_MCR_RTS)
- flags |= CHR_TIOCM_RTS;
- if (val & UART_MCR_DTR)
- flags |= CHR_TIOCM_DTR;
-
- qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
+ serial_update_tiocm(s);
/* Update the modem status after a one-character-send wait-time, since there may be a response
from the device/computer at the other end of the serial line */
timer_mod(s->modem_status_poll, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time);
@@ -884,9 +891,37 @@ static void serial_reset(void *opaque)
s->msr &= ~UART_MSR_ANY_DELTA;
}
+static int serial_be_change(void *opaque)
+{
+ SerialState *s = opaque;
+
+ qemu_chr_fe_set_handlers(&s->chr, serial_can_receive1, serial_receive1,
+ serial_event, serial_be_change, s, NULL, true);
+
+ serial_update_parameters(s);
+
+ qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
+ &s->last_break_enable);
+
+ s->poll_msl = (s->ier & UART_IER_MSI) ? 1 : 0;
+ serial_update_msl(s);
+
+ if (s->poll_msl >= 0 && !(s->mcr & UART_MCR_LOOP)) {
+ serial_update_tiocm(s);
+ }
+
+ if (s->watch_tag > 0) {
+ g_source_remove(s->watch_tag);
+ s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
+ serial_watch_cb, s);
+ }
+
+ return 0;
+}
+
void serial_realize_core(SerialState *s, Error **errp)
{
- if (!qemu_chr_fe_get_driver(&s->chr)) {
+ if (!qemu_chr_fe_backend_connected(&s->chr)) {
error_setg(errp, "Can't create serial device, empty char device");
return;
}
@@ -897,7 +932,7 @@ void serial_realize_core(SerialState *s, Error **errp)
qemu_register_reset(serial_reset, s);
qemu_chr_fe_set_handlers(&s->chr, serial_can_receive1, serial_receive1,
- serial_event, s, NULL, true);
+ serial_event, serial_be_change, s, NULL, true);
fifo8_create(&s->recv_fifo, UART_FIFO_LENGTH);
fifo8_create(&s->xmit_fifo, UART_FIFO_LENGTH);
serial_reset(s);
diff --git a/hw/char/sh_serial.c b/hw/char/sh_serial.c
index ca9816d..835b537 100644
--- a/hw/char/sh_serial.c
+++ b/hw/char/sh_serial.c
@@ -110,7 +110,7 @@ static void sh_serial_write(void *opaque, hwaddr offs,
}
return;
case 0x0c: /* FTDR / TDR */
- if (qemu_chr_fe_get_driver(&s->chr)) {
+ if (qemu_chr_fe_backend_connected(&s->chr)) {
ch = val;
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
@@ -400,7 +400,7 @@ void sh_serial_init(MemoryRegion *sysmem,
qemu_chr_fe_init(&s->chr, chr, &error_abort);
qemu_chr_fe_set_handlers(&s->chr, sh_serial_can_receive1,
sh_serial_receive1,
- sh_serial_event, s, NULL, true);
+ sh_serial_event, NULL, s, NULL, true);
}
s->eri = eri_source;
diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 8f02f3a..0fa416c 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -78,13 +78,13 @@ static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error **errp)
{
VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev);
- if (!qemu_chr_fe_get_driver(&dev->chardev)) {
+ if (!qemu_chr_fe_backend_connected(&dev->chardev)) {
error_setg(errp, "chardev property not set");
return;
}
qemu_chr_fe_set_handlers(&dev->chardev, vty_can_receive,
- vty_receive, NULL, dev, NULL, true);
+ vty_receive, NULL, NULL, dev, NULL, true);
}
/* Forward declaration */
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
index 59872e6..268e435 100644
--- a/hw/char/stm32f2xx_usart.c
+++ b/hw/char/stm32f2xx_usart.c
@@ -207,7 +207,8 @@ static void stm32f2xx_usart_realize(DeviceState *dev, Error **errp)
STM32F2XXUsartState *s = STM32F2XX_USART(dev);
qemu_chr_fe_set_handlers(&s->chr, stm32f2xx_usart_can_receive,
- stm32f2xx_usart_receive, NULL, s, NULL, true);
+ stm32f2xx_usart_receive, NULL, NULL,
+ s, NULL, true);
}
static void stm32f2xx_usart_class_init(ObjectClass *klass, void *data)
diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c
index 7b10a04..28f5991 100644
--- a/hw/char/terminal3270.c
+++ b/hw/char/terminal3270.c
@@ -179,7 +179,7 @@ static void terminal_init(EmulatedCcw3270Device *dev, Error **errp)
}
terminal_available = true;
qemu_chr_fe_set_handlers(&t->chr, terminal_can_read,
- terminal_read, chr_event, t, NULL, true);
+ terminal_read, chr_event, NULL, t, NULL, true);
}
static int read_payload_3270(EmulatedCcw3270Device *dev, uint32_t cda,
@@ -239,7 +239,7 @@ static int write_payload_3270(EmulatedCcw3270Device *dev, uint8_t cmd,
return 0;
}
}
- if (!qemu_chr_fe_get_driver(&t->chr)) {
+ if (!qemu_chr_fe_backend_connected(&t->chr)) {
/* We just say we consumed all data if there's no backend. */
return count;
}
diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index 0cb1668..198b2a8 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -49,7 +49,7 @@ static ssize_t flush_buf(VirtIOSerialPort *port,
VirtConsole *vcon = VIRTIO_CONSOLE(port);
ssize_t ret;
- if (!qemu_chr_fe_get_driver(&vcon->chr)) {
+ if (!qemu_chr_fe_backend_connected(&vcon->chr)) {
/* If there's no backend, we can just say we consumed all data. */
return len;
}
@@ -163,12 +163,35 @@ static void chr_event(void *opaque, int event)
}
}
+static int chr_be_change(void *opaque)
+{
+ VirtConsole *vcon = opaque;
+ VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(vcon);
+ VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
+
+ if (k->is_console) {
+ qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
+ NULL, chr_be_change, vcon, NULL, true);
+ } else {
+ qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
+ chr_event, chr_be_change, vcon, NULL, false);
+ }
+
+ if (vcon->watch) {
+ g_source_remove(vcon->watch);
+ vcon->watch = qemu_chr_fe_add_watch(&vcon->chr,
+ G_IO_OUT | G_IO_HUP,
+ chr_write_unblocked, vcon);
+ }
+
+ return 0;
+}
+
static void virtconsole_realize(DeviceState *dev, Error **errp)
{
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
VirtConsole *vcon = VIRTIO_CONSOLE(dev);
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
- Chardev *chr = qemu_chr_fe_get_driver(&vcon->chr);
if (port->id == 0 && !k->is_console) {
error_setg(errp, "Port number 0 on virtio-serial devices reserved "
@@ -176,7 +199,7 @@ static void virtconsole_realize(DeviceState *dev, Error **errp)
return;
}
- if (chr) {
+ if (qemu_chr_fe_backend_connected(&vcon->chr)) {
/*
* For consoles we don't block guest data transfer just
* because nothing is connected - we'll just let it go
@@ -188,11 +211,13 @@ static void virtconsole_realize(DeviceState *dev, Error **errp)
*/
if (k->is_console) {
qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
- NULL, vcon, NULL, true);
+ NULL, chr_be_change,
+ vcon, NULL, true);
virtio_serial_open(port);
} else {
qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
- chr_event, vcon, NULL, false);
+ chr_event, chr_be_change,
+ vcon, NULL, false);
}
}
}
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index f9af8ca..3643dfe 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -150,7 +150,7 @@ static void xencons_send(struct XenConsole *con)
ssize_t len, size;
size = con->buffer.size - con->buffer.consumed;
- if (qemu_chr_fe_get_driver(&con->chr)) {
+ if (qemu_chr_fe_backend_connected(&con->chr)) {
len = qemu_chr_fe_write(&con->chr,
con->buffer.data + con->buffer.consumed,
size);
@@ -246,7 +246,7 @@ static int con_initialise(struct XenDevice *xendev)
xen_be_bind_evtchn(&con->xendev);
qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive,
- xencons_receive, NULL, con, NULL, true);
+ xencons_receive, NULL, NULL, con, NULL, true);
xen_pv_printf(xendev, 1,
"ring mfn %d, remote port %d, local port %d, limit %zd\n",
diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c
index 71ed2fc..2a8bc1e 100644
--- a/hw/char/xilinx_uartlite.c
+++ b/hw/char/xilinx_uartlite.c
@@ -212,7 +212,7 @@ static void xilinx_uartlite_realize(DeviceState *dev, Error **errp)
XilinxUARTLite *s = XILINX_UARTLITE(dev);
qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
- uart_event, s, NULL, true);
+ uart_event, NULL, s, NULL, true);
}
static void xilinx_uartlite_init(Object *obj)
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 3bef419..ec10da7 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -159,7 +159,7 @@ static void set_drive(Object *obj, Visitor *v, const char *name, void *opaque,
set_pointer(obj, v, opaque, parse_drive, name, errp);
}
-PropertyInfo qdev_prop_drive = {
+const PropertyInfo qdev_prop_drive = {
.name = "str",
.description = "Node name or ID of a block device to use as a backend",
.get = get_drive,
@@ -228,7 +228,7 @@ static void release_chr(Object *obj, const char *name, void *opaque)
qemu_chr_fe_deinit(be, false);
}
-PropertyInfo qdev_prop_chr = {
+const PropertyInfo qdev_prop_chr = {
.name = "str",
.description = "ID of a chardev to use as a backend",
.get = get_chr,
@@ -313,7 +313,7 @@ out:
g_free(str);
}
-PropertyInfo qdev_prop_netdev = {
+const PropertyInfo qdev_prop_netdev = {
.name = "str",
.description = "ID of a netdev to use as a backend",
.get = get_netdev,
@@ -393,7 +393,7 @@ static void set_vlan(Object *obj, Visitor *v, const char *name, void *opaque,
*ptr = hubport;
}
-PropertyInfo qdev_prop_vlan = {
+const PropertyInfo qdev_prop_vlan = {
.name = "int32",
.description = "Integer VLAN id to connect to",
.print = print_vlan,
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 3d0bba2..dcecdf0 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -25,7 +25,8 @@ void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
}
}
-void qdev_prop_allow_set_link_before_realize(Object *obj, const char *name,
+void qdev_prop_allow_set_link_before_realize(const Object *obj,
+ const char *name,
Object *val, Error **errp)
{
DeviceState *dev = DEVICE(obj);
@@ -131,7 +132,7 @@ static void set_default_value_bool(Object *obj, const Property *prop)
object_property_set_bool(obj, prop->defval.u, prop->name, &error_abort);
}
-PropertyInfo qdev_prop_bit = {
+const PropertyInfo qdev_prop_bit = {
.name = "bool",
.description = "on/off",
.get = prop_get_bit,
@@ -190,7 +191,7 @@ static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
bit64_prop_set(dev, prop, value);
}
-PropertyInfo qdev_prop_bit64 = {
+const PropertyInfo qdev_prop_bit64 = {
.name = "bool",
.description = "on/off",
.get = prop_get_bit64,
@@ -225,7 +226,7 @@ static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
visit_type_bool(v, name, ptr, errp);
}
-PropertyInfo qdev_prop_bool = {
+const PropertyInfo qdev_prop_bool = {
.name = "bool",
.get = get_bool,
.set = set_bool,
@@ -269,7 +270,7 @@ static void set_default_value_uint(Object *obj, const Property *prop)
object_property_set_uint(obj, prop->defval.u, prop->name, &error_abort);
}
-PropertyInfo qdev_prop_uint8 = {
+const PropertyInfo qdev_prop_uint8 = {
.name = "uint8",
.get = get_uint8,
.set = set_uint8,
@@ -303,7 +304,7 @@ static void set_uint16(Object *obj, Visitor *v, const char *name,
visit_type_uint16(v, name, ptr, errp);
}
-PropertyInfo qdev_prop_uint16 = {
+const PropertyInfo qdev_prop_uint16 = {
.name = "uint16",
.get = get_uint16,
.set = set_uint16,
@@ -362,14 +363,14 @@ static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
visit_type_int32(v, name, ptr, errp);
}
-PropertyInfo qdev_prop_uint32 = {
+const PropertyInfo qdev_prop_uint32 = {
.name = "uint32",
.get = get_uint32,
.set = set_uint32,
.set_default_value = set_default_value_uint,
};
-PropertyInfo qdev_prop_int32 = {
+const PropertyInfo qdev_prop_int32 = {
.name = "int32",
.get = get_int32,
.set = set_int32,
@@ -403,7 +404,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
visit_type_uint64(v, name, ptr, errp);
}
-PropertyInfo qdev_prop_uint64 = {
+const PropertyInfo qdev_prop_uint64 = {
.name = "uint64",
.get = get_uint64,
.set = set_uint64,
@@ -456,7 +457,7 @@ static void set_string(Object *obj, Visitor *v, const char *name,
*ptr = str;
}
-PropertyInfo qdev_prop_string = {
+const PropertyInfo qdev_prop_string = {
.name = "str",
.release = release_string,
.get = get_string,
@@ -466,7 +467,7 @@ PropertyInfo qdev_prop_string = {
/* --- pointer --- */
/* Not a proper property, just for dirty hacks. TODO Remove it! */
-PropertyInfo qdev_prop_ptr = {
+const PropertyInfo qdev_prop_ptr = {
.name = "ptr",
};
@@ -540,7 +541,7 @@ inval:
g_free(str);
}
-PropertyInfo qdev_prop_macaddr = {
+const PropertyInfo qdev_prop_macaddr = {
.name = "str",
.description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
.get = get_mac,
@@ -549,7 +550,7 @@ PropertyInfo qdev_prop_macaddr = {
/* --- on/off/auto --- */
-PropertyInfo qdev_prop_on_off_auto = {
+const PropertyInfo qdev_prop_on_off_auto = {
.name = "OnOffAuto",
.description = "on/off/auto",
.enum_table = OnOffAuto_lookup,
@@ -562,7 +563,7 @@ PropertyInfo qdev_prop_on_off_auto = {
QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
-PropertyInfo qdev_prop_losttickpolicy = {
+const PropertyInfo qdev_prop_losttickpolicy = {
.name = "LostTickPolicy",
.enum_table = LostTickPolicy_lookup,
.get = get_enum,
@@ -574,7 +575,7 @@ PropertyInfo qdev_prop_losttickpolicy = {
QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));
-PropertyInfo qdev_prop_blockdev_on_error = {
+const PropertyInfo qdev_prop_blockdev_on_error = {
.name = "BlockdevOnError",
.description = "Error handling policy, "
"report/ignore/enospc/stop/auto",
@@ -588,7 +589,7 @@ PropertyInfo qdev_prop_blockdev_on_error = {
QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
-PropertyInfo qdev_prop_bios_chs_trans = {
+const PropertyInfo qdev_prop_bios_chs_trans = {
.name = "BiosAtaTranslation",
.description = "Logical CHS translation algorithm, "
"auto/none/lba/large/rechs",
@@ -600,7 +601,7 @@ PropertyInfo qdev_prop_bios_chs_trans = {
/* --- FDC default drive types */
-PropertyInfo qdev_prop_fdc_drive_type = {
+const PropertyInfo qdev_prop_fdc_drive_type = {
.name = "FdcDriveType",
.description = "FDC drive type, "
"144/288/120/none/auto",
@@ -676,7 +677,7 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
}
}
-PropertyInfo qdev_prop_pci_devfn = {
+const PropertyInfo qdev_prop_pci_devfn = {
.name = "int32",
.description = "Slot and optional function number, example: 06.0 or 06",
.print = print_pci_devfn,
@@ -725,7 +726,7 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
*ptr = value;
}
-PropertyInfo qdev_prop_blocksize = {
+const PropertyInfo qdev_prop_blocksize = {
.name = "uint16",
.description = "A power of two between 512 and 32768",
.get = get_uint16,
@@ -840,7 +841,7 @@ inval:
g_free(str);
}
-PropertyInfo qdev_prop_pci_host_devaddr = {
+const PropertyInfo qdev_prop_pci_host_devaddr = {
.name = "str",
.description = "Address (bus/device/function) of "
"the host device, example: 04:10.0",
@@ -949,7 +950,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
}
}
-PropertyInfo qdev_prop_arraylen = {
+const PropertyInfo qdev_prop_arraylen = {
.name = "uint32",
.get = get_uint32,
.set = set_prop_arraylen,
@@ -1207,9 +1208,27 @@ static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
visit_type_size(v, name, ptr, errp);
}
-PropertyInfo qdev_prop_size = {
+const PropertyInfo qdev_prop_size = {
.name = "size",
.get = get_size,
.set = set_size,
.set_default_value = set_default_value_uint,
};
+
+/* --- object link property --- */
+
+static void create_link_property(Object *obj, Property *prop, Error **errp)
+{
+ Object **child = qdev_get_prop_ptr(DEVICE(obj), prop);
+
+ object_property_add_link(obj, prop->name, prop->link_type,
+ child,
+ qdev_prop_allow_set_link_before_realize,
+ OBJ_PROP_LINK_UNREF_ON_RELEASE,
+ errp);
+}
+
+const PropertyInfo qdev_prop_link = {
+ .name = "link",
+ .create = create_link_property,
+};
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 849952a..ec63fe0 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -744,6 +744,10 @@ static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
return;
}
+ if (prop->info->create) {
+ return;
+ }
+
name = g_strdup_printf("legacy-%s", prop->name);
object_property_add(OBJECT(dev), name, "str",
prop->info->print ? qdev_get_legacy_property : prop->info->get,
@@ -770,20 +774,23 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
Error *local_err = NULL;
Object *obj = OBJECT(dev);
- /*
- * TODO qdev_prop_ptr does not have getters or setters. It must
- * go now that it can be replaced with links. The test should be
- * removed along with it: all static properties are read/write.
- */
- if (!prop->info->get && !prop->info->set) {
- return;
+ if (prop->info->create) {
+ prop->info->create(obj, prop, &local_err);
+ } else {
+ /*
+ * TODO qdev_prop_ptr does not have getters or setters. It must
+ * go now that it can be replaced with links. The test should be
+ * removed along with it: all static properties are read/write.
+ */
+ if (!prop->info->get && !prop->info->set) {
+ return;
+ }
+ object_property_add(obj, prop->name, prop->info->name,
+ prop->info->get, prop->info->set,
+ prop->info->release,
+ prop, &local_err);
}
- object_property_add(obj, prop->name, prop->info->name,
- prop->info->get, prop->info->set,
- prop->info->release,
- prop, &local_err);
-
if (local_err) {
error_propagate(errp, local_err);
return;
diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
index a77d7db..561f828 100644
--- a/hw/display/xlnx_dp.c
+++ b/hw/display/xlnx_dp.c
@@ -515,7 +515,7 @@ static void xlnx_dp_aux_set_command(XlnxDPState *s, uint32_t value)
s->core_registers[DP_INTERRUPT_SIGNAL_STATE] |= 0x04;
}
-static void xlnx_dp_set_dpdma(Object *obj, const char *name, Object *val,
+static void xlnx_dp_set_dpdma(const Object *obj, const char *name, Object *val,
Error **errp)
{
XlnxDPState *s = XLNX_DP(obj);
diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index edf9432..5d4833e 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -54,6 +54,8 @@ typedef struct dma_pagetable_entry {
#define RC4030(obj) \
OBJECT_CHECK(rc4030State, (obj), TYPE_RC4030)
+#define TYPE_RC4030_IOMMU_MEMORY_REGION "rc4030-iommu-memory-region"
+
typedef struct rc4030State
{
SysBusDevice parent;
@@ -90,7 +92,7 @@ typedef struct rc4030State
qemu_irq jazz_bus_irq;
/* whole DMA memory region, root of DMA address space */
- MemoryRegion dma_mr;
+ IOMMUMemoryRegion dma_mr;
AddressSpace dma_as;
MemoryRegion iomem_chipset;
@@ -488,7 +490,7 @@ static const MemoryRegionOps jazzio_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static IOMMUTLBEntry rc4030_dma_translate(MemoryRegion *iommu, hwaddr addr,
+static IOMMUTLBEntry rc4030_dma_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
IOMMUAccessFlags flag)
{
rc4030State *s = container_of(iommu, rc4030State, dma_mr);
@@ -516,10 +518,6 @@ static IOMMUTLBEntry rc4030_dma_translate(MemoryRegion *iommu, hwaddr addr,
return ret;
}
-static const MemoryRegionIOMMUOps rc4030_dma_ops = {
- .translate = rc4030_dma_translate,
-};
-
static void rc4030_reset(DeviceState *dev)
{
rc4030State *s = RC4030(dev);
@@ -677,9 +675,10 @@ static void rc4030_realize(DeviceState *dev, Error **errp)
memory_region_init_io(&s->iomem_jazzio, NULL, &jazzio_ops, s,
"rc4030.jazzio", 0x00001000);
- memory_region_init_iommu(&s->dma_mr, o, &rc4030_dma_ops,
- "rc4030.dma", UINT32_MAX);
- address_space_init(&s->dma_as, &s->dma_mr, "rc4030-dma");
+ memory_region_init_iommu(&s->dma_mr, sizeof(s->dma_mr),
+ TYPE_RC4030_IOMMU_MEMORY_REGION,
+ o, "rc4030.dma", UINT32_MAX);
+ address_space_init(&s->dma_as, MEMORY_REGION(&s->dma_mr), "rc4030-dma");
}
static void rc4030_unrealize(DeviceState *dev, Error **errp)
@@ -710,14 +709,29 @@ static const TypeInfo rc4030_info = {
.class_init = rc4030_class_init,
};
+static void rc4030_iommu_memory_region_class_init(ObjectClass *klass,
+ void *data)
+{
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
+
+ imrc->translate = rc4030_dma_translate;
+}
+
+static const TypeInfo rc4030_iommu_memory_region_info = {
+ .parent = TYPE_IOMMU_MEMORY_REGION,
+ .name = TYPE_RC4030_IOMMU_MEMORY_REGION,
+ .class_init = rc4030_iommu_memory_region_class_init,
+};
+
static void rc4030_register_types(void)
{
type_register_static(&rc4030_info);
+ type_register_static(&rc4030_iommu_memory_region_info);
}
type_init(rc4030_register_types)
-DeviceState *rc4030_init(rc4030_dma **dmas, MemoryRegion **dma_mr)
+DeviceState *rc4030_init(rc4030_dma **dmas, IOMMUMemoryRegion **dma_mr)
{
DeviceState *dev;
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index d93ffc2..334938a 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -52,7 +52,7 @@ struct AMDVIAddressSpace {
uint8_t bus_num; /* bus number */
uint8_t devfn; /* device function */
AMDVIState *iommu_state; /* AMDVI - one per machine */
- MemoryRegion iommu; /* Device's address translation region */
+ IOMMUMemoryRegion iommu; /* Device's address translation region */
MemoryRegion iommu_ir; /* Device's interrupt remapping region */
AddressSpace as; /* device's corresponding address space */
};
@@ -987,7 +987,7 @@ static inline bool amdvi_is_interrupt_addr(hwaddr addr)
return addr >= AMDVI_INT_ADDR_FIRST && addr <= AMDVI_INT_ADDR_LAST;
}
-static IOMMUTLBEntry amdvi_translate(MemoryRegion *iommu, hwaddr addr,
+static IOMMUTLBEntry amdvi_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
IOMMUAccessFlags flag)
{
AMDVIAddressSpace *as = container_of(iommu, AMDVIAddressSpace, iommu);
@@ -1044,9 +1044,13 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
iommu_as[devfn]->devfn = (uint8_t)devfn;
iommu_as[devfn]->iommu_state = s;
- memory_region_init_iommu(&iommu_as[devfn]->iommu, OBJECT(s),
- &s->iommu_ops, "amd-iommu", UINT64_MAX);
- address_space_init(&iommu_as[devfn]->as, &iommu_as[devfn]->iommu,
+ memory_region_init_iommu(&iommu_as[devfn]->iommu,
+ sizeof(iommu_as[devfn]->iommu),
+ TYPE_AMD_IOMMU_MEMORY_REGION,
+ OBJECT(s),
+ "amd-iommu", UINT64_MAX);
+ address_space_init(&iommu_as[devfn]->as,
+ MEMORY_REGION(&iommu_as[devfn]->iommu),
"amd-iommu");
}
return &iommu_as[devfn]->as;
@@ -1067,7 +1071,7 @@ static const MemoryRegionOps mmio_mem_ops = {
}
};
-static void amdvi_iommu_notify_flag_changed(MemoryRegion *iommu,
+static void amdvi_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
IOMMUNotifierFlag old,
IOMMUNotifierFlag new)
{
@@ -1085,8 +1089,6 @@ static void amdvi_init(AMDVIState *s)
{
amdvi_iotlb_reset(s);
- s->iommu_ops.translate = amdvi_translate;
- s->iommu_ops.notify_flag_changed = amdvi_iommu_notify_flag_changed;
s->devtab_len = 0;
s->cmdbuf_len = 0;
s->cmdbuf_head = 0;
@@ -1227,10 +1229,25 @@ static const TypeInfo amdviPCI = {
.instance_size = sizeof(AMDVIPCIState),
};
+static void amdvi_iommu_memory_region_class_init(ObjectClass *klass, void *data)
+{
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
+
+ imrc->translate = amdvi_translate;
+ imrc->notify_flag_changed = amdvi_iommu_notify_flag_changed;
+}
+
+static const TypeInfo amdvi_iommu_memory_region_info = {
+ .parent = TYPE_IOMMU_MEMORY_REGION,
+ .name = TYPE_AMD_IOMMU_MEMORY_REGION,
+ .class_init = amdvi_iommu_memory_region_class_init,
+};
+
static void amdviPCI_register_types(void)
{
type_register_static(&amdviPCI);
type_register_static(&amdvi);
+ type_register_static(&amdvi_iommu_memory_region_info);
}
type_init(amdviPCI_register_types);
diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h
index 0d3dc6a..d370ae3 100644
--- a/hw/i386/amd_iommu.h
+++ b/hw/i386/amd_iommu.h
@@ -220,6 +220,8 @@
#define TYPE_AMD_IOMMU_PCI "AMDVI-PCI"
+#define TYPE_AMD_IOMMU_MEMORY_REGION "amd-iommu-iommu-memory-region"
+
typedef struct AMDVIAddressSpace AMDVIAddressSpace;
/* functions to steal PCI config space */
@@ -276,9 +278,6 @@ typedef struct AMDVIState {
uint8_t romask[AMDVI_MMIO_SIZE]; /* MMIO read/only mask */
bool mmio_enabled;
- /* IOMMU function */
- MemoryRegionIOMMUOps iommu_ops;
-
/* for each served device */
AMDVIAddressSpace **address_spaces[PCI_BUS_MAX];
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 88dc042..e398746 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -972,9 +972,9 @@ static bool vtd_switch_address_space(VTDAddressSpace *as)
/* Turn off first then on the other */
if (use_iommu) {
memory_region_set_enabled(&as->sys_alias, false);
- memory_region_set_enabled(&as->iommu, true);
+ memory_region_set_enabled(MEMORY_REGION(&as->iommu), true);
} else {
- memory_region_set_enabled(&as->iommu, false);
+ memory_region_set_enabled(MEMORY_REGION(&as->iommu), false);
memory_region_set_enabled(&as->sys_alias, true);
}
@@ -1366,7 +1366,7 @@ static void vtd_iotlb_domain_invalidate(IntelIOMMUState *s, uint16_t domain_id)
static int vtd_page_invalidate_notify_hook(IOMMUTLBEntry *entry,
void *private)
{
- memory_region_notify_iommu((MemoryRegion *)private, *entry);
+ memory_region_notify_iommu((IOMMUMemoryRegion *)private, *entry);
return 0;
}
@@ -2264,7 +2264,7 @@ static void vtd_mem_write(void *opaque, hwaddr addr,
}
}
-static IOMMUTLBEntry vtd_iommu_translate(MemoryRegion *iommu, hwaddr addr,
+static IOMMUTLBEntry vtd_iommu_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
IOMMUAccessFlags flag)
{
VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
@@ -2303,7 +2303,7 @@ static IOMMUTLBEntry vtd_iommu_translate(MemoryRegion *iommu, hwaddr addr,
return iotlb;
}
-static void vtd_iommu_notify_flag_changed(MemoryRegion *iommu,
+static void vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
IOMMUNotifierFlag old,
IOMMUNotifierFlag new)
{
@@ -2718,8 +2718,9 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
* vtd_sys_alias and intel_iommu regions. IR region is always
* enabled.
*/
- memory_region_init_iommu(&vtd_dev_as->iommu, OBJECT(s),
- &s->iommu_ops, "intel_iommu_dmar",
+ memory_region_init_iommu(&vtd_dev_as->iommu, sizeof(vtd_dev_as->iommu),
+ TYPE_INTEL_IOMMU_MEMORY_REGION, OBJECT(s),
+ "intel_iommu_dmar",
UINT64_MAX);
memory_region_init_alias(&vtd_dev_as->sys_alias, OBJECT(s),
"vtd_sys_alias", get_system_memory(),
@@ -2736,7 +2737,8 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
memory_region_add_subregion_overlap(&vtd_dev_as->root, 0,
&vtd_dev_as->sys_alias, 1);
memory_region_add_subregion_overlap(&vtd_dev_as->root, 0,
- &vtd_dev_as->iommu, 1);
+ MEMORY_REGION(&vtd_dev_as->iommu),
+ 1);
vtd_switch_address_space(vtd_dev_as);
}
return vtd_dev_as;
@@ -2816,9 +2818,9 @@ static int vtd_replay_hook(IOMMUTLBEntry *entry, void *private)
return 0;
}
-static void vtd_iommu_replay(MemoryRegion *mr, IOMMUNotifier *n)
+static void vtd_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n)
{
- VTDAddressSpace *vtd_as = container_of(mr, VTDAddressSpace, iommu);
+ VTDAddressSpace *vtd_as = container_of(iommu_mr, VTDAddressSpace, iommu);
IntelIOMMUState *s = vtd_as->iommu_state;
uint8_t bus_n = pci_bus_num(vtd_as->bus);
VTDContextEntry ce;
@@ -2856,9 +2858,6 @@ static void vtd_init(IntelIOMMUState *s)
memset(s->w1cmask, 0, DMAR_REG_SIZE);
memset(s->womask, 0, DMAR_REG_SIZE);
- s->iommu_ops.translate = vtd_iommu_translate;
- s->iommu_ops.notify_flag_changed = vtd_iommu_notify_flag_changed;
- s->iommu_ops.replay = vtd_iommu_replay;
s->root = 0;
s->root_extended = false;
s->dmar_enabled = false;
@@ -3073,9 +3072,26 @@ static const TypeInfo vtd_info = {
.class_init = vtd_class_init,
};
+static void vtd_iommu_memory_region_class_init(ObjectClass *klass,
+ void *data)
+{
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
+
+ imrc->translate = vtd_iommu_translate;
+ imrc->notify_flag_changed = vtd_iommu_notify_flag_changed;
+ imrc->replay = vtd_iommu_replay;
+}
+
+static const TypeInfo vtd_iommu_memory_region_info = {
+ .parent = TYPE_IOMMU_MEMORY_REGION,
+ .name = TYPE_INTEL_IOMMU_MEMORY_REGION,
+ .class_init = vtd_iommu_memory_region_class_init,
+};
+
static void vtd_register_types(void)
{
type_register_static(&vtd_info);
+ type_register_static(&vtd_iommu_memory_region_info);
}
type_init(vtd_register_types)
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 0d9ef77..fc962c5 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -383,8 +383,7 @@ static void patch_byte(X86CPU *cpu, target_ulong addr, uint8_t byte)
cpu_memory_rw_debug(CPU(cpu), addr, &byte, 1, 1);
}
-static void patch_call(VAPICROMState *s, X86CPU *cpu, target_ulong ip,
- uint32_t target)
+static void patch_call(X86CPU *cpu, target_ulong ip, uint32_t target)
{
uint32_t offset;
@@ -393,77 +392,71 @@ static void patch_call(VAPICROMState *s, X86CPU *cpu, target_ulong ip,
cpu_memory_rw_debug(CPU(cpu), ip + 1, (void *)&offset, sizeof(offset), 1);
}
-static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
+typedef struct PatchInfo {
+ VAPICHandlers *handler;
+ target_ulong ip;
+} PatchInfo;
+
+static void do_patch_instruction(CPUState *cs, run_on_cpu_data data)
{
- CPUState *cs = CPU(cpu);
- CPUX86State *env = &cpu->env;
- VAPICHandlers *handlers;
+ X86CPU *x86_cpu = X86_CPU(cs);
+ PatchInfo *info = (PatchInfo *) data.host_ptr;
+ VAPICHandlers *handlers = info->handler;
+ target_ulong ip = info->ip;
uint8_t opcode[2];
uint32_t imm32 = 0;
- target_ulong current_pc = 0;
- target_ulong current_cs_base = 0;
- uint32_t current_flags = 0;
-
- if (smp_cpus == 1) {
- handlers = &s->rom_state.up;
- } else {
- handlers = &s->rom_state.mp;
- }
-
- if (tcg_enabled()) {
- cpu_restore_state(cs, cs->mem_io_pc);
- cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
- &current_flags);
- /* Account this instruction, because we will exit the tb.
- This is the first instruction in the block. Therefore
- there is no need in restoring CPU state. */
- if (use_icount) {
- --cs->icount_decr.u16.low;
- }
- }
-
- pause_all_vcpus();
cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0);
switch (opcode[0]) {
case 0x89: /* mov r32 to r/m32 */
- patch_byte(cpu, ip, 0x50 + modrm_reg(opcode[1])); /* push reg */
- patch_call(s, cpu, ip + 1, handlers->set_tpr);
+ patch_byte(x86_cpu, ip, 0x50 + modrm_reg(opcode[1])); /* push reg */
+ patch_call(x86_cpu, ip + 1, handlers->set_tpr);
break;
case 0x8b: /* mov r/m32 to r32 */
- patch_byte(cpu, ip, 0x90);
- patch_call(s, cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
+ patch_byte(x86_cpu, ip, 0x90);
+ patch_call(x86_cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
break;
case 0xa1: /* mov abs to eax */
- patch_call(s, cpu, ip, handlers->get_tpr[0]);
+ patch_call(x86_cpu, ip, handlers->get_tpr[0]);
break;
case 0xa3: /* mov eax to abs */
- patch_call(s, cpu, ip, handlers->set_tpr_eax);
+ patch_call(x86_cpu, ip, handlers->set_tpr_eax);
break;
case 0xc7: /* mov imm32, r/m32 (c7/0) */
- patch_byte(cpu, ip, 0x68); /* push imm32 */
+ patch_byte(x86_cpu, ip, 0x68); /* push imm32 */
cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), 0);
cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), 1);
- patch_call(s, cpu, ip + 5, handlers->set_tpr);
+ patch_call(x86_cpu, ip + 5, handlers->set_tpr);
break;
case 0xff: /* push r/m32 */
- patch_byte(cpu, ip, 0x50); /* push eax */
- patch_call(s, cpu, ip + 1, handlers->get_tpr_stack);
+ patch_byte(x86_cpu, ip, 0x50); /* push eax */
+ patch_call(x86_cpu, ip + 1, handlers->get_tpr_stack);
break;
default:
abort();
}
- resume_all_vcpus();
+ g_free(info);
+}
+
+static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
+{
+ CPUState *cs = CPU(cpu);
+ VAPICHandlers *handlers;
+ PatchInfo *info;
- if (tcg_enabled()) {
- /* Both tb_lock and iothread_mutex will be reset when
- * longjmps back into the cpu_exec loop. */
- tb_lock();
- tb_gen_code(cs, current_pc, current_cs_base, current_flags, 1);
- cpu_loop_exit_noexc(cs);
+ if (smp_cpus == 1) {
+ handlers = &s->rom_state.up;
+ } else {
+ handlers = &s->rom_state.mp;
}
+
+ info = g_new(PatchInfo, 1);
+ info->handler = handlers;
+ info->ip = ip;
+
+ async_safe_run_on_cpu(cs, do_patch_instruction, RUN_ON_CPU_HOST_PTR(info));
}
void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c
index afafe14..b27babd 100644
--- a/hw/ipmi/ipmi.c
+++ b/hw/ipmi/ipmi.c
@@ -90,7 +90,7 @@ static TypeInfo ipmi_interface_type_info = {
.class_init = ipmi_interface_class_init,
};
-static void isa_ipmi_bmc_check(Object *obj, const char *name,
+static void isa_ipmi_bmc_check(const Object *obj, const char *name,
Object *val, Error **errp)
{
IPMIBmc *bmc = IPMI_BMC(val);
diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
index 329b03e..abab3bb 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -447,13 +447,13 @@ static void ipmi_bmc_extern_realize(DeviceState *dev, Error **errp)
{
IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev);
- if (!qemu_chr_fe_get_driver(&ibe->chr)) {
+ if (!qemu_chr_fe_backend_connected(&ibe->chr)) {
error_setg(errp, "IPMI external bmc requires chardev attribute");
return;
}
qemu_chr_fe_set_handlers(&ibe->chr, can_receive, receive,
- chr_event, ibe, NULL, true);
+ chr_event, NULL, ibe, NULL, true);
}
static int ipmi_bmc_extern_post_migrate(void *opaque, int version_id)
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index b72258e..ea67b46 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -350,6 +350,8 @@ static Property pc_dimm_properties[] = {
DEFINE_PROP_UINT32(PC_DIMM_NODE_PROP, PCDIMMDevice, node, 0),
DEFINE_PROP_INT32(PC_DIMM_SLOT_PROP, PCDIMMDevice, slot,
PC_DIMM_UNASSIGNED_SLOT),
+ DEFINE_PROP_LINK(PC_DIMM_MEMDEV_PROP, PCDIMMDevice, hostmem,
+ TYPE_MEMORY_BACKEND, HostMemoryBackend *),
DEFINE_PROP_END_OF_LIST(),
};
@@ -367,33 +369,10 @@ static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name,
visit_type_uint64(v, name, &value, errp);
}
-static void pc_dimm_check_memdev_is_busy(Object *obj, const char *name,
- Object *val, Error **errp)
-{
- Error *local_err = NULL;
-
- if (host_memory_backend_is_mapped(MEMORY_BACKEND(val))) {
- char *path = object_get_canonical_path_component(val);
- error_setg(&local_err, "can't use already busy memdev: %s", path);
- g_free(path);
- } else {
- qdev_prop_allow_set_link_before_realize(obj, name, val, &local_err);
- }
-
- error_propagate(errp, local_err);
-}
-
static void pc_dimm_init(Object *obj)
{
- PCDIMMDevice *dimm = PC_DIMM(obj);
-
object_property_add(obj, PC_DIMM_SIZE_PROP, "uint64", pc_dimm_get_size,
NULL, NULL, NULL, &error_abort);
- object_property_add_link(obj, PC_DIMM_MEMDEV_PROP, TYPE_MEMORY_BACKEND,
- (Object **)&dimm->hostmem,
- pc_dimm_check_memdev_is_busy,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
}
static void pc_dimm_realize(DeviceState *dev, Error **errp)
@@ -404,6 +383,11 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp)
if (!dimm->hostmem) {
error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property is not set");
return;
+ } else if (host_memory_backend_is_mapped(dimm->hostmem)) {
+ char *path = object_get_canonical_path_component(OBJECT(dimm->hostmem));
+ error_setg(errp, "can't use already busy memdev: %s", path);
+ g_free(path);
+ return;
}
if (((nb_numa_nodes > 0) && (dimm->node >= nb_numa_nodes)) ||
(!nb_numa_nodes && dimm->node)) {
diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index a4677f7..146be2a 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -533,7 +533,7 @@ static void boston_mach_init(MachineState *machine)
chr = qemu_chr_new("lcd", "vc:320x240");
qemu_chr_fe_init(&s->lcd_display, chr, NULL);
qemu_chr_fe_set_handlers(&s->lcd_display, NULL, NULL,
- boston_lcd_event, s, NULL, true);
+ boston_lcd_event, NULL, s, NULL, true);
ahci = pci_create_simple_multifunction(&PCI_BRIDGE(&pcie2->root)->sec_bus,
PCI_DEVFN(0, 0),
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 1cef581..1f69322 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -130,7 +130,7 @@ static void mips_jazz_init(MachineState *machine,
CPUMIPSState *env;
qemu_irq *i8259;
rc4030_dma *dmas;
- MemoryRegion *rc4030_dma_mr;
+ IOMMUMemoryRegion *rc4030_dma_mr;
MemoryRegion *isa_mem = g_new(MemoryRegion, 1);
MemoryRegion *isa_io = g_new(MemoryRegion, 1);
MemoryRegion *rtc = g_new(MemoryRegion, 1);
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index dad2f37..8cb9d3c 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -570,7 +570,7 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
chr = qemu_chr_new("fpga", "vc:320x200");
qemu_chr_fe_init(&s->display, chr, NULL);
qemu_chr_fe_set_handlers(&s->display, NULL, NULL,
- malta_fgpa_display_event, s, NULL, true);
+ malta_fgpa_display_event, NULL, s, NULL, true);
s->uart = serial_mm_init(address_space, base + 0x900, 3, uart_irq,
230400, uart_chr, DEVICE_NATIVE_ENDIAN);
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 2f0819d..a58f9ee 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -894,7 +894,7 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
}
qemu_chr_fe_set_handlers(&s->server_chr, ivshmem_can_receive,
- ivshmem_read, NULL, s, NULL, true);
+ ivshmem_read, NULL, NULL, s, NULL, true);
if (ivshmem_setup_interrupts(s, errp) < 0) {
error_prepend(errp, "Failed to initialize interrupts: ");
@@ -1009,18 +1009,6 @@ static const TypeInfo ivshmem_common_info = {
.class_init = ivshmem_common_class_init,
};
-static void ivshmem_check_memdev_is_busy(Object *obj, const char *name,
- Object *val, Error **errp)
-{
- if (host_memory_backend_is_mapped(MEMORY_BACKEND(val))) {
- char *path = object_get_canonical_path_component(val);
- error_setg(errp, "can't use already busy memdev: %s", path);
- g_free(path);
- } else {
- qdev_prop_allow_set_link_before_realize(obj, name, val, errp);
- }
-}
-
static const VMStateDescription ivshmem_plain_vmsd = {
.name = TYPE_IVSHMEM_PLAIN,
.version_id = 0,
@@ -1037,6 +1025,8 @@ static const VMStateDescription ivshmem_plain_vmsd = {
static Property ivshmem_plain_properties[] = {
DEFINE_PROP_ON_OFF_AUTO("master", IVShmemState, master, ON_OFF_AUTO_OFF),
+ DEFINE_PROP_LINK("memdev", IVShmemState, hostmem, TYPE_MEMORY_BACKEND,
+ HostMemoryBackend *),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1044,11 +1034,6 @@ static void ivshmem_plain_init(Object *obj)
{
IVShmemState *s = IVSHMEM_PLAIN(obj);
- object_property_add_link(obj, "memdev", TYPE_MEMORY_BACKEND,
- (Object **)&s->hostmem,
- ivshmem_check_memdev_is_busy,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
s->not_legacy_32bit = 1;
}
@@ -1059,6 +1044,11 @@ static void ivshmem_plain_realize(PCIDevice *dev, Error **errp)
if (!s->hostmem) {
error_setg(errp, "You must specify a 'memdev'");
return;
+ } else if (host_memory_backend_is_mapped(s->hostmem)) {
+ char *path = object_get_canonical_path_component(OBJECT(s->hostmem));
+ error_setg(errp, "can't use already busy memdev: %s", path);
+ g_free(path);
+ return;
}
ivshmem_common_realize(dev, errp);
@@ -1128,7 +1118,7 @@ static void ivshmem_doorbell_realize(PCIDevice *dev, Error **errp)
{
IVShmemState *s = IVSHMEM_COMMON(dev);
- if (!qemu_chr_fe_get_driver(&s->server_chr)) {
+ if (!qemu_chr_fe_backend_connected(&s->server_chr)) {
error_setg(errp, "You must specify a 'chardev'");
return;
}
@@ -1257,7 +1247,7 @@ static void ivshmem_realize(PCIDevice *dev, Error **errp)
" or ivshmem-doorbell instead");
}
- if (!!qemu_chr_fe_get_driver(&s->server_chr) + !!s->shmobj != 1) {
+ if (qemu_chr_fe_backend_connected(&s->server_chr) + !!s->shmobj != 1) {
error_setg(errp, "You must specify either 'shm' or 'chardev'");
return;
}
diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c
index a1edb53..211f609 100644
--- a/hw/misc/mips_cmgcr.c
+++ b/hw/misc/mips_cmgcr.c
@@ -181,18 +181,6 @@ static void mips_gcr_init(Object *obj)
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
MIPSGCRState *s = MIPS_GCR(obj);
- object_property_add_link(obj, "gic", TYPE_MEMORY_REGION,
- (Object **)&s->gic_mr,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
-
- object_property_add_link(obj, "cpc", TYPE_MEMORY_REGION,
- (Object **)&s->cpc_mr,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
-
memory_region_init_io(&s->iomem, OBJECT(s), &gcr_ops, s,
"mips-gcr", GCR_ADDRSPACE_SZ);
sysbus_init_mmio(sbd, &s->iomem);
@@ -227,6 +215,10 @@ static Property mips_gcr_properties[] = {
DEFINE_PROP_INT32("num-vp", MIPSGCRState, num_vps, 1),
DEFINE_PROP_INT32("gcr-rev", MIPSGCRState, gcr_rev, 0x800),
DEFINE_PROP_UINT64("gcr-base", MIPSGCRState, gcr_base, GCR_BASE_ADDR),
+ DEFINE_PROP_LINK("gic", MIPSGCRState, gic_mr, TYPE_MEMORY_REGION,
+ MemoryRegion *),
+ DEFINE_PROP_LINK("cpc", MIPSGCRState, cpc_mr, TYPE_MEMORY_REGION,
+ MemoryRegion *),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
index 326f5ef..96e5d0b 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/apb.c
@@ -123,7 +123,7 @@ do { printf("IOMMU: " fmt , ## __VA_ARGS__); } while (0)
typedef struct IOMMUState {
AddressSpace iommu_as;
- MemoryRegion iommu;
+ IOMMUMemoryRegion iommu;
uint64_t regs[IOMMU_NREGS];
} IOMMUState;
@@ -133,6 +133,8 @@ typedef struct IOMMUState {
#define APB_DEVICE(obj) \
OBJECT_CHECK(APBState, (obj), TYPE_APB)
+#define TYPE_APB_IOMMU_MEMORY_REGION "pbm-iommu-memory-region"
+
typedef struct APBState {
PCIHostState parent_obj;
@@ -208,7 +210,7 @@ static AddressSpace *pbm_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
}
/* Called from RCU critical section */
-static IOMMUTLBEntry pbm_translate_iommu(MemoryRegion *iommu, hwaddr addr,
+static IOMMUTLBEntry pbm_translate_iommu(IOMMUMemoryRegion *iommu, hwaddr addr,
IOMMUAccessFlags flag)
{
IOMMUState *is = container_of(iommu, IOMMUState, iommu);
@@ -322,10 +324,6 @@ static IOMMUTLBEntry pbm_translate_iommu(MemoryRegion *iommu, hwaddr addr,
return ret;
}
-static MemoryRegionIOMMUOps pbm_iommu_ops = {
- .translate = pbm_translate_iommu,
-};
-
static void iommu_config_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
@@ -697,9 +695,10 @@ PCIBus *pci_apb_init(hwaddr special_base,
is = &d->iommu;
memset(is, 0, sizeof(IOMMUState));
- memory_region_init_iommu(&is->iommu, OBJECT(dev), &pbm_iommu_ops,
+ memory_region_init_iommu(&is->iommu, sizeof(is->iommu),
+ TYPE_APB_IOMMU_MEMORY_REGION, OBJECT(dev),
"iommu-apb", UINT64_MAX);
- address_space_init(&is->iommu_as, &is->iommu, "pbm-as");
+ address_space_init(&is->iommu_as, MEMORY_REGION(&is->iommu), "pbm-as");
pci_setup_iommu(phb->bus, pbm_pci_dma_iommu, is);
/* APB secondary busses */
@@ -860,11 +859,25 @@ static const TypeInfo pbm_pci_bridge_info = {
.class_init = pbm_pci_bridge_class_init,
};
+static void pbm_iommu_memory_region_class_init(ObjectClass *klass, void *data)
+{
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
+
+ imrc->translate = pbm_translate_iommu;
+}
+
+static const TypeInfo pbm_iommu_memory_region_info = {
+ .parent = TYPE_IOMMU_MEMORY_REGION,
+ .name = TYPE_APB_IOMMU_MEMORY_REGION,
+ .class_init = pbm_iommu_memory_region_class_init,
+};
+
static void pbm_register_types(void)
{
type_register_static(&pbm_host_info);
type_register_static(&pbm_pci_host_info);
type_register_static(&pbm_pci_bridge_info);
+ type_register_static(&pbm_iommu_memory_region_info);
}
type_init(pbm_register_types)
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 583afc1..e614621 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -110,7 +110,8 @@ static void spapr_tce_free_table(uint64_t *table, int fd, uint32_t nb_table)
}
/* Called from RCU critical section */
-static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr,
+static IOMMUTLBEntry spapr_tce_translate_iommu(IOMMUMemoryRegion *iommu,
+ hwaddr addr,
IOMMUAccessFlags flag)
{
sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
@@ -150,14 +151,14 @@ static void spapr_tce_table_pre_save(void *opaque)
tcet->bus_offset, tcet->page_shift);
}
-static uint64_t spapr_tce_get_min_page_size(MemoryRegion *iommu)
+static uint64_t spapr_tce_get_min_page_size(IOMMUMemoryRegion *iommu)
{
sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
return 1ULL << tcet->page_shift;
}
-static void spapr_tce_notify_flag_changed(MemoryRegion *iommu,
+static void spapr_tce_notify_flag_changed(IOMMUMemoryRegion *iommu,
IOMMUNotifierFlag old,
IOMMUNotifierFlag new)
{
@@ -247,12 +248,6 @@ static const VMStateDescription vmstate_spapr_tce_table = {
}
};
-static MemoryRegionIOMMUOps spapr_iommu_ops = {
- .translate = spapr_tce_translate_iommu,
- .get_min_page_size = spapr_tce_get_min_page_size,
- .notify_flag_changed = spapr_tce_notify_flag_changed,
-};
-
static int spapr_tce_table_realize(DeviceState *dev)
{
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
@@ -265,7 +260,9 @@ static int spapr_tce_table_realize(DeviceState *dev)
memory_region_init(&tcet->root, tcetobj, tmp, UINT64_MAX);
snprintf(tmp, sizeof(tmp), "tce-iommu-%x", tcet->liobn);
- memory_region_init_iommu(&tcet->iommu, tcetobj, &spapr_iommu_ops, tmp, 0);
+ memory_region_init_iommu(&tcet->iommu, sizeof(tcet->iommu),
+ TYPE_SPAPR_IOMMU_MEMORY_REGION,
+ tcetobj, tmp, 0);
QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list);
@@ -348,9 +345,10 @@ void spapr_tce_table_enable(sPAPRTCETable *tcet,
&tcet->fd,
tcet->need_vfio);
- memory_region_set_size(&tcet->iommu,
+ memory_region_set_size(MEMORY_REGION(&tcet->iommu),
(uint64_t)tcet->nb_table << tcet->page_shift);
- memory_region_add_subregion(&tcet->root, tcet->bus_offset, &tcet->iommu);
+ memory_region_add_subregion(&tcet->root, tcet->bus_offset,
+ MEMORY_REGION(&tcet->iommu));
}
void spapr_tce_table_disable(sPAPRTCETable *tcet)
@@ -359,8 +357,8 @@ void spapr_tce_table_disable(sPAPRTCETable *tcet)
return;
}
- memory_region_del_subregion(&tcet->root, &tcet->iommu);
- memory_region_set_size(&tcet->iommu, 0);
+ memory_region_del_subregion(&tcet->root, MEMORY_REGION(&tcet->iommu));
+ memory_region_set_size(MEMORY_REGION(&tcet->iommu), 0);
spapr_tce_free_table(tcet->table, tcet->fd, tcet->nb_table);
tcet->fd = -1;
@@ -637,9 +635,25 @@ static TypeInfo spapr_tce_table_info = {
.class_init = spapr_tce_table_class_init,
};
+static void spapr_iommu_memory_region_class_init(ObjectClass *klass, void *data)
+{
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
+
+ imrc->translate = spapr_tce_translate_iommu;
+ imrc->get_min_page_size = spapr_tce_get_min_page_size;
+ imrc->notify_flag_changed = spapr_tce_notify_flag_changed;
+}
+
+static const TypeInfo spapr_iommu_memory_region_info = {
+ .parent = TYPE_IOMMU_MEMORY_REGION,
+ .name = TYPE_SPAPR_IOMMU_MEMORY_REGION,
+ .class_init = spapr_iommu_memory_region_class_init,
+};
+
static void register_types(void)
{
type_register_static(&spapr_tce_table_info);
+ type_register_static(&spapr_iommu_memory_region_info);
}
type_init(register_types);
diff --git a/hw/ppc/spapr_rng.c b/hw/ppc/spapr_rng.c
index 80515eb..d2acd61 100644
--- a/hw/ppc/spapr_rng.c
+++ b/hw/ppc/spapr_rng.c
@@ -96,17 +96,11 @@ static target_ulong h_random(PowerPCCPU *cpu, sPAPRMachineState *spapr,
static void spapr_rng_instance_init(Object *obj)
{
- sPAPRRngState *rngstate = SPAPR_RNG(obj);
-
if (object_resolve_path_type("", TYPE_SPAPR_RNG, NULL) != NULL) {
error_report("spapr-rng can not be instantiated twice!");
return;
}
- object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
- (Object **)&rngstate->backend,
- object_property_allow_set_link,
- OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
object_property_set_description(obj, "rng",
"ID of the random number generator backend",
NULL);
@@ -163,6 +157,8 @@ int spapr_rng_populate_dt(void *fdt)
static Property spapr_rng_properties[] = {
DEFINE_PROP_BOOL("use-kvm", sPAPRRngState, use_kvm, false),
+ DEFINE_PROP_LINK("rng", sPAPRRngState, backend, TYPE_RNG_BACKEND,
+ RngBackend *),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index d67fffa..cd0b776 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2095,7 +2095,7 @@ out:
g_free(str);
}
-PropertyInfo css_devid_propinfo = {
+const PropertyInfo css_devid_propinfo = {
.name = "str",
.description = "Identifier of an I/O device in the channel "
"subsystem, example: fe.1.23ab",
@@ -2103,7 +2103,7 @@ PropertyInfo css_devid_propinfo = {
.set = set_css_devid,
};
-PropertyInfo css_devid_ro_propinfo = {
+const PropertyInfo css_devid_ro_propinfo = {
.name = "str",
.description = "Read-only identifier of an I/O device in the channel "
"subsystem, example: fe.1.23ab",
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 5651483..af702f8 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -356,7 +356,7 @@ out:
return pte;
}
-static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *mr, hwaddr addr,
+static IOMMUTLBEntry s390_translate_iommu(IOMMUMemoryRegion *mr, hwaddr addr,
IOMMUAccessFlags flag)
{
uint64_t pte;
@@ -407,10 +407,6 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *mr, hwaddr addr,
return ret;
}
-static const MemoryRegionIOMMUOps s390_iommu_ops = {
- .translate = s390_translate_iommu,
-};
-
static S390PCIIOMMU *s390_pci_get_iommu(S390pciState *s, PCIBus *bus,
int devfn)
{
@@ -522,17 +518,18 @@ static const MemoryRegionOps s390_msi_ctrl_ops = {
void s390_pci_iommu_enable(S390PCIIOMMU *iommu)
{
char *name = g_strdup_printf("iommu-s390-%04x", iommu->pbdev->uid);
- memory_region_init_iommu(&iommu->iommu_mr, OBJECT(&iommu->mr),
- &s390_iommu_ops, name, iommu->pal + 1);
+ memory_region_init_iommu(&iommu->iommu_mr, sizeof(iommu->iommu_mr),
+ TYPE_S390_IOMMU_MEMORY_REGION, OBJECT(&iommu->mr),
+ name, iommu->pal + 1);
iommu->enabled = true;
- memory_region_add_subregion(&iommu->mr, 0, &iommu->iommu_mr);
+ memory_region_add_subregion(&iommu->mr, 0, MEMORY_REGION(&iommu->iommu_mr));
g_free(name);
}
void s390_pci_iommu_disable(S390PCIIOMMU *iommu)
{
iommu->enabled = false;
- memory_region_del_subregion(&iommu->mr, &iommu->iommu_mr);
+ memory_region_del_subregion(&iommu->mr, MEMORY_REGION(&iommu->iommu_mr));
object_unparent(OBJECT(&iommu->iommu_mr));
}
@@ -1018,7 +1015,7 @@ static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
zpci->fid_defined = true;
}
-static PropertyInfo s390_pci_fid_propinfo = {
+static const PropertyInfo s390_pci_fid_propinfo = {
.name = "zpci_fid",
.get = s390_pci_get_fid,
.set = s390_pci_set_fid,
@@ -1058,12 +1055,26 @@ static TypeInfo s390_pci_iommu_info = {
.instance_size = sizeof(S390PCIIOMMU),
};
+static void s390_iommu_memory_region_class_init(ObjectClass *klass, void *data)
+{
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
+
+ imrc->translate = s390_translate_iommu;
+}
+
+static const TypeInfo s390_iommu_memory_region_info = {
+ .parent = TYPE_IOMMU_MEMORY_REGION,
+ .name = TYPE_S390_IOMMU_MEMORY_REGION,
+ .class_init = s390_iommu_memory_region_class_init,
+};
+
static void s390_pci_register_types(void)
{
type_register_static(&s390_pcihost_info);
type_register_static(&s390_pcibus_info);
type_register_static(&s390_pci_device_info);
type_register_static(&s390_pci_iommu_info);
+ type_register_static(&s390_iommu_memory_region_info);
}
type_init(s390_pci_register_types)
diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index cf142a3..67af2c1 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -24,6 +24,7 @@
#define TYPE_S390_PCI_BUS "s390-pcibus"
#define TYPE_S390_PCI_DEVICE "zpci"
#define TYPE_S390_PCI_IOMMU "s390-pci-iommu"
+#define TYPE_S390_IOMMU_MEMORY_REGION "s390-iommu-memory-region"
#define FH_MASK_ENABLE 0x80000000
#define FH_MASK_INSTANCE 0x7f000000
#define FH_MASK_SHM 0x00ff0000
@@ -266,7 +267,7 @@ typedef struct S390PCIIOMMU {
S390PCIBusDevice *pbdev;
AddressSpace as;
MemoryRegion mr;
- MemoryRegion iommu_mr;
+ IOMMUMemoryRegion iommu_mr;
bool enabled;
uint64_t g_iota;
uint64_t pba;
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 8bc7c98..b7beb8c 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -563,7 +563,8 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
S390PCIIOMMU *iommu;
hwaddr start, end;
IOMMUTLBEntry entry;
- MemoryRegion *mr;
+ IOMMUMemoryRegion *iommu_mr;
+ IOMMUMemoryRegionClass *imrc;
cpu_synchronize_state(CPU(cpu));
@@ -622,9 +623,11 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
goto out;
}
- mr = &iommu->iommu_mr;
+ iommu_mr = &iommu->iommu_mr;
+ imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr);
+
while (start < end) {
- entry = mr->iommu_ops->translate(mr, start, IOMMU_NONE);
+ entry = imrc->translate(iommu_mr, start, IOMMU_NONE);
if (!entry.translated_addr) {
pbdev->state = ZPCI_FS_ERROR;
@@ -635,7 +638,7 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
goto out;
}
- memory_region_notify_iommu(mr, entry);
+ memory_region_notify_iommu(iommu_mr, entry);
start += entry.addr_mask + 1;
}
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index e18fd26..c07ddb1 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -867,8 +867,6 @@ static void virtio_ccw_blk_instance_init(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_BLK);
- object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
- &error_abort);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
@@ -952,8 +950,6 @@ static void virtio_ccw_scsi_instance_init(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_SCSI);
- object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev), "iothread",
- &error_abort);
}
#ifdef CONFIG_VHOST_SCSI
@@ -1552,8 +1548,6 @@ static void virtio_ccw_rng_instance_init(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_RNG);
- object_property_add_alias(obj, "rng", OBJECT(&dev->vdev),
- "rng", &error_abort);
}
static Property virtio_ccw_rng_properties[] = {
@@ -1600,9 +1594,6 @@ static void virtio_ccw_crypto_instance_init(Object *obj)
ccw_dev->force_revision_1 = true;
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_CRYPTO);
-
- object_property_add_alias(obj, "cryptodev", OBJECT(&dev->vdev),
- "cryptodev", &error_abort);
}
static void virtio_ccw_crypto_class_init(ObjectClass *klass, void *data)
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index d076fe7..eb63944 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -898,16 +898,6 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
virtio_scsi_dataplane_setup(s, errp);
}
-static void virtio_scsi_instance_init(Object *obj)
-{
- VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(obj);
-
- object_property_add_link(obj, "iothread", TYPE_IOTHREAD,
- (Object **)&vs->conf.iothread,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
-}
-
void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
@@ -935,6 +925,8 @@ static Property virtio_scsi_properties[] = {
VIRTIO_SCSI_F_HOTPLUG, true),
DEFINE_PROP_BIT("param_change", VirtIOSCSI, host_features,
VIRTIO_SCSI_F_CHANGE, true),
+ DEFINE_PROP_LINK("iothread", VirtIOSCSI, parent_obj.conf.iothread,
+ TYPE_IOTHREAD, IOThread *),
DEFINE_PROP_END_OF_LIST(),
};
@@ -989,7 +981,6 @@ static const TypeInfo virtio_scsi_info = {
.name = TYPE_VIRTIO_SCSI,
.parent = TYPE_VIRTIO_SCSI_COMMON,
.instance_size = sizeof(VirtIOSCSI),
- .instance_init = virtio_scsi_instance_init,
.class_init = virtio_scsi_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_HOTPLUG_HANDLER },
diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c
index ac1725e..45d96b0 100644
--- a/hw/usb/ccid-card-passthru.c
+++ b/hw/usb/ccid-card-passthru.c
@@ -322,7 +322,7 @@ static void passthru_apdu_from_guest(
{
PassthruState *card = PASSTHRU_CCID_CARD(base);
- if (!qemu_chr_fe_get_driver(&card->cs)) {
+ if (!qemu_chr_fe_backend_connected(&card->cs)) {
printf("ccid-passthru: no chardev, discarding apdu length %d\n", len);
return;
}
@@ -343,12 +343,12 @@ static int passthru_initfn(CCIDCardState *base)
card->vscard_in_pos = 0;
card->vscard_in_hdr = 0;
- if (qemu_chr_fe_get_driver(&card->cs)) {
+ if (qemu_chr_fe_backend_connected(&card->cs)) {
DPRINTF(card, D_INFO, "initing chardev\n");
qemu_chr_fe_set_handlers(&card->cs,
ccid_card_vscard_can_read,
ccid_card_vscard_read,
- ccid_card_vscard_event, card, NULL, true);
+ ccid_card_vscard_event, NULL, card, NULL, true);
ccid_card_vscard_send_init(card);
} else {
error_report("missing chardev");
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index bfbf7cd..94b5c34 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -484,13 +484,12 @@ static void usb_serial_realize(USBDevice *dev, Error **errp)
{
USBSerialState *s = USB_SERIAL_DEV(dev);
Error *local_err = NULL;
- Chardev *chr = qemu_chr_fe_get_driver(&s->cs);
usb_desc_create_serial(dev);
usb_desc_init(dev);
dev->auto_attach = 0;
- if (!chr) {
+ if (!qemu_chr_fe_backend_connected(&s->cs)) {
error_setg(errp, "Property chardev is required");
return;
}
@@ -502,10 +501,10 @@ static void usb_serial_realize(USBDevice *dev, Error **errp)
}
qemu_chr_fe_set_handlers(&s->cs, usb_serial_can_read, usb_serial_read,
- usb_serial_event, s, NULL, true);
+ usb_serial_event, NULL, s, NULL, true);
usb_serial_handle_reset(dev);
- if (chr->be_open && !dev->attached) {
+ if (qemu_chr_fe_backend_open(&s->cs) && !dev->attached) {
usb_device_attach(dev, &error_abort);
}
}
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 5b65965..5e42730 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -273,10 +273,9 @@ static gboolean usbredir_write_unblocked(GIOChannel *chan, GIOCondition cond,
static int usbredir_write(void *priv, uint8_t *data, int count)
{
USBRedirDevice *dev = priv;
- Chardev *chr = qemu_chr_fe_get_driver(&dev->cs);
int r;
- if (!chr->be_open) {
+ if (!qemu_chr_fe_backend_open(&dev->cs)) {
return 0;
}
@@ -1366,7 +1365,7 @@ static void usbredir_realize(USBDevice *udev, Error **errp)
USBRedirDevice *dev = USB_REDIRECT(udev);
int i;
- if (!qemu_chr_fe_get_driver(&dev->cs)) {
+ if (!qemu_chr_fe_backend_connected(&dev->cs)) {
error_setg(errp, QERR_MISSING_PARAMETER, "chardev");
return;
}
@@ -1399,7 +1398,7 @@ static void usbredir_realize(USBDevice *udev, Error **errp)
/* Let the backend know we are ready */
qemu_chr_fe_set_handlers(&dev->cs, usbredir_chardev_can_read,
usbredir_chardev_read, usbredir_chardev_event,
- dev, NULL, true);
+ NULL, dev, NULL, true);
dev->vmstate =
qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 29923e4..c1bb6d4 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -479,6 +479,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
if (memory_region_is_iommu(section->mr)) {
VFIOGuestIOMMU *giommu;
+ IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
trace_vfio_listener_region_add_iommu(iova, end);
/*
@@ -488,7 +489,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
* device emulation the VFIO iommu handles to use).
*/
giommu = g_malloc0(sizeof(*giommu));
- giommu->iommu = section->mr;
+ giommu->iommu = iommu_mr;
giommu->iommu_offset = section->offset_within_address_space -
section->offset_within_region;
giommu->container = container;
@@ -501,7 +502,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
int128_get64(llend));
QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next);
- memory_region_register_iommu_notifier(giommu->iommu, &giommu->n);
+ memory_region_register_iommu_notifier(section->mr, &giommu->n);
memory_region_iommu_replay(giommu->iommu, &giommu->n);
return;
@@ -569,9 +570,9 @@ static void vfio_listener_region_del(MemoryListener *listener,
VFIOGuestIOMMU *giommu;
QLIST_FOREACH(giommu, &container->giommu_list, giommu_next) {
- if (giommu->iommu == section->mr &&
+ if (MEMORY_REGION(giommu->iommu) == section->mr &&
giommu->n.start == section->offset_within_region) {
- memory_region_unregister_iommu_notifier(giommu->iommu,
+ memory_region_unregister_iommu_notifier(section->mr,
&giommu->n);
QLIST_REMOVE(giommu, giommu_next);
g_free(giommu);
@@ -1163,7 +1164,8 @@ static void vfio_disconnect_container(VFIOGroup *group)
QLIST_REMOVE(container, next);
QLIST_FOREACH_SAFE(giommu, &container->giommu_list, giommu_next, tmp) {
- memory_region_unregister_iommu_notifier(giommu->iommu, &giommu->n);
+ memory_region_unregister_iommu_notifier(
+ MEMORY_REGION(giommu->iommu), &giommu->n);
QLIST_REMOVE(giommu, giommu_next);
g_free(giommu);
}
diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c
index 4409bcc..32fd6a9 100644
--- a/hw/vfio/spapr.c
+++ b/hw/vfio/spapr.c
@@ -143,7 +143,8 @@ int vfio_spapr_create_window(VFIOContainer *container,
hwaddr *pgsize)
{
int ret;
- unsigned pagesize = memory_region_iommu_get_min_page_size(section->mr);
+ IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
+ unsigned pagesize = memory_region_iommu_get_min_page_size(iommu_mr);
unsigned entries, pages;
struct vfio_iommu_spapr_tce_create create = { .argsz = sizeof(create) };
diff --git a/hw/virtio/virtio-crypto-pci.c b/hw/virtio/virtio-crypto-pci.c
index 422aca3..bf64996 100644
--- a/hw/virtio/virtio-crypto-pci.c
+++ b/hw/virtio/virtio-crypto-pci.c
@@ -62,8 +62,6 @@ static void virtio_crypto_initfn(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_CRYPTO);
- object_property_add_alias(obj, "cryptodev", OBJECT(&dev->vdev),
- "cryptodev", &error_abort);
}
static const TypeInfo virtio_crypto_pci_info = {
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 0353eb6..19c82e0 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -781,6 +781,11 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
if (vcrypto->cryptodev == NULL) {
error_setg(errp, "'cryptodev' parameter expects a valid object");
return;
+ } else if (cryptodev_backend_is_used(vcrypto->cryptodev)) {
+ char *path = object_get_canonical_path_component(OBJECT(vcrypto->conf.cryptodev));
+ error_setg(errp, "can't use already used cryptodev backend: %s", path);
+ g_free(path);
+ return;
}
vcrypto->max_queues = MAX(vcrypto->cryptodev->conf.peers.queues, 1);
@@ -845,6 +850,8 @@ static const VMStateDescription vmstate_virtio_crypto = {
};
static Property virtio_crypto_properties[] = {
+ DEFINE_PROP_LINK("cryptodev", VirtIOCrypto, conf.cryptodev,
+ TYPE_CRYPTODEV_BACKEND, CryptoDevBackend *),
DEFINE_PROP_END_OF_LIST(),
};
@@ -888,20 +895,6 @@ static void virtio_crypto_class_init(ObjectClass *klass, void *data)
vdc->reset = virtio_crypto_reset;
}
-static void
-virtio_crypto_check_cryptodev_is_used(Object *obj, const char *name,
- Object *val, Error **errp)
-{
- if (cryptodev_backend_is_used(CRYPTODEV_BACKEND(val))) {
- char *path = object_get_canonical_path_component(val);
- error_setg(errp,
- "can't use already used cryptodev backend: %s", path);
- g_free(path);
- } else {
- qdev_prop_allow_set_link_before_realize(obj, name, val, errp);
- }
-}
-
static void virtio_crypto_instance_init(Object *obj)
{
VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(obj);
@@ -911,12 +904,6 @@ static void virtio_crypto_instance_init(Object *obj)
* Can be overriden with virtio_crypto_set_config_size.
*/
vcrypto->config_size = sizeof(struct virtio_crypto_config);
-
- object_property_add_link(obj, "cryptodev",
- TYPE_CRYPTODEV_BACKEND,
- (Object **)&vcrypto->conf.cryptodev,
- virtio_crypto_check_cryptodev_is_used,
- OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
}
static const TypeInfo virtio_crypto_info = {
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 93480a7..5d14bd6 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -2000,8 +2000,6 @@ static void virtio_blk_pci_instance_init(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_BLK);
- object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
- &error_abort);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
@@ -2071,8 +2069,6 @@ static void virtio_scsi_pci_instance_init(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_SCSI);
- object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev), "iothread",
- &error_abort);
}
static const TypeInfo virtio_scsi_pci_info = {
@@ -2467,8 +2463,6 @@ static void virtio_rng_initfn(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_RNG);
- object_property_add_alias(obj, "rng", OBJECT(&dev->vdev), "rng",
- &error_abort);
}
static const TypeInfo virtio_rng_pci_info = {
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index a6ee501..289bbca 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -246,6 +246,7 @@ static Property virtio_rng_properties[] = {
*/
DEFINE_PROP_UINT64("max-bytes", VirtIORNG, conf.max_bytes, INT64_MAX),
DEFINE_PROP_UINT32("period", VirtIORNG, conf.period_ms, 1 << 16),
+ DEFINE_PROP_LINK("rng", VirtIORNG, conf.rng, TYPE_RNG_BACKEND, RngBackend *),
DEFINE_PROP_END_OF_LIST(),
};
@@ -262,21 +263,10 @@ static void virtio_rng_class_init(ObjectClass *klass, void *data)
vdc->get_features = get_features;
}
-static void virtio_rng_initfn(Object *obj)
-{
- VirtIORNG *vrng = VIRTIO_RNG(obj);
-
- object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
- (Object **)&vrng->conf.rng,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
-}
-
static const TypeInfo virtio_rng_info = {
.name = TYPE_VIRTIO_RNG,
.parent = TYPE_VIRTIO_DEVICE,
.instance_size = sizeof(VirtIORNG),
- .instance_init = virtio_rng_initfn,
.class_init = virtio_rng_class_init,
};