From ee9a569ab88edd0755402aaf31ec0c69decf7756 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Thu, 29 Jan 2015 16:04:58 +1100 Subject: spapr_vio/spapr_iommu: Move VIO bypass where it belongs Instead of tweaking a TCE table device by adding there a bypass flag, let's add an alias to RAM and IOMMU memory region, and enable/disable those according to the selected bypass mode. This way IOMMU memory region can have size of the actual window rather than ram_size which is essential for upcoming DDW support. This moves bypass logic to VIO layer and keeps @bypass flag in TCE table for migration compatibility only. This replaces spapr_tce_set_bypass() calls with explicit assignment to avoid confusion as the function could do something more that just syncing the @bypass flag. This adds a pointer to VIO device into the sPAPRTCETable struct to provide the sPAPRTCETable device a way to update bypass mode for the VIO device. Signed-off-by: Alexey Kardashevskiy Reviewed-by: David Gibson Signed-off-by: Alexander Graf --- include/hw/ppc/spapr.h | 2 +- include/hw/ppc/spapr_vio.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'include/hw') diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 716bff4..642cdc3 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -463,6 +463,7 @@ struct sPAPRTCETable { bool vfio_accel; int fd; MemoryRegion iommu; + struct VIOsPAPRDevice *vdev; /* for @bypass migration compatibility only */ QLIST_ENTRY(sPAPRTCETable) list; }; @@ -475,7 +476,6 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, uint32_t nb_table, bool vfio_accel); MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet); -void spapr_tce_set_bypass(sPAPRTCETable *tcet, bool bypass); int spapr_dma_dt(void *fdt, int node_off, const char *propname, uint32_t liobn, uint64_t window, uint32_t size); int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h index 46edc2a..222397d 100644 --- a/include/hw/ppc/spapr_vio.h +++ b/include/hw/ppc/spapr_vio.h @@ -64,6 +64,8 @@ struct VIOsPAPRDevice { target_ulong signal_state; VIOsPAPR_CRQ crq; AddressSpace as; + MemoryRegion mrroot; + MemoryRegion mrbypass; sPAPRTCETable *tcet; }; @@ -139,4 +141,6 @@ extern const VMStateDescription vmstate_spapr_vio; #define VMSTATE_SPAPR_VIO(_f, _s) \ VMSTATE_STRUCT(_f, _s, 0, vmstate_spapr_vio, VIOsPAPRDevice) +void spapr_vio_set_bypass(VIOsPAPRDevice *dev, bool bypass); + #endif /* _HW_SPAPR_VIO_H */ -- cgit v1.1 From 3e4ac9687103f907eadea10d6176eb2e989d1e36 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 14 Jan 2015 13:33:39 +1100 Subject: pseries: Limit PCI host bridge "index" value pseries guests can have large numbers of PCI host bridges. To avoid the user having to specify a number of different configuration values for every one, the device supports an "index" property which is a shorthand setting the various window and configuration addresses from a predefined sensible set. There are some problems with the details at present: * The "index" propery is signed, but negative values will create PCI windows below where we expect, potentially colliding with other devices * No limit is imposed on the "index" property and large values can translate to extremely large window addresses. With PCI passthrough in particular this can mean we exceed various mapping and physical address limits causing the guest host bridge to not work in strange ways. This patch addresses this, by making "index" unsigned, and imposing a limit. Currently the limit allows indices from 0..255 which is probably enough host bridges for the time being. It's fairly easy to extend if we discover we need more. Signed-off-by: David Gibson Reviewed-by: Paolo Bonzini Reviewed-by: Michael Roth Signed-off-by: Alexander Graf --- include/hw/pci-host/spapr.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/hw') diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 4ea2a0d..876ecf09 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -64,7 +64,7 @@ typedef struct spapr_pci_msi_mig { struct sPAPRPHBState { PCIHostState parent_obj; - int32_t index; + uint32_t index; uint64_t buid; char *dtbusname; @@ -94,6 +94,8 @@ struct sPAPRPHBVFIOState { int32_t iommugroupid; }; +#define SPAPR_PCI_MAX_INDEX 255 + #define SPAPR_PCI_BASE_BUID 0x800000020000000ULL #define SPAPR_PCI_WINDOW_BASE 0x10000000000ULL -- cgit v1.1 From b194df478ae7607d93b47a8307e623c9f9f2b3ab Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Fri, 30 Jan 2015 12:53:19 +1100 Subject: spapr-pci: Enable huge BARs At the moment sPAPR only supports 512MB window for MMIO BARs. However modern devices might want bigger 64bit BARs. This extends MMIO window from 512MB to 62GB (aligned to SPAPR_PCI_WINDOW_SPACING) and advertises it in 2 records in the PHB "ranges" property. 32bit gets the space from SPAPR_PCI_MEM_WIN_BUS_OFFSET till the end of 4GB, 64bit gets the rest of the space. If no space is left, 64bit range is not advertised. The MMIO space size is set to old value of 0x20000000 by default for pseries machines older than 2.3. The approach changes the device tree which is a guest visible change, however it won't break migration as: 1. we do not support migration to older QEMU versions 2. migration to newer QEMU will migrate the device tree as well and since the new layout only extends the old one and does not change address mappigns, no breakage is expected here too. SLOF change is required to utilize this extension. Suggested-by: Benjamin Herrenschmidt Signed-off-by: Alexey Kardashevskiy Reviewed-by: David Gibson Signed-off-by: Alexander Graf --- include/hw/pci-host/spapr.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include/hw') diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 876ecf09..d725f0e 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -98,17 +98,18 @@ struct sPAPRPHBVFIOState { #define SPAPR_PCI_BASE_BUID 0x800000020000000ULL +#define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL + #define SPAPR_PCI_WINDOW_BASE 0x10000000000ULL #define SPAPR_PCI_WINDOW_SPACING 0x1000000000ULL #define SPAPR_PCI_MMIO_WIN_OFF 0xA0000000 -#define SPAPR_PCI_MMIO_WIN_SIZE 0x20000000 +#define SPAPR_PCI_MMIO_WIN_SIZE (SPAPR_PCI_WINDOW_SPACING - \ + SPAPR_PCI_MEM_WIN_BUS_OFFSET) #define SPAPR_PCI_IO_WIN_OFF 0x80000000 #define SPAPR_PCI_IO_WIN_SIZE 0x10000 #define SPAPR_PCI_MSI_WINDOW 0x40000000000ULL -#define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL - static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin) { return xics_get_qirq(spapr->icp, phb->lsi_table[pin].irq); -- cgit v1.1 From 12f421745cd763742377c7134f48fa12fb889ee3 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 6 Feb 2015 14:55:47 +1100 Subject: pseries: Move sPAPR RTC code into its own file At the moment the RTAS (firmware/hypervisor) time of day functions are implemented in spapr_rtas.c along with a bunch of other things. Since we're going to be expanding these a bit, move the RTAS RTC related code out into new file spapr_rtc.c. Also add its own initialization function, spapr_rtc_init() called from the main machine init routine. Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- include/hw/ppc/spapr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/hw') diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 642cdc3..e43339d 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -480,5 +480,6 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname, uint32_t liobn, uint64_t window, uint32_t size); int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, sPAPRTCETable *tcet); +void spapr_rtc_init(void); #endif /* !defined (__HW_SPAPR_H__) */ -- cgit v1.1 From e5dad1d7d1618822dbadb1dd12efa1b5674b6c40 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 6 Feb 2015 14:55:49 +1100 Subject: pseries: Add spapr_rtc_read() helper function The virtual RTC time is used in two places in the pseries machine. First is in the RTAS get-time-of-day function which returns the RTC time to the guest. Second is in the spapr events code which is used to timestamp event messages from the hypervisor to the guest. Currently both call qemu_get_timedate() directly, but we want to change that so we can properly handle the various -rtc options. In preparation, create a helper function to return the virtual RTC time. Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- include/hw/ppc/spapr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/hw') diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index e43339d..0fd4912 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -481,5 +481,6 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname, int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, sPAPRTCETable *tcet); void spapr_rtc_init(void); +void spapr_rtc_read(sPAPREnvironment *spapr, struct tm *tm, uint32_t *ns); #endif /* !defined (__HW_SPAPR_H__) */ -- cgit v1.1 From 28df36a13a3b0b792d9df64f8db8a392df5e0b35 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 6 Feb 2015 14:55:51 +1100 Subject: pseries: Make the PAPR RTC a qdev device At present the PAPR RTC isn't a "device" as such - it's accessed only via firmware/hypervisor calls, and is handled in the sPAPR core code. This becomes inconvenient as we extend it in various ways. This patch makes the PAPR RTC a separate device in the qemu device model. For now, the only piece of device state - the rtc_offset - is still kept in the global sPAPREnvironment structure. That's clearly wrong, but leaving it to be fixed in a following patch makes for a clearer separation between the internal re-organization of the device, and the behavioural changes (because the migration stream format needs to change slightly when the offset is moved into the device's own state). Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- include/hw/ppc/spapr.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include/hw') diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 0fd4912..80c6e4f 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -15,6 +15,7 @@ typedef struct sPAPREnvironment { QLIST_HEAD(, sPAPRPHBState) phbs; struct sPAPRNVRAM *nvram; XICSState *icp; + DeviceState *rtc; hwaddr ram_limit; void *htab; @@ -480,7 +481,9 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname, uint32_t liobn, uint64_t window, uint32_t size); int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, sPAPRTCETable *tcet); -void spapr_rtc_init(void); -void spapr_rtc_read(sPAPREnvironment *spapr, struct tm *tm, uint32_t *ns); + +#define TYPE_SPAPR_RTC "spapr-rtc" + +void spapr_rtc_read(DeviceState *dev, struct tm *tm, uint32_t *ns); #endif /* !defined (__HW_SPAPR_H__) */ -- cgit v1.1 From 880ae7de5958a765699386777de0f3841d635e1d Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 6 Feb 2015 14:55:52 +1100 Subject: pseries: Move rtc_offset into RTC device's state structure The initial creation of the PAPR RTC qdev class left a wart - the rtc's offset was left in the sPAPREnvironment structure, accessed via a global. This patch moves it into the RTC device's own state structure, were it belongs. This requires a small change to the migration stream format. In order to handle incoming streams from older versions, we also need to retain the rtc_offset field in the sPAPREnvironment structure, so that it can be loaded into via the vmsd, then pushed into the RTC device. Since we're changing the migration format, this also takes the opportunity to: * Change the rtc offset from a value in seconds to a value in nanoseconds, allowing nanosecond offsets between host and guest rtc time, if desired. * Remove both the already unused "next_irq" field and now unused "rtc_offset" field from the new version of the spapr migration stream Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- include/hw/ppc/spapr.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/hw') diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 80c6e4f..a8e6817 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -27,7 +27,7 @@ typedef struct sPAPREnvironment { void *rtas_blob; void *fdt_skel; target_ulong entry_point; - uint64_t rtc_offset; + uint64_t rtc_offset; /* Now used only during incoming migration */ struct PPCTimebase tb; bool has_graphics; @@ -485,5 +485,6 @@ int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, #define TYPE_SPAPR_RTC "spapr-rtc" void spapr_rtc_read(DeviceState *dev, struct tm *tm, uint32_t *ns); +int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset); #endif /* !defined (__HW_SPAPR_H__) */ -- cgit v1.1 From eefaccc02bab659c8cb4c994b2f385c3f0a27551 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 10 Feb 2015 15:36:16 +1100 Subject: pseries: Switch VGA endian on H_SET_MODE When the guest switches the interrupt endian mode, which essentially means a global machine endian switch, we want to change the VGA framebuffer endian mode as well in order to be backward compatible with existing guests who don't know about the new endian control register. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: David Gibson Reviewed-by: Michael Roth Signed-off-by: Alexander Graf --- include/hw/ppc/spapr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/hw') diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index a8e6817..168b608 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -481,6 +481,7 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname, uint32_t liobn, uint64_t window, uint32_t size); int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, sPAPRTCETable *tcet); +void spapr_pci_switch_vga(bool big_endian); #define TYPE_SPAPR_RTC "spapr-rtc" -- cgit v1.1 From 28b07e737eb58f299b066c1c6b3740bb055a2cf9 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 27 Feb 2015 11:52:17 +0100 Subject: spapr_vio: Convert to realize() Bonus fix: always set an error on failure. Some failures were silent before, except for the generic error set by device_realize(). Signed-off-by: Markus Armbruster Signed-off-by: Alexander Graf --- include/hw/ppc/spapr_vio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/hw') diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h index 222397d..f95016a 100644 --- a/include/hw/ppc/spapr_vio.h +++ b/include/hw/ppc/spapr_vio.h @@ -52,7 +52,7 @@ typedef struct VIOsPAPRDeviceClass { const char *dt_name, *dt_type, *dt_compatible; target_ulong signal_mask; uint32_t rtce_window_size; - int (*init)(VIOsPAPRDevice *dev); + void (*realize)(VIOsPAPRDevice *dev, Error **errp); void (*reset)(VIOsPAPRDevice *dev); int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off); } VIOsPAPRDeviceClass; -- cgit v1.1 From ee954280da8d9ea7afd28b4c288da15fb8b4efca Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Fri, 20 Feb 2015 15:58:52 +1100 Subject: sPAPR: Implement EEH RTAS calls The emulation for EEH RTAS requests from guest isn't covered by QEMU yet and the patch implements them. The patch defines constants used by EEH RTAS calls and adds callbacks sPAPRPHBClass::{eeh_set_option, eeh_get_state, eeh_reset, eeh_configure}, which are going to be used as follows: * RTAS calls are received in spapr_pci.c, sanity check is done there. * RTAS handlers handle what they can. If there is something it cannot handle and the corresponding sPAPRPHBClass callback is defined, it is called. * Those callbacks are only implemented for VFIO now. They do ioctl() to the IOMMU container fd to complete the calls. Error codes from that ioctl() are transferred back to the guest. [aik: defined RTAS tokens for EEH RTAS calls] Signed-off-by: Gavin Shan Reviewed-by: David Gibson Signed-off-by: Alexander Graf --- include/hw/pci-host/spapr.h | 4 ++++ include/hw/ppc/spapr.h | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) (limited to 'include/hw') diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index d725f0e..895d273 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -49,6 +49,10 @@ struct sPAPRPHBClass { PCIHostBridgeClass parent_class; void (*finish_realize)(sPAPRPHBState *sphb, Error **errp); + int (*eeh_set_option)(sPAPRPHBState *sphb, unsigned int addr, int option); + int (*eeh_get_state)(sPAPRPHBState *sphb, int *state); + int (*eeh_reset)(sPAPRPHBState *sphb, int option); + int (*eeh_configure)(sPAPRPHBState *sphb); }; typedef struct spapr_pci_msi { diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 168b608..af71e8b 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -339,6 +339,39 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode, int spapr_allocate_irq(int hint, bool lsi); int spapr_allocate_irq_block(int num, bool lsi, bool msi); +/* ibm,set-eeh-option */ +#define RTAS_EEH_DISABLE 0 +#define RTAS_EEH_ENABLE 1 +#define RTAS_EEH_THAW_IO 2 +#define RTAS_EEH_THAW_DMA 3 + +/* ibm,get-config-addr-info2 */ +#define RTAS_GET_PE_ADDR 0 +#define RTAS_GET_PE_MODE 1 +#define RTAS_PE_MODE_NONE 0 +#define RTAS_PE_MODE_NOT_SHARED 1 +#define RTAS_PE_MODE_SHARED 2 + +/* ibm,read-slot-reset-state2 */ +#define RTAS_EEH_PE_STATE_NORMAL 0 +#define RTAS_EEH_PE_STATE_RESET 1 +#define RTAS_EEH_PE_STATE_STOPPED_IO_DMA 2 +#define RTAS_EEH_PE_STATE_STOPPED_DMA 4 +#define RTAS_EEH_PE_STATE_UNAVAIL 5 +#define RTAS_EEH_NOT_SUPPORT 0 +#define RTAS_EEH_SUPPORT 1 +#define RTAS_EEH_PE_UNAVAIL_INFO 1000 +#define RTAS_EEH_PE_RECOVER_INFO 0 + +/* ibm,set-slot-reset */ +#define RTAS_SLOT_RESET_DEACTIVATE 0 +#define RTAS_SLOT_RESET_HOT 1 +#define RTAS_SLOT_RESET_FUNDAMENTAL 3 + +/* ibm,slot-error-detail */ +#define RTAS_SLOT_TEMP_ERR_LOG 1 +#define RTAS_SLOT_PERM_ERR_LOG 2 + /* RTAS return codes */ #define RTAS_OUT_SUCCESS 0 #define RTAS_OUT_NO_ERRORS_FOUND 1 @@ -383,8 +416,14 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi); #define RTAS_GET_SENSOR_STATE (RTAS_TOKEN_BASE + 0x1D) #define RTAS_IBM_CONFIGURE_CONNECTOR (RTAS_TOKEN_BASE + 0x1E) #define RTAS_IBM_OS_TERM (RTAS_TOKEN_BASE + 0x1F) - -#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x20) +#define RTAS_IBM_SET_EEH_OPTION (RTAS_TOKEN_BASE + 0x20) +#define RTAS_IBM_GET_CONFIG_ADDR_INFO2 (RTAS_TOKEN_BASE + 0x21) +#define RTAS_IBM_READ_SLOT_RESET_STATE2 (RTAS_TOKEN_BASE + 0x22) +#define RTAS_IBM_SET_SLOT_RESET (RTAS_TOKEN_BASE + 0x23) +#define RTAS_IBM_CONFIGURE_PE (RTAS_TOKEN_BASE + 0x24) +#define RTAS_IBM_SLOT_ERROR_DETAIL (RTAS_TOKEN_BASE + 0x25) + +#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x26) /* RTAS ibm,get-system-parameter token values */ #define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS 20 -- cgit v1.1