summary refs log tree commit diff stats
path: root/include/hw
diff options
context:
space:
mode:
Diffstat (limited to 'include/hw')
-rw-r--r--include/hw/boards.h29
-rw-r--r--include/hw/i386/intel_iommu.h5
-rw-r--r--include/hw/mips/mips.h2
-rw-r--r--include/hw/misc/unimp.h2
-rw-r--r--include/hw/ppc/pnv_psi.h2
-rw-r--r--include/hw/ppc/spapr.h31
-rw-r--r--include/hw/ppc/spapr_drc.h74
-rw-r--r--include/hw/ppc/spapr_ovec.h1
-rw-r--r--include/hw/ptimer.h120
-rw-r--r--include/hw/qdev-core.h6
-rw-r--r--include/hw/qdev-properties.h62
-rw-r--r--include/hw/s390x/css.h27
-rw-r--r--include/hw/s390x/s390-virtio-ccw.h10
-rw-r--r--include/hw/s390x/s390_flic.h14
-rw-r--r--include/hw/s390x/sclp.h3
-rw-r--r--include/hw/s390x/storage-attributes.h81
-rw-r--r--include/hw/vfio/vfio-common.h2
17 files changed, 399 insertions, 72 deletions
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 76ce0219ff..3363dd19fd 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -9,6 +9,35 @@
 #include "qom/object.h"
 #include "qom/cpu.h"
 
+/**
+ * memory_region_allocate_system_memory - Allocate a board's main memory
+ * @mr: the #MemoryRegion to be initialized
+ * @owner: the object that tracks the region's reference count
+ * @name: name of the memory region
+ * @ram_size: size of the region in bytes
+ *
+ * This function allocates the main memory for a board model, and
+ * initializes @mr appropriately. It also arranges for the memory
+ * to be migrated (by calling vmstate_register_ram_global()).
+ *
+ * Memory allocated via this function will be backed with the memory
+ * backend the user provided using "-mem-path" or "-numa node,memdev=..."
+ * if appropriate; this is typically used to cause host huge pages to be
+ * used. This function should therefore be called by a board exactly once,
+ * for the primary or largest RAM area it implements.
+ *
+ * For boards where the major RAM is split into two parts in the memory
+ * map, you can deal with this by calling memory_region_allocate_system_memory()
+ * once to get a MemoryRegion with enough RAM for both parts, and then
+ * creating alias MemoryRegions via memory_region_init_alias() which
+ * alias into different parts of the RAM MemoryRegion and can be mapped
+ * into the memory map in the appropriate places.
+ *
+ * Smaller pieces of memory (display RAM, static RAMs, etc) don't need
+ * to be backed via the -mem-path memory backend and can simply
+ * be created via memory_region_allocate_aux_memory() or
+ * memory_region_init_ram().
+ */
 void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
                                           const char *name,
                                           uint64_t ram_size);
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index 3e51876b75..08d8a26d13 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -32,6 +32,8 @@
 #define INTEL_IOMMU_DEVICE(obj) \
      OBJECT_CHECK(IntelIOMMUState, (obj), TYPE_INTEL_IOMMU_DEVICE)
 
+#define TYPE_INTEL_IOMMU_MEMORY_REGION "intel-iommu-iommu-memory-region"
+
 /* DMAR Hardware Unit Definition address (IOMMU unit) */
 #define Q35_HOST_BRIDGE_IOMMU_ADDR  0xfed90000ULL
 
@@ -83,7 +85,7 @@ struct VTDAddressSpace {
     PCIBus *bus;
     uint8_t devfn;
     AddressSpace as;
-    MemoryRegion iommu;
+    IOMMUMemoryRegion iommu;
     MemoryRegion root;
     MemoryRegion sys_alias;
     MemoryRegion iommu_ir;      /* Interrupt region: 0xfeeXXXXX */
@@ -289,7 +291,6 @@ struct IntelIOMMUState {
     uint32_t context_cache_gen;     /* Should be in [1,MAX] */
     GHashTable *iotlb;              /* IOTLB */
 
-    MemoryRegionIOMMUOps iommu_ops;
     GHashTable *vtd_as_by_busptr;   /* VTDBus objects indexed by PCIBus* reference */
     VTDBus *vtd_as_by_bus_num[VTD_PCI_BUS_MAX]; /* VTDBus objects indexed by bus number */
     /* list of registered notifiers */
diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h
index 16412dc150..2f6774d540 100644
--- a/include/hw/mips/mips.h
+++ b/include/hw/mips/mips.h
@@ -19,6 +19,6 @@ typedef struct rc4030DMAState *rc4030_dma;
 void rc4030_dma_read(void *dma, uint8_t *buf, int len);
 void rc4030_dma_write(void *dma, uint8_t *buf, int len);
 
-DeviceState *rc4030_init(rc4030_dma **dmas, MemoryRegion **dma_mr);
+DeviceState *rc4030_init(rc4030_dma **dmas, IOMMUMemoryRegion **dma_mr);
 
 #endif
diff --git a/include/hw/misc/unimp.h b/include/hw/misc/unimp.h
index 3462d85836..52e068ec3e 100644
--- a/include/hw/misc/unimp.h
+++ b/include/hw/misc/unimp.h
@@ -8,6 +8,8 @@
 #ifndef HW_MISC_UNIMP_H
 #define HW_MISC_UNIMP_H
 
+#include "hw/sysbus.h"
+
 #define TYPE_UNIMPLEMENTED_DEVICE "unimplemented-device"
 
 /**
diff --git a/include/hw/ppc/pnv_psi.h b/include/hw/ppc/pnv_psi.h
index 11d83e43f8..f6af5eae1f 100644
--- a/include/hw/ppc/pnv_psi.h
+++ b/include/hw/ppc/pnv_psi.h
@@ -28,8 +28,6 @@
 
 #define PSIHB_XSCOM_MAX         0x20
 
-typedef struct XICSState XICSState;
-
 typedef struct PnvPsi {
     SysBusDevice parent;
 
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index a184ffab0e..2a303a705c 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -13,6 +13,7 @@ struct sPAPRPHBState;
 struct sPAPRNVRAM;
 typedef struct sPAPREventLogEntry sPAPREventLogEntry;
 typedef struct sPAPREventSource sPAPREventSource;
+typedef struct sPAPRPendingHPT sPAPRPendingHPT;
 
 #define HPTE64_V_HPTE_DIRTY     0x0000000000000040ULL
 #define SPAPR_ENTRY_POINT       0x100
@@ -42,6 +43,13 @@ typedef struct sPAPRMachineClass sPAPRMachineClass;
 #define SPAPR_MACHINE_CLASS(klass) \
     OBJECT_CLASS_CHECK(sPAPRMachineClass, klass, TYPE_SPAPR_MACHINE)
 
+typedef enum {
+    SPAPR_RESIZE_HPT_DEFAULT = 0,
+    SPAPR_RESIZE_HPT_DISABLED,
+    SPAPR_RESIZE_HPT_ENABLED,
+    SPAPR_RESIZE_HPT_REQUIRED,
+} sPAPRResizeHPT;
+
 /**
  * sPAPRMachineClass:
  */
@@ -58,6 +66,7 @@ struct sPAPRMachineClass {
                           uint64_t *buid, hwaddr *pio, 
                           hwaddr *mmio32, hwaddr *mmio64,
                           unsigned n_dma, uint32_t *liobns, Error **errp);
+    sPAPRResizeHPT resize_hpt_default;
 };
 
 /**
@@ -73,9 +82,12 @@ struct sPAPRMachineState {
     ICSState *ics;
     sPAPRRTCState rtc;
 
+    sPAPRResizeHPT resize_hpt;
     void *htab;
     uint32_t htab_shift;
     uint64_t patb_entry; /* Process tbl registed in H_REGISTER_PROCESS_TABLE */
+    sPAPRPendingHPT *pending_hpt; /* in-progress resize */
+
     hwaddr rma_size;
     int vrma_adjust;
     ssize_t rtas_size;
@@ -367,6 +379,8 @@ struct sPAPRMachineState {
 #define H_XIRR_X                0x2FC
 #define H_RANDOM                0x300
 #define H_SET_MODE              0x31C
+#define H_RESIZE_HPT_PREPARE    0x36C
+#define H_RESIZE_HPT_COMMIT     0x370
 #define H_CLEAN_SLB             0x374
 #define H_INVALIDATE_PID        0x378
 #define H_REGISTER_PROC_TBL     0x37C
@@ -582,6 +596,10 @@ typedef struct sPAPRTCETable sPAPRTCETable;
 #define SPAPR_TCE_TABLE(obj) \
     OBJECT_CHECK(sPAPRTCETable, (obj), TYPE_SPAPR_TCE_TABLE)
 
+#define TYPE_SPAPR_IOMMU_MEMORY_REGION "spapr-iommu-memory-region"
+#define SPAPR_IOMMU_MEMORY_REGION(obj) \
+        OBJECT_CHECK(IOMMUMemoryRegion, (obj), TYPE_SPAPR_IOMMU_MEMORY_REGION)
+
 struct sPAPRTCETable {
     DeviceState parent;
     uint32_t liobn;
@@ -594,7 +612,8 @@ struct sPAPRTCETable {
     bool bypass;
     bool need_vfio;
     int fd;
-    MemoryRegion root, iommu;
+    MemoryRegion root;
+    IOMMUMemoryRegion iommu;
     struct VIOsPAPRDevice *vdev; /* for @bypass migration compatibility only */
     QLIST_ENTRY(sPAPRTCETable) list;
 };
@@ -602,8 +621,9 @@ struct sPAPRTCETable {
 sPAPRTCETable *spapr_tce_find_by_liobn(target_ulong liobn);
 
 struct sPAPREventLogEntry {
-    int log_type;
-    void *data;
+    uint32_t summary;
+    uint32_t extended_length;
+    void *extended_log;
     QTAILQ_ENTRY(sPAPREventLogEntry) next;
 };
 
@@ -639,6 +659,9 @@ void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type,
 void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type,
                                                uint32_t count, uint32_t index);
 void spapr_cpu_parse_features(sPAPRMachineState *spapr);
+int spapr_hpt_shift_for_ramsize(uint64_t ramsize);
+void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
+                          Error **errp);
 
 /* CPU and LMB DRC release callbacks. */
 void spapr_core_release(DeviceState *dev);
@@ -679,4 +702,6 @@ int spapr_rng_populate_dt(void *fdt);
 
 void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg);
 
+#define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
+
 #endif /* HW_SPAPR_H */
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index d15e9eb3b4..a7958d0a8d 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -15,6 +15,7 @@
 
 #include <libfdt.h>
 #include "qom/object.h"
+#include "sysemu/sysemu.h"
 #include "hw/qdev.h"
 
 #define TYPE_SPAPR_DR_CONNECTOR "spapr-dr-connector"
@@ -32,7 +33,7 @@
 #define SPAPR_DRC_PHYSICAL_CLASS(klass) \
         OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
                            TYPE_SPAPR_DRC_PHYSICAL)
-#define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
+#define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(sPAPRDRCPhysical, (obj), \
                                              TYPE_SPAPR_DRC_PHYSICAL)
 
 #define TYPE_SPAPR_DRC_LOGICAL "spapr-drc-logical"
@@ -172,11 +173,23 @@ typedef enum {
     SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003,
 } sPAPRDRCCResponse;
 
-/* rtas-configure-connector state */
-typedef struct sPAPRConfigureConnectorState {
-    int fdt_offset;
-    int fdt_depth;
-} sPAPRConfigureConnectorState;
+typedef enum {
+    /*
+     * Values come from Fig. 12 in LoPAPR section 13.4
+     *
+     * These are exposed in the migration stream, so don't change
+     * them.
+     */
+    SPAPR_DRC_STATE_INVALID             = 0,
+    SPAPR_DRC_STATE_LOGICAL_UNUSABLE    = 1,
+    SPAPR_DRC_STATE_LOGICAL_AVAILABLE   = 2,
+    SPAPR_DRC_STATE_LOGICAL_UNISOLATE   = 3,
+    SPAPR_DRC_STATE_LOGICAL_CONFIGURED  = 4,
+    SPAPR_DRC_STATE_PHYSICAL_AVAILABLE  = 5,
+    SPAPR_DRC_STATE_PHYSICAL_POWERON    = 6,
+    SPAPR_DRC_STATE_PHYSICAL_UNISOLATE  = 7,
+    SPAPR_DRC_STATE_PHYSICAL_CONFIGURED = 8,
+} sPAPRDRCState;
 
 typedef struct sPAPRDRConnector {
     /*< private >*/
@@ -185,29 +198,25 @@ typedef struct sPAPRDRConnector {
     uint32_t id;
     Object *owner;
 
-    /* DR-indicator */
-    uint32_t dr_indicator;
+    uint32_t state;
 
-    /* sensor/indicator states */
-    uint32_t isolation_state;
-    uint32_t allocation_state;
-
-    /* configure-connector state */
-    void *fdt;
-    int fdt_start_offset;
-    bool configured;
-    sPAPRConfigureConnectorState *ccs;
-
-    bool awaiting_release;
-    bool awaiting_allocation;
+    /* RTAS ibm,configure-connector state */
+    /* (only valid in UNISOLATE state) */
+    int ccs_offset;
+    int ccs_depth;
 
     /* device pointer, via link property */
     DeviceState *dev;
+    bool unplug_requested;
+    void *fdt;
+    int fdt_start_offset;
 } sPAPRDRConnector;
 
 typedef struct sPAPRDRConnectorClass {
     /*< private >*/
     DeviceClass parent;
+    sPAPRDRCState empty_state;
+    sPAPRDRCState ready_state;
 
     /*< public >*/
     sPAPRDRConnectorTypeShift typeshift;
@@ -218,11 +227,23 @@ typedef struct sPAPRDRConnectorClass {
     uint32_t (*isolate)(sPAPRDRConnector *drc);
     uint32_t (*unisolate)(sPAPRDRConnector *drc);
     void (*release)(DeviceState *dev);
-
-    /* QEMU interfaces for managing hotplug operations */
-    bool (*release_pending)(sPAPRDRConnector *drc);
 } sPAPRDRConnectorClass;
 
+typedef struct sPAPRDRCPhysical {
+    /*< private >*/
+    sPAPRDRConnector parent;
+
+    /* DR-indicator */
+    uint32_t dr_indicator;
+} sPAPRDRCPhysical;
+
+static inline bool spapr_drc_hotplugged(DeviceState *dev)
+{
+    return dev->hotplugged && !runstate_check(RUN_STATE_INMIGRATE);
+}
+
+void spapr_drc_reset(sPAPRDRConnector *drc);
+
 uint32_t spapr_drc_index(sPAPRDRConnector *drc);
 sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc);
 
@@ -235,6 +256,11 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
 
 void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
                       int fdt_start_offset, Error **errp);
-void spapr_drc_detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp);
+void spapr_drc_detach(sPAPRDRConnector *drc);
+
+static inline bool spapr_drc_unplug_requested(sPAPRDRConnector *drc)
+{
+    return drc->unplug_requested;
+}
 
 #endif /* HW_SPAPR_DRC_H */
diff --git a/include/hw/ppc/spapr_ovec.h b/include/hw/ppc/spapr_ovec.h
index 0b464e22e7..9edfa5ff75 100644
--- a/include/hw/ppc/spapr_ovec.h
+++ b/include/hw/ppc/spapr_ovec.h
@@ -50,6 +50,7 @@ typedef struct sPAPROptionVector sPAPROptionVector;
 #define OV5_DRCONF_MEMORY       OV_BIT(2, 2)
 #define OV5_FORM1_AFFINITY      OV_BIT(5, 0)
 #define OV5_HP_EVT              OV_BIT(6, 5)
+#define OV5_HPT_RESIZE          OV_BIT(6, 7)
 #define OV5_XIVE_EXPLOIT        OV_BIT(23, 7)
 
 /* ISA 3.00 MMU features: */
diff --git a/include/hw/ptimer.h b/include/hw/ptimer.h
index eafc3f0a86..fc4ef5cc1d 100644
--- a/include/hw/ptimer.h
+++ b/include/hw/ptimer.h
@@ -12,6 +12,20 @@
 #include "qemu/timer.h"
 #include "migration/vmstate.h"
 
+/* The ptimer API implements a simple periodic countdown timer.
+ * The countdown timer has a value (which can be read and written via
+ * ptimer_get_count() and ptimer_set_count()). When it is enabled
+ * using ptimer_run(), the value will count downwards at the frequency
+ * which has been configured using ptimer_set_period() or ptimer_set_freq().
+ * When it reaches zero it will trigger a QEMU bottom half handler, and
+ * can be set to either reload itself from a specified limit value
+ * and keep counting down, or to stop (as a one-shot timer).
+ *
+ * Forgetting to set the period/frequency (or setting it to zero) is a
+ * bug in the QEMU device and will cause warning messages to be printed
+ * to stderr when the guest attempts to enable the timer.
+ */
+
 /* The default ptimer policy retains backward compatibility with the legacy
  * timers. Custom policies are adjusting the default one. Consider providing
  * a correct policy for your timer.
@@ -59,15 +73,121 @@
 typedef struct ptimer_state ptimer_state;
 typedef void (*ptimer_cb)(void *opaque);
 
+/**
+ * ptimer_init - Allocate and return a new ptimer
+ * @bh: QEMU bottom half which is run on timer expiry
+ * @policy: PTIMER_POLICY_* bits specifying behaviour
+ *
+ * The ptimer returned must be freed using ptimer_free().
+ * The ptimer takes ownership of @bh and will delete it
+ * when the ptimer is eventually freed.
+ */
 ptimer_state *ptimer_init(QEMUBH *bh, uint8_t policy_mask);
+
+/**
+ * ptimer_free - Free a ptimer
+ * @s: timer to free
+ *
+ * Free a ptimer created using ptimer_init() (including
+ * deleting the bottom half which it is using).
+ */
 void ptimer_free(ptimer_state *s);
+
+/**
+ * ptimer_set_period - Set counter increment interval in nanoseconds
+ * @s: ptimer to configure
+ * @period: period of the counter in nanoseconds
+ *
+ * Note that if your counter behaviour is specified as having a
+ * particular frequency rather than a period then ptimer_set_freq()
+ * may be more appropriate.
+ */
 void ptimer_set_period(ptimer_state *s, int64_t period);
+
+/**
+ * ptimer_set_freq - Set counter frequency in Hz
+ * @s: ptimer to configure
+ * @freq: counter frequency in Hz
+ *
+ * This does the same thing as ptimer_set_period(), so you only
+ * need to call one of them. If the counter behaviour is specified
+ * as setting the frequency then this function is more appropriate,
+ * because it allows specifying an effective period which is
+ * precise to fractions of a nanosecond, avoiding rounding errors.
+ */
 void ptimer_set_freq(ptimer_state *s, uint32_t freq);
+
+/**
+ * ptimer_get_limit - Get the configured limit of the ptimer
+ * @s: ptimer to query
+ *
+ * This function returns the current limit (reload) value
+ * of the down-counter; that is, the value which it will be
+ * reset to when it hits zero.
+ *
+ * Generally timer devices using ptimers should be able to keep
+ * their reload register state inside the ptimer using the get
+ * and set limit functions rather than needing to also track it
+ * in their own state structure.
+ */
 uint64_t ptimer_get_limit(ptimer_state *s);
+
+/**
+ * ptimer_set_limit - Set the limit of the ptimer
+ * @s: ptimer
+ * @limit: initial countdown value
+ * @reload: if nonzero, then reset the counter to the new limit
+ *
+ * Set the limit value of the down-counter. The @reload flag can
+ * be used to emulate the behaviour of timers which immediately
+ * reload the counter when their reload register is written to.
+ */
 void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
+
+/**
+ * ptimer_get_count - Get the current value of the ptimer
+ * @s: ptimer
+ *
+ * Return the current value of the down-counter. This will
+ * return the correct value whether the counter is enabled or
+ * disabled.
+ */
 uint64_t ptimer_get_count(ptimer_state *s);
+
+/**
+ * ptimer_set_count - Set the current value of the ptimer
+ * @s: ptimer
+ * @count: count value to set
+ *
+ * Set the value of the down-counter. If the counter is currently
+ * enabled this will arrange for a timer callback at the appropriate
+ * point in the future.
+ */
 void ptimer_set_count(ptimer_state *s, uint64_t count);
+
+/**
+ * ptimer_run - Start a ptimer counting
+ * @s: ptimer
+ * @oneshot: non-zero if this timer should only count down once
+ *
+ * Start a ptimer counting down; when it reaches zero the bottom half
+ * passed to ptimer_init() will be invoked. If the @oneshot argument is zero,
+ * the counter value will then be reloaded from the limit and it will
+ * start counting down again. If @oneshot is non-zero, then the counter
+ * will disable itself when it reaches zero.
+ */
 void ptimer_run(ptimer_state *s, int oneshot);
+
+/**
+ * ptimer_stop - Stop a ptimer counting
+ * @s: ptimer
+ *
+ * Pause a timer (the count stays at its current value until ptimer_run()
+ * is called to start it counting again).
+ *
+ * Note that this can cause it to "lose" time, even if it is immediately
+ * restarted.
+ */
 void ptimer_stop(ptimer_state *s);
 
 extern const VMStateDescription vmstate_ptimer;
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 9d7c1c0e9b..53488153fd 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -223,7 +223,7 @@ struct BusState {
 
 struct Property {
     const char   *name;
-    PropertyInfo *info;
+    const PropertyInfo *info;
     ptrdiff_t    offset;
     uint8_t      bitnr;
     union {
@@ -231,8 +231,9 @@ struct Property {
         uint64_t u;
     } defval;
     int          arrayoffset;
-    PropertyInfo *arrayinfo;
+    const PropertyInfo *arrayinfo;
     int          arrayfieldsize;
+    const char   *link_type;
 };
 
 struct PropertyInfo {
@@ -241,6 +242,7 @@ struct PropertyInfo {
     const char * const *enum_table;
     int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
     void (*set_default_value)(Object *obj, const Property *prop);
+    void (*create)(Object *obj, Property *prop, Error **errp);
     ObjectPropertyAccessor *get;
     ObjectPropertyAccessor *set;
     ObjectPropertyRelease *release;
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 0604c337e0..f6692d5dc3 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -5,31 +5,32 @@
 
 /*** qdev-properties.c ***/
 
-extern PropertyInfo qdev_prop_bit;
-extern PropertyInfo qdev_prop_bit64;
-extern PropertyInfo qdev_prop_bool;
-extern PropertyInfo qdev_prop_uint8;
-extern PropertyInfo qdev_prop_uint16;
-extern PropertyInfo qdev_prop_uint32;
-extern PropertyInfo qdev_prop_int32;
-extern PropertyInfo qdev_prop_uint64;
-extern PropertyInfo qdev_prop_size;
-extern PropertyInfo qdev_prop_string;
-extern PropertyInfo qdev_prop_chr;
-extern PropertyInfo qdev_prop_ptr;
-extern PropertyInfo qdev_prop_macaddr;
-extern PropertyInfo qdev_prop_on_off_auto;
-extern PropertyInfo qdev_prop_losttickpolicy;
-extern PropertyInfo qdev_prop_blockdev_on_error;
-extern PropertyInfo qdev_prop_bios_chs_trans;
-extern PropertyInfo qdev_prop_fdc_drive_type;
-extern PropertyInfo qdev_prop_drive;
-extern PropertyInfo qdev_prop_netdev;
-extern PropertyInfo qdev_prop_vlan;
-extern PropertyInfo qdev_prop_pci_devfn;
-extern PropertyInfo qdev_prop_blocksize;
-extern PropertyInfo qdev_prop_pci_host_devaddr;
-extern PropertyInfo qdev_prop_arraylen;
+extern const PropertyInfo qdev_prop_bit;
+extern const PropertyInfo qdev_prop_bit64;
+extern const PropertyInfo qdev_prop_bool;
+extern const PropertyInfo qdev_prop_uint8;
+extern const PropertyInfo qdev_prop_uint16;
+extern const PropertyInfo qdev_prop_uint32;
+extern const PropertyInfo qdev_prop_int32;
+extern const PropertyInfo qdev_prop_uint64;
+extern const PropertyInfo qdev_prop_size;
+extern const PropertyInfo qdev_prop_string;
+extern const PropertyInfo qdev_prop_chr;
+extern const PropertyInfo qdev_prop_ptr;
+extern const PropertyInfo qdev_prop_macaddr;
+extern const PropertyInfo qdev_prop_on_off_auto;
+extern const PropertyInfo qdev_prop_losttickpolicy;
+extern const PropertyInfo qdev_prop_blockdev_on_error;
+extern const PropertyInfo qdev_prop_bios_chs_trans;
+extern const PropertyInfo qdev_prop_fdc_drive_type;
+extern const PropertyInfo qdev_prop_drive;
+extern const PropertyInfo qdev_prop_netdev;
+extern const PropertyInfo qdev_prop_vlan;
+extern const PropertyInfo qdev_prop_pci_devfn;
+extern const PropertyInfo qdev_prop_blocksize;
+extern const PropertyInfo qdev_prop_pci_host_devaddr;
+extern const PropertyInfo qdev_prop_arraylen;
+extern const PropertyInfo qdev_prop_link;
 
 #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
         .name      = (_name),                                    \
@@ -117,6 +118,14 @@ extern PropertyInfo qdev_prop_arraylen;
         .arrayoffset = offsetof(_state, _arrayfield),                   \
         }
 
+#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type) {     \
+        .name = (_name),                                                \
+        .info = &(qdev_prop_link),                                      \
+        .offset = offsetof(_state, _field)                              \
+            + type_check(_ptr_type, typeof_field(_state, _field)),      \
+        .link_type  = _type,                                            \
+        }
+
 #define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
     DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
 #define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
@@ -272,7 +281,8 @@ void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
  * This function should be used as the check() argument to
  * object_property_add_link().
  */
-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);
 
 #endif
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index eb0e26f258..5c5fe6b202 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -12,6 +12,7 @@
 #ifndef CSS_H
 #define CSS_H
 
+#include "cpu.h"
 #include "hw/s390x/adapter.h"
 #include "hw/s390x/s390_flic.h"
 #include "hw/s390x/ioinst.h"
@@ -89,10 +90,11 @@ struct SubchDev {
     bool thinint_active;
     uint8_t ccw_no_data_cnt;
     uint16_t migrated_schid; /* used for missmatch detection */
+    ORB orb;
     /* transport-provided data: */
     int (*ccw_cb) (SubchDev *, CCW1);
     void (*disable_cb)(SubchDev *);
-    int (*do_subchannel_work) (SubchDev *, ORB *);
+    int (*do_subchannel_work) (SubchDev *);
     SenseId id;
     void *driver_data;
 };
@@ -112,7 +114,7 @@ typedef struct CssDevId {
     bool valid;
 } CssDevId;
 
-extern PropertyInfo css_devid_propinfo;
+extern const PropertyInfo css_devid_propinfo;
 
 #define DEFINE_PROP_CSS_DEV_ID(_n, _s, _f) \
     DEFINE_PROP(_n, _s, _f, css_devid_propinfo, CssDevId)
@@ -154,10 +156,9 @@ void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
 void css_generate_chp_crws(uint8_t cssid, uint8_t chpid);
 void css_generate_css_crws(uint8_t cssid);
 void css_clear_sei_pending(void);
-void css_adapter_interrupt(uint8_t isc);
 int s390_ccw_cmd_request(ORB *orb, SCSW *scsw, void *data);
-int do_subchannel_work_virtual(SubchDev *sub, ORB *orb);
-int do_subchannel_work_passthrough(SubchDev *sub, ORB *orb);
+int do_subchannel_work_virtual(SubchDev *sub);
+int do_subchannel_work_passthrough(SubchDev *sub);
 
 typedef enum {
     CSS_IO_ADAPTER_VIRTIO = 0,
@@ -165,9 +166,17 @@ typedef enum {
     CSS_IO_ADAPTER_TYPE_NUMS,
 } CssIoAdapterType;
 
+void css_adapter_interrupt(CssIoAdapterType type, uint8_t isc);
+int css_do_sic(CPUS390XState *env, uint8_t isc, uint16_t mode);
 uint32_t css_get_adapter_id(CssIoAdapterType type, uint8_t isc);
 void css_register_io_adapters(CssIoAdapterType type, bool swap, bool maskable,
-                              Error **errp);
+                              uint8_t flags, Error **errp);
+
+#ifndef CONFIG_KVM
+#define S390_ADAPTER_SUPPRESSIBLE 0x01
+#else
+#define S390_ADAPTER_SUPPRESSIBLE KVM_S390_ADAPTER_SUPPRESSIBLE
+#endif
 
 #ifndef CONFIG_USER_ONLY
 SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid,
@@ -196,7 +205,7 @@ int css_do_rchp(uint8_t cssid, uint8_t chpid);
 bool css_present(uint8_t cssid);
 #endif
 
-extern PropertyInfo css_devid_ro_propinfo;
+extern const PropertyInfo css_devid_ro_propinfo;
 
 #define DEFINE_PROP_CSS_DEV_ID_RO(_n, _s, _f) \
     DEFINE_PROP(_n, _s, _f, css_devid_ro_propinfo, CssDevId)
@@ -225,4 +234,8 @@ extern PropertyInfo css_devid_ro_propinfo;
  */
 SubchDev *css_create_sch(CssDevId bus_id, bool is_virtual, bool squash_mcss,
                          Error **errp);
+
+/** Turn on css migration */
+void css_register_vmstate(void);
+
 #endif
diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h
index 3027555f6d..41a9d2862b 100644
--- a/include/hw/s390x/s390-virtio-ccw.h
+++ b/include/hw/s390x/s390-virtio-ccw.h
@@ -39,11 +39,21 @@ typedef struct S390CcwMachineClass {
     /*< public >*/
     bool ri_allowed;
     bool cpu_model_allowed;
+    bool css_migration_enabled;
+    bool gs_allowed;
 } S390CcwMachineClass;
 
 /* runtime-instrumentation allowed by the machine */
 bool ri_allowed(void);
 /* cpu model allowed by the machine */
 bool cpu_model_allowed(void);
+/* guarded-storage allowed by the machine */
+bool gs_allowed(void);
+
+/**
+ * Returns true if (vmstate based) migration of the channel subsystem
+ * is enabled, false if it is disabled.
+ */
+bool css_migration_enabled(void);
 
 #endif
diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h
index caa6fc608d..7aab6ef7f0 100644
--- a/include/hw/s390x/s390_flic.h
+++ b/include/hw/s390x/s390_flic.h
@@ -44,7 +44,7 @@ typedef struct S390FLICState {
     SysBusDevice parent_obj;
     /* to limit AdapterRoutes.num_routes for compat */
     uint32_t adapter_routes_max_batch;
-
+    bool ais_supported;
 } S390FLICState;
 
 #define S390_FLIC_COMMON_CLASS(klass) \
@@ -56,13 +56,16 @@ typedef struct S390FLICStateClass {
     DeviceClass parent_class;
 
     int (*register_io_adapter)(S390FLICState *fs, uint32_t id, uint8_t isc,
-                               bool swap, bool maskable);
+                               bool swap, bool maskable, uint8_t flags);
     int (*io_adapter_map)(S390FLICState *fs, uint32_t id, uint64_t map_addr,
                           bool do_map);
     int (*add_adapter_routes)(S390FLICState *fs, AdapterRoutes *routes);
     void (*release_adapter_routes)(S390FLICState *fs, AdapterRoutes *routes);
     int (*clear_io_irq)(S390FLICState *fs, uint16_t subchannel_id,
                         uint16_t subchannel_nr);
+    int (*modify_ais_mode)(S390FLICState *fs, uint8_t isc, uint16_t mode);
+    int (*inject_airq)(S390FLICState *fs, uint8_t type, uint8_t isc,
+                       uint8_t flags);
 } S390FLICStateClass;
 
 #define TYPE_KVM_S390_FLIC "s390-flic-kvm"
@@ -73,13 +76,20 @@ typedef struct S390FLICStateClass {
 #define QEMU_S390_FLIC(obj) \
     OBJECT_CHECK(QEMUS390FLICState, (obj), TYPE_QEMU_S390_FLIC)
 
+#define SIC_IRQ_MODE_ALL 0
+#define SIC_IRQ_MODE_SINGLE 1
+#define AIS_MODE_MASK(isc) (0x80 >> isc)
+
 typedef struct QEMUS390FLICState {
     S390FLICState parent_obj;
+    uint8_t simm;
+    uint8_t nimm;
 } QEMUS390FLICState;
 
 void s390_flic_init(void);
 
 S390FLICState *s390_get_flic(void);
+bool ais_needed(void *opaque);
 
 #ifdef CONFIG_KVM
 DeviceState *s390_flic_kvm_create(void);
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index 3008a5148a..e71d526605 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -123,8 +123,7 @@ typedef struct ReadInfo {
     uint64_t facilities;                /* 48-55 */
     uint8_t  _reserved0[76 - 56];       /* 56-75 */
     uint32_t ibc_val;
-    uint8_t  conf_char[96 - 80];        /* 80-95 */
-    uint8_t  _reserved4[99 - 96];       /* 96-98 */
+    uint8_t  conf_char[99 - 80];        /* 80-98 */
     uint8_t mha_pow;
     uint32_t rnsize2;
     uint64_t rnmax2;
diff --git a/include/hw/s390x/storage-attributes.h b/include/hw/s390x/storage-attributes.h
new file mode 100644
index 0000000000..9be954d163
--- /dev/null
+++ b/include/hw/s390x/storage-attributes.h
@@ -0,0 +1,81 @@
+/*
+ * s390 storage attributes device
+ *
+ * Copyright 2016 IBM Corp.
+ * Author(s): Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#ifndef S390_STORAGE_ATTRIBUTES_H
+#define S390_STORAGE_ATTRIBUTES_H
+
+#include <hw/qdev.h>
+#include "monitor/monitor.h"
+
+#define TYPE_S390_STATTRIB "s390-storage_attributes"
+#define TYPE_QEMU_S390_STATTRIB "s390-storage_attributes-qemu"
+#define TYPE_KVM_S390_STATTRIB "s390-storage_attributes-kvm"
+
+#define S390_STATTRIB(obj) \
+    OBJECT_CHECK(S390StAttribState, (obj), TYPE_S390_STATTRIB)
+
+typedef struct S390StAttribState {
+    DeviceState parent_obj;
+    uint64_t migration_cur_gfn;
+    bool migration_enabled;
+} S390StAttribState;
+
+#define S390_STATTRIB_CLASS(klass) \
+    OBJECT_CLASS_CHECK(S390StAttribClass, (klass), TYPE_S390_STATTRIB)
+#define S390_STATTRIB_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(S390StAttribClass, (obj), TYPE_S390_STATTRIB)
+
+typedef struct S390StAttribClass {
+    DeviceClass parent_class;
+    /* Return value: < 0 on error, or new count */
+    int (*get_stattr)(S390StAttribState *sa, uint64_t *start_gfn,
+                      uint32_t count, uint8_t *values);
+    int (*peek_stattr)(S390StAttribState *sa, uint64_t start_gfn,
+                       uint32_t count, uint8_t *values);
+    int (*set_stattr)(S390StAttribState *sa, uint64_t start_gfn,
+                      uint32_t count, uint8_t *values);
+    void (*synchronize)(S390StAttribState *sa);
+    int (*set_migrationmode)(S390StAttribState *sa, bool value);
+    int (*get_active)(S390StAttribState *sa);
+    long long (*get_dirtycount)(S390StAttribState *sa);
+} S390StAttribClass;
+
+#define QEMU_S390_STATTRIB(obj) \
+    OBJECT_CHECK(QEMUS390StAttribState, (obj), TYPE_QEMU_S390_STATTRIB)
+
+typedef struct QEMUS390StAttribState {
+    S390StAttribState parent_obj;
+} QEMUS390StAttribState;
+
+#define KVM_S390_STATTRIB(obj) \
+    OBJECT_CHECK(KVMS390StAttribState, (obj), TYPE_KVM_S390_STATTRIB)
+
+typedef struct KVMS390StAttribState {
+    S390StAttribState parent_obj;
+    uint64_t still_dirty;
+    uint8_t *incoming_buffer;
+} KVMS390StAttribState;
+
+void s390_stattrib_init(void);
+
+#ifdef CONFIG_KVM
+Object *kvm_s390_stattrib_create(void);
+#else
+static inline Object *kvm_s390_stattrib_create(void)
+{
+    return NULL;
+}
+#endif
+
+void hmp_info_cmma(Monitor *mon, const QDict *qdict);
+void hmp_migrationmode(Monitor *mon, const QDict *qdict);
+
+#endif /* S390_STORAGE_ATTRIBUTES_H */
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 0b475a3596..f3a2ac9fee 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -95,7 +95,7 @@ typedef struct VFIOContainer {
 
 typedef struct VFIOGuestIOMMU {
     VFIOContainer *container;
-    MemoryRegion *iommu;
+    IOMMUMemoryRegion *iommu;
     hwaddr iommu_offset;
     IOMMUNotifier n;
     QLIST_ENTRY(VFIOGuestIOMMU) giommu_next;