* [PATCH v5 00/13] basic channel IO passthrough infrastructure based on vfio
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
The patch series introduce a basic channel I/O passthrough
infrastructure based on vfio.
- Focus on supporting dasd-eckd(cu_type/dev_type = 0x3990/0x3390) as
the target device.
- Support new qemu parameters in the style of:
-machine s390-ccw-virtio(,s390-squash-mcss=on|off) \
-device vfio-ccw,sysfsdev=$MDEV_PATH
We want to support real (i.e. not virtual) channel devices even for
guests that do not support MCSS-E (where guests may see devices from
any channel subsystem image at once). As all virtio-ccw devices are in
css 0xfe (and show up in the default css 0 for guests not activating
MCSS-E), we need an option to squash e.g. passed-through channel devices
from their real css (0-3, or 0 for hosts not activating MCSS-E) into
the default css, that is what the new machine option s390-squash-css is
added.
Build and install:
1. kernel configuration
CONFIG_S390_CCW_IOMMU=m
CONFIG_VFIO=m
CONFIG_VFIO_MDEV=m
CONFIG_VFIO_MDEV_DEVICE=m
CONFIG_VFIO_CCW=m
2. modules required
modprobe vfio.ko
modprobe mdev.ko
modprobe vfio_mdev.ko
modprobe vfio_iommu_type1.ko
modprobe vfio_ccw.ko
3. find a subchannel(0.0."%schid") of a DASD-ECKD device and bind it to
vfio_ccw driver
#find the dasd you can use with lsdasd on your host. e.g.:
devno="7e52"
schid="16ca"
#unbind the ccw device from the subchannel
echo 0.0."$devno" > /sys/bus/ccw/devices/0.0."$devno"/driver/unbind
#unbind the subchannel from io_subchannel driver
echo 0.0."$schid" > /sys/bus/css/devices/0.0."$schid"/driver/unbind
#bind the subchannel with vfio_ccw driver
echo 0.0."$schid" > /sys/bus/css/drivers/vfio_ccw/bind
4. create a mediated device
#generate a uuid with uuidgen. e.g.:
uuid="6dfd3ec5-e8b3-4e18-a6fe-57bc9eceb920"
echo "$uuid" > \
/sys/bus/css/devices/0.0."$schid"/mdev_supported_types/vfio_ccw-io/create
5. pass-through this device to a vm
-M s390-ccw-virtio,s390-squash-css=on \
-device vfio-ccw,sysfsdev=/sys/bus/mdev/devices/$uuid \
... ...
Change log:
v4 -> v5:
1. Rebase to git://github.com/cohuck/qemu s390-next.
2. New patch #1: update-linux-headers.
3. Patch #6: update s390_ccw_realize according to the new code base.
4. New patch #13: add maintainer for vfio-ccw.
v3 -> v4:
1. Adjustments of the s-o-b chains for some patches.
v2 -> v3:
1. Move vfio_ccw.h to uapi.
2. Adopt the vfio-ccw cmdline interface as vfio-pci with mdev devices.
3. Rename s390-map-css to s390-squash-mcss (patch 2), and update devno
generation method (patch 5).
4. Patch 7: correct the validation of num_regions.
5. Patch 8: correct the validation of num_irqs.
v1 -> v2:
1. Rebase the implementation to the mdev framework approach.
2. Use pread and pwrite on an I/O region to issue I/O requests and
receive results.
Dong Jia Shi (8):
update-linux-headers: update for vfio-ccw
vfio: linux-headers update for vfio-ccw
s390x/css: realize css_create_sch
s390x/css: device support for s390-ccw passthrough
vfio/ccw: get io region info
vfio/ccw: get irqs info and set the eventfd fd
vfio/ccw: update sense data if a unit check is pending
MAINTAINERS: Add vfio-ccw maintainer
Xiao Feng Ren (5):
s390x/css: add s390-squash-mcss machine option
s390x/css: realize css_sch_build_schib
vfio/ccw: vfio based subchannel passthrough driver
s390x/css: introduce and realize ccw-request callback
s390x/css: ccw translation infrastructure
MAINTAINERS | 5 +
default-configs/s390x-softmmu.mak | 1 +
hw/s390x/Makefile.objs | 1 +
hw/s390x/css-bridge.c | 2 +
hw/s390x/css.c | 290 ++++++++++++++++++++++--
hw/s390x/s390-ccw.c | 146 ++++++++++++
hw/s390x/s390-ccw.h | 39 ++++
hw/s390x/s390-virtio-ccw.c | 35 ++-
hw/s390x/virtio-ccw.c | 7 +-
hw/vfio/Makefile.objs | 1 +
hw/vfio/ccw.c | 441 +++++++++++++++++++++++++++++++++++++
include/hw/s390x/css-bridge.h | 1 +
include/hw/s390x/css.h | 67 +++---
include/hw/s390x/s390-virtio-ccw.h | 1 +
include/hw/vfio/vfio-common.h | 1 +
linux-headers/linux/vfio.h | 17 ++
linux-headers/linux/vfio_ccw.h | 28 +++
qemu-options.hx | 6 +-
scripts/update-linux-headers.sh | 2 +-
target/s390x/cpu.h | 10 +
target/s390x/ioinst.c | 9 +
21 files changed, 1061 insertions(+), 49 deletions(-)
create mode 100644 hw/s390x/s390-ccw.c
create mode 100644 hw/s390x/s390-ccw.h
create mode 100644 hw/vfio/ccw.c
create mode 100644 linux-headers/linux/vfio_ccw.h
--
2.10.2
^ permalink raw reply [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 00/13] basic channel IO passthrough infrastructure based on vfio
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
The patch series introduce a basic channel I/O passthrough
infrastructure based on vfio.
- Focus on supporting dasd-eckd(cu_type/dev_type = 0x3990/0x3390) as
the target device.
- Support new qemu parameters in the style of:
-machine s390-ccw-virtio(,s390-squash-mcss=on|off) \
-device vfio-ccw,sysfsdev=$MDEV_PATH
We want to support real (i.e. not virtual) channel devices even for
guests that do not support MCSS-E (where guests may see devices from
any channel subsystem image at once). As all virtio-ccw devices are in
css 0xfe (and show up in the default css 0 for guests not activating
MCSS-E), we need an option to squash e.g. passed-through channel devices
from their real css (0-3, or 0 for hosts not activating MCSS-E) into
the default css, that is what the new machine option s390-squash-css is
added.
Build and install:
1. kernel configuration
CONFIG_S390_CCW_IOMMU=m
CONFIG_VFIO=m
CONFIG_VFIO_MDEV=m
CONFIG_VFIO_MDEV_DEVICE=m
CONFIG_VFIO_CCW=m
2. modules required
modprobe vfio.ko
modprobe mdev.ko
modprobe vfio_mdev.ko
modprobe vfio_iommu_type1.ko
modprobe vfio_ccw.ko
3. find a subchannel(0.0."%schid") of a DASD-ECKD device and bind it to
vfio_ccw driver
#find the dasd you can use with lsdasd on your host. e.g.:
devno="7e52"
schid="16ca"
#unbind the ccw device from the subchannel
echo 0.0."$devno" > /sys/bus/ccw/devices/0.0."$devno"/driver/unbind
#unbind the subchannel from io_subchannel driver
echo 0.0."$schid" > /sys/bus/css/devices/0.0."$schid"/driver/unbind
#bind the subchannel with vfio_ccw driver
echo 0.0."$schid" > /sys/bus/css/drivers/vfio_ccw/bind
4. create a mediated device
#generate a uuid with uuidgen. e.g.:
uuid="6dfd3ec5-e8b3-4e18-a6fe-57bc9eceb920"
echo "$uuid" > \
/sys/bus/css/devices/0.0."$schid"/mdev_supported_types/vfio_ccw-io/create
5. pass-through this device to a vm
-M s390-ccw-virtio,s390-squash-css=on \
-device vfio-ccw,sysfsdev=/sys/bus/mdev/devices/$uuid \
... ...
Change log:
v4 -> v5:
1. Rebase to git://github.com/cohuck/qemu s390-next.
2. New patch #1: update-linux-headers.
3. Patch #6: update s390_ccw_realize according to the new code base.
4. New patch #13: add maintainer for vfio-ccw.
v3 -> v4:
1. Adjustments of the s-o-b chains for some patches.
v2 -> v3:
1. Move vfio_ccw.h to uapi.
2. Adopt the vfio-ccw cmdline interface as vfio-pci with mdev devices.
3. Rename s390-map-css to s390-squash-mcss (patch 2), and update devno
generation method (patch 5).
4. Patch 7: correct the validation of num_regions.
5. Patch 8: correct the validation of num_irqs.
v1 -> v2:
1. Rebase the implementation to the mdev framework approach.
2. Use pread and pwrite on an I/O region to issue I/O requests and
receive results.
Dong Jia Shi (8):
update-linux-headers: update for vfio-ccw
vfio: linux-headers update for vfio-ccw
s390x/css: realize css_create_sch
s390x/css: device support for s390-ccw passthrough
vfio/ccw: get io region info
vfio/ccw: get irqs info and set the eventfd fd
vfio/ccw: update sense data if a unit check is pending
MAINTAINERS: Add vfio-ccw maintainer
Xiao Feng Ren (5):
s390x/css: add s390-squash-mcss machine option
s390x/css: realize css_sch_build_schib
vfio/ccw: vfio based subchannel passthrough driver
s390x/css: introduce and realize ccw-request callback
s390x/css: ccw translation infrastructure
MAINTAINERS | 5 +
default-configs/s390x-softmmu.mak | 1 +
hw/s390x/Makefile.objs | 1 +
hw/s390x/css-bridge.c | 2 +
hw/s390x/css.c | 290 ++++++++++++++++++++++--
hw/s390x/s390-ccw.c | 146 ++++++++++++
hw/s390x/s390-ccw.h | 39 ++++
hw/s390x/s390-virtio-ccw.c | 35 ++-
hw/s390x/virtio-ccw.c | 7 +-
hw/vfio/Makefile.objs | 1 +
hw/vfio/ccw.c | 441 +++++++++++++++++++++++++++++++++++++
include/hw/s390x/css-bridge.h | 1 +
include/hw/s390x/css.h | 67 +++---
include/hw/s390x/s390-virtio-ccw.h | 1 +
include/hw/vfio/vfio-common.h | 1 +
linux-headers/linux/vfio.h | 17 ++
linux-headers/linux/vfio_ccw.h | 28 +++
qemu-options.hx | 6 +-
scripts/update-linux-headers.sh | 2 +-
target/s390x/cpu.h | 10 +
target/s390x/ioinst.c | 9 +
21 files changed, 1061 insertions(+), 49 deletions(-)
create mode 100644 hw/s390x/s390-ccw.c
create mode 100644 hw/s390x/s390-ccw.h
create mode 100644 hw/vfio/ccw.c
create mode 100644 linux-headers/linux/vfio_ccw.h
--
2.10.2
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH v5 01/13] update-linux-headers: update for vfio-ccw
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
Add vfio_ccw.h.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
| 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 6a370a8..2f906c4 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -113,7 +113,7 @@ done
rm -rf "$output/linux-headers/linux"
mkdir -p "$output/linux-headers/linux"
-for header in kvm.h kvm_para.h vfio.h vhost.h \
+for header in kvm.h kvm_para.h vfio.h vfio_ccw.h vhost.h \
psci.h userfaultfd.h; do
cp "$tmpdir/include/linux/$header" "$output/linux-headers/linux"
done
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 01/13] update-linux-headers: update for vfio-ccw
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
Add vfio_ccw.h.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
| 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 6a370a8..2f906c4 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -113,7 +113,7 @@ done
rm -rf "$output/linux-headers/linux"
mkdir -p "$output/linux-headers/linux"
-for header in kvm.h kvm_para.h vfio.h vhost.h \
+for header in kvm.h kvm_para.h vfio.h vfio_ccw.h vhost.h \
psci.h userfaultfd.h; do
cp "$tmpdir/include/linux/$header" "$output/linux-headers/linux"
done
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v5 02/13] vfio: linux-headers update for vfio-ccw
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
This is a placeholder for a linux-headers update.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
| 17 +++++++++++++++++
| 28 ++++++++++++++++++++++++++++
2 files changed, 45 insertions(+)
create mode 100644 linux-headers/linux/vfio_ccw.h
--git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index 531cb2e..39a1d3b 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -198,6 +198,7 @@ struct vfio_device_info {
#define VFIO_DEVICE_FLAGS_PCI (1 << 1) /* vfio-pci device */
#define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2) /* vfio-platform device */
#define VFIO_DEVICE_FLAGS_AMBA (1 << 3) /* vfio-amba device */
+#define VFIO_DEVICE_FLAGS_CCW (1 << 4) /* vfio-ccw device */
__u32 num_regions; /* Max region index + 1 */
__u32 num_irqs; /* Max IRQ index + 1 */
};
@@ -446,6 +447,22 @@ enum {
VFIO_PCI_NUM_IRQS
};
+/*
+ * The VFIO-CCW bus driver makes use of the following fixed region and
+ * IRQ index mapping. Unimplemented regions return a size of zero.
+ * Unimplemented IRQ types return a count of zero.
+ */
+
+enum {
+ VFIO_CCW_CONFIG_REGION_INDEX,
+ VFIO_CCW_NUM_REGIONS
+};
+
+enum {
+ VFIO_CCW_IO_IRQ_INDEX,
+ VFIO_CCW_NUM_IRQS
+};
+
/**
* VFIO_DEVICE_GET_PCI_HOT_RESET_INFO - _IORW(VFIO_TYPE, VFIO_BASE + 12,
* struct vfio_pci_hot_reset_info)
--git a/linux-headers/linux/vfio_ccw.h b/linux-headers/linux/vfio_ccw.h
new file mode 100644
index 0000000..4ee74ae
--- /dev/null
+++ b/linux-headers/linux/vfio_ccw.h
@@ -0,0 +1,28 @@
+/*
+ * Interfaces for vfio-ccw
+ *
+ * Copyright IBM Corp. 2017
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (version 2 only)
+ * as published by the Free Software Foundation.
+ *
+ * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
+ */
+
+#ifndef _VFIO_CCW_H_
+#define _VFIO_CCW_H_
+
+#include <linux/types.h>
+
+struct ccw_io_region {
+#define ORB_AREA_SIZE 12
+ __u8 orb_area[ORB_AREA_SIZE];
+#define SCSW_AREA_SIZE 12
+ __u8 scsw_area[SCSW_AREA_SIZE];
+#define IRB_AREA_SIZE 96
+ __u8 irb_area[IRB_AREA_SIZE];
+ __u32 ret_code;
+} __packed;
+
+#endif
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 02/13] vfio: linux-headers update for vfio-ccw
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
This is a placeholder for a linux-headers update.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
| 17 +++++++++++++++++
| 28 ++++++++++++++++++++++++++++
2 files changed, 45 insertions(+)
create mode 100644 linux-headers/linux/vfio_ccw.h
--git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index 531cb2e..39a1d3b 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -198,6 +198,7 @@ struct vfio_device_info {
#define VFIO_DEVICE_FLAGS_PCI (1 << 1) /* vfio-pci device */
#define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2) /* vfio-platform device */
#define VFIO_DEVICE_FLAGS_AMBA (1 << 3) /* vfio-amba device */
+#define VFIO_DEVICE_FLAGS_CCW (1 << 4) /* vfio-ccw device */
__u32 num_regions; /* Max region index + 1 */
__u32 num_irqs; /* Max IRQ index + 1 */
};
@@ -446,6 +447,22 @@ enum {
VFIO_PCI_NUM_IRQS
};
+/*
+ * The VFIO-CCW bus driver makes use of the following fixed region and
+ * IRQ index mapping. Unimplemented regions return a size of zero.
+ * Unimplemented IRQ types return a count of zero.
+ */
+
+enum {
+ VFIO_CCW_CONFIG_REGION_INDEX,
+ VFIO_CCW_NUM_REGIONS
+};
+
+enum {
+ VFIO_CCW_IO_IRQ_INDEX,
+ VFIO_CCW_NUM_IRQS
+};
+
/**
* VFIO_DEVICE_GET_PCI_HOT_RESET_INFO - _IORW(VFIO_TYPE, VFIO_BASE + 12,
* struct vfio_pci_hot_reset_info)
--git a/linux-headers/linux/vfio_ccw.h b/linux-headers/linux/vfio_ccw.h
new file mode 100644
index 0000000..4ee74ae
--- /dev/null
+++ b/linux-headers/linux/vfio_ccw.h
@@ -0,0 +1,28 @@
+/*
+ * Interfaces for vfio-ccw
+ *
+ * Copyright IBM Corp. 2017
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (version 2 only)
+ * as published by the Free Software Foundation.
+ *
+ * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
+ */
+
+#ifndef _VFIO_CCW_H_
+#define _VFIO_CCW_H_
+
+#include <linux/types.h>
+
+struct ccw_io_region {
+#define ORB_AREA_SIZE 12
+ __u8 orb_area[ORB_AREA_SIZE];
+#define SCSW_AREA_SIZE 12
+ __u8 scsw_area[SCSW_AREA_SIZE];
+#define IRB_AREA_SIZE 96
+ __u8 irb_area[IRB_AREA_SIZE];
+ __u32 ret_code;
+} __packed;
+
+#endif
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v5 03/13] s390x/css: add s390-squash-mcss machine option
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
We want to support real (i.e. not virtual) channel devices
even for guests that do not support MCSS-E (where guests may
see devices from any channel subsystem image at once). As all
virtio-ccw devices are in css 0xfe (and show up in the default
css 0 for guests not activating MCSS-E), we need an option to
squash both the virtio subchannels and e.g. passed-through
subchannels from their real css (0-3, or 0 for hosts not
activating MCSS-E) into the default css. This will be
exploited in a later patch.
Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/s390x/s390-virtio-ccw.c | 23 +++++++++++++++++++++++
include/hw/s390x/s390-virtio-ccw.h | 1 +
qemu-options.hx | 6 +++++-
target/s390x/cpu.h | 10 ++++++++++
4 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 04bd0eb..bfa5f60 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -274,6 +274,21 @@ bool cpu_model_allowed(void)
return true;
}
+static inline bool machine_get_squash_mcss(Object *obj, Error **errp)
+{
+ S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
+
+ return ms->s390_squash_mcss;
+}
+
+static inline void machine_set_squash_mcss(Object *obj, bool value,
+ Error **errp)
+{
+ S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
+
+ ms->s390_squash_mcss = value;
+}
+
static inline void s390_machine_initfn(Object *obj)
{
object_property_add_bool(obj, "aes-key-wrap",
@@ -291,6 +306,14 @@ static inline void s390_machine_initfn(Object *obj)
"enable/disable DEA key wrapping using the CPACF wrapping key",
NULL);
object_property_set_bool(obj, true, "dea-key-wrap", NULL);
+
+ object_property_add_bool(obj, "s390-squash-mcss",
+ machine_get_squash_mcss,
+ machine_set_squash_mcss, NULL);
+ object_property_set_description(obj, "s390-squash-mcss",
+ "enable/disable squashing subchannels into the default css",
+ NULL);
+ object_property_set_bool(obj, false, "s390-squash-mcss", NULL);
}
static const TypeInfo ccw_machine_info = {
diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h
index 6ecae00..28d98fa 100644
--- a/include/hw/s390x/s390-virtio-ccw.h
+++ b/include/hw/s390x/s390-virtio-ccw.h
@@ -28,6 +28,7 @@ typedef struct S390CcwMachineState {
/*< public >*/
bool aes_key_wrap;
bool dea_key_wrap;
+ bool s390_squash_mcss;
} S390CcwMachineState;
typedef struct S390CcwMachineClass {
diff --git a/qemu-options.hx b/qemu-options.hx
index 99af8ed..ec9dcba 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -42,7 +42,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" dea-key-wrap=on|off controls support for DEA key wrapping (default=on)\n"
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
" nvdimm=on|off controls NVDIMM support (default=off)\n"
- " enforce-config-section=on|off enforce configuration section migration (default=off)\n",
+ " enforce-config-section=on|off enforce configuration section migration (default=off)\n"
+ " s390-squash-mcss=on|off controls support for squashing into default css (default=off)\n",
QEMU_ARCH_ALL)
STEXI
@item -machine [type=]@var{name}[,prop=@var{value}[,...]]
@@ -81,6 +82,9 @@ controls whether DEA wrapping keys will be created to allow
execution of DEA cryptographic functions. The default is on.
@item nvdimm=on|off
Enables or disables NVDIMM support. The default is off.
+@item s390-squash-mcss=on|off
+Enables or disables squashing subchannels into the default css.
+The default is off.
@end table
ETEXI
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 058ddad..c367891 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -1250,6 +1250,16 @@ static inline void s390_crypto_reset(void)
}
}
+static inline bool s390_get_squash_mcss(void)
+{
+ if (object_property_get_bool(OBJECT(qdev_get_machine()), "s390-squash-mcss",
+ NULL)) {
+ return true;
+ }
+
+ return false;
+}
+
/* machine check interruption code */
/* subclasses */
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 03/13] s390x/css: add s390-squash-mcss machine option
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
We want to support real (i.e. not virtual) channel devices
even for guests that do not support MCSS-E (where guests may
see devices from any channel subsystem image at once). As all
virtio-ccw devices are in css 0xfe (and show up in the default
css 0 for guests not activating MCSS-E), we need an option to
squash both the virtio subchannels and e.g. passed-through
subchannels from their real css (0-3, or 0 for hosts not
activating MCSS-E) into the default css. This will be
exploited in a later patch.
Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/s390x/s390-virtio-ccw.c | 23 +++++++++++++++++++++++
include/hw/s390x/s390-virtio-ccw.h | 1 +
qemu-options.hx | 6 +++++-
target/s390x/cpu.h | 10 ++++++++++
4 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 04bd0eb..bfa5f60 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -274,6 +274,21 @@ bool cpu_model_allowed(void)
return true;
}
+static inline bool machine_get_squash_mcss(Object *obj, Error **errp)
+{
+ S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
+
+ return ms->s390_squash_mcss;
+}
+
+static inline void machine_set_squash_mcss(Object *obj, bool value,
+ Error **errp)
+{
+ S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
+
+ ms->s390_squash_mcss = value;
+}
+
static inline void s390_machine_initfn(Object *obj)
{
object_property_add_bool(obj, "aes-key-wrap",
@@ -291,6 +306,14 @@ static inline void s390_machine_initfn(Object *obj)
"enable/disable DEA key wrapping using the CPACF wrapping key",
NULL);
object_property_set_bool(obj, true, "dea-key-wrap", NULL);
+
+ object_property_add_bool(obj, "s390-squash-mcss",
+ machine_get_squash_mcss,
+ machine_set_squash_mcss, NULL);
+ object_property_set_description(obj, "s390-squash-mcss",
+ "enable/disable squashing subchannels into the default css",
+ NULL);
+ object_property_set_bool(obj, false, "s390-squash-mcss", NULL);
}
static const TypeInfo ccw_machine_info = {
diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h
index 6ecae00..28d98fa 100644
--- a/include/hw/s390x/s390-virtio-ccw.h
+++ b/include/hw/s390x/s390-virtio-ccw.h
@@ -28,6 +28,7 @@ typedef struct S390CcwMachineState {
/*< public >*/
bool aes_key_wrap;
bool dea_key_wrap;
+ bool s390_squash_mcss;
} S390CcwMachineState;
typedef struct S390CcwMachineClass {
diff --git a/qemu-options.hx b/qemu-options.hx
index 99af8ed..ec9dcba 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -42,7 +42,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" dea-key-wrap=on|off controls support for DEA key wrapping (default=on)\n"
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
" nvdimm=on|off controls NVDIMM support (default=off)\n"
- " enforce-config-section=on|off enforce configuration section migration (default=off)\n",
+ " enforce-config-section=on|off enforce configuration section migration (default=off)\n"
+ " s390-squash-mcss=on|off controls support for squashing into default css (default=off)\n",
QEMU_ARCH_ALL)
STEXI
@item -machine [type=]@var{name}[,prop=@var{value}[,...]]
@@ -81,6 +82,9 @@ controls whether DEA wrapping keys will be created to allow
execution of DEA cryptographic functions. The default is on.
@item nvdimm=on|off
Enables or disables NVDIMM support. The default is off.
+@item s390-squash-mcss=on|off
+Enables or disables squashing subchannels into the default css.
+The default is off.
@end table
ETEXI
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 058ddad..c367891 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -1250,6 +1250,16 @@ static inline void s390_crypto_reset(void)
}
}
+static inline bool s390_get_squash_mcss(void)
+{
+ if (object_property_get_bool(OBJECT(qdev_get_machine()), "s390-squash-mcss",
+ NULL)) {
+ return true;
+ }
+
+ return false;
+}
+
/* machine check interruption code */
/* subclasses */
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v5 04/13] s390x/css: realize css_sch_build_schib
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
The S390 virtual css support already has a mechanism to build virtual
Sub-Channel Information Block and provide virtual subchannels to the
guest. However, to pass-through subchannels to a guest, we need to
introduce a new mechanism to build its schib according to the real
device information. Thus we realize a new css_sch_build_schib function
to extract the path_masks, chpids, chpid type from sysfs. To reuse
the existing code, we refactor css_add_virtual_chpid to css_add_chpid.
Reviewed-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/s390x/css.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++-
include/hw/s390x/css.h | 36 ++++++------
2 files changed, 169 insertions(+), 20 deletions(-)
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index c03bb20..748e2ad 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -13,6 +13,7 @@
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "hw/qdev.h"
+#include "qemu/error-report.h"
#include "qemu/bitops.h"
#include "exec/address-spaces.h"
#include "cpu.h"
@@ -1302,7 +1303,8 @@ bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid)
(MAX_SCHID + 1) / sizeof(unsigned long));
}
-static int css_add_virtual_chpid(uint8_t cssid, uint8_t chpid, uint8_t type)
+static int css_add_chpid(uint8_t cssid, uint8_t chpid, uint8_t type,
+ bool is_virt)
{
CssImage *css;
@@ -1316,7 +1318,7 @@ static int css_add_virtual_chpid(uint8_t cssid, uint8_t chpid, uint8_t type)
}
css->chpids[chpid].in_use = 1;
css->chpids[chpid].type = type;
- css->chpids[chpid].is_virtual = 1;
+ css->chpids[chpid].is_virtual = is_virt;
css_generate_chp_crws(cssid, chpid);
@@ -1340,7 +1342,7 @@ void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type)
p->pam = 0x80;
p->chpid[0] = chpid;
if (!css->chpids[chpid].in_use) {
- css_add_virtual_chpid(sch->cssid, chpid, type);
+ css_add_chpid(sch->cssid, chpid, type, true);
}
memset(s, 0, sizeof(SCSW));
@@ -1954,3 +1956,148 @@ SubchDev *css_create_virtual_sch(CssDevId bus_id, Error **errp)
css_subch_assign(sch->cssid, sch->ssid, schid, sch->devno, sch);
return sch;
}
+
+static int css_sch_get_chpids(SubchDev *sch, CssDevId *dev_id)
+{
+ char *fid_path;
+ FILE *fd;
+ uint32_t chpid[8];
+ int i;
+ PMCW *p = &sch->curr_status.pmcw;
+
+ fid_path = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/chpids",
+ dev_id->cssid, dev_id->ssid, dev_id->devid);
+ fd = fopen(fid_path, "r");
+ if (fd == NULL) {
+ error_report("%s: open %s failed", __func__, fid_path);
+ g_free(fid_path);
+ return -EINVAL;
+ }
+
+ if (fscanf(fd, "%x %x %x %x %x %x %x %x",
+ &chpid[0], &chpid[1], &chpid[2], &chpid[3],
+ &chpid[4], &chpid[5], &chpid[6], &chpid[7]) != 8) {
+ fclose(fd);
+ g_free(fid_path);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(p->chpid); i++) {
+ p->chpid[i] = chpid[i];
+ }
+
+ fclose(fd);
+ g_free(fid_path);
+
+ return 0;
+}
+
+static int css_sch_get_path_masks(SubchDev *sch, CssDevId *dev_id)
+{
+ char *fid_path;
+ FILE *fd;
+ uint32_t pim, pam, pom;
+ PMCW *p = &sch->curr_status.pmcw;
+
+ fid_path = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/pimpampom",
+ dev_id->cssid, dev_id->ssid, dev_id->devid);
+ fd = fopen(fid_path, "r");
+ if (fd == NULL) {
+ error_report("%s: open %s failed", __func__, fid_path);
+ g_free(fid_path);
+ return -EINVAL;
+ }
+
+ if (fscanf(fd, "%x %x %x", &pim, &pam, &pom) != 3) {
+ fclose(fd);
+ g_free(fid_path);
+ return -EINVAL;
+ }
+
+ p->pim = pim;
+ p->pam = pam;
+ p->pom = pom;
+ fclose(fd);
+ g_free(fid_path);
+
+ return 0;
+}
+
+static int css_sch_get_chpid_type(uint8_t chpid, uint32_t *type,
+ CssDevId *dev_id)
+{
+ char *fid_path;
+ FILE *fd;
+
+ fid_path = g_strdup_printf("/sys/devices/css%x/chp0.%02x/type",
+ dev_id->cssid, chpid);
+ fd = fopen(fid_path, "r");
+ if (fd == NULL) {
+ error_report("%s: open %s failed", __func__, fid_path);
+ g_free(fid_path);
+ return -EINVAL;
+ }
+
+ if (fscanf(fd, "%x", type) != 1) {
+ fclose(fd);
+ g_free(fid_path);
+ return -EINVAL;
+ }
+
+ fclose(fd);
+ g_free(fid_path);
+
+ return 0;
+}
+
+/*
+ * We currently retrieve the real device information from sysfs to build the
+ * guest subchannel information block without considering the migration feature.
+ * If migrate, it won't be sure to use the real device information directly,
+ * this point will be handled in the future.
+ */
+int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id)
+{
+ CssImage *css = channel_subsys.css[sch->cssid];
+ PMCW *p = &sch->curr_status.pmcw;
+ SCSW *s = &sch->curr_status.scsw;
+ uint32_t type;
+ int i, ret;
+
+ /* We are dealing with I/O subchannels only. */
+ assert(css != NULL);
+ memset(p, 0, sizeof(PMCW));
+ p->flags |= PMCW_FLAGS_MASK_DNV;
+ p->devno = sch->devno;
+
+ /* Grab path mask from sysfs. */
+ ret = css_sch_get_path_masks(sch, dev_id);
+ if (ret) {
+ return ret;
+ }
+
+ /* Grab chpids from sysfs. */
+ ret = css_sch_get_chpids(sch, dev_id);
+ if (ret) {
+ return ret;
+ }
+
+ /* Build chpid type. */
+ for (i = 0; i < ARRAY_SIZE(p->chpid); i++) {
+ if (p->chpid[i] && !css->chpids[p->chpid[i]].in_use) {
+ ret = css_sch_get_chpid_type(p->chpid[i], &type, dev_id);
+ if (ret) {
+ return ret;
+ }
+ css_add_chpid(sch->cssid, p->chpid[i], type, false);
+ }
+ }
+
+ memset(s, 0, sizeof(SCSW));
+ sch->curr_status.mba = 0;
+ for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) {
+ sch->curr_status.mda[i] = 0;
+ }
+
+ return 0;
+}
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index f1f0d7f..868c6c7 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -94,6 +94,24 @@ struct SubchDev {
void *driver_data;
};
+/*
+ * Identify a device within the channel subsystem.
+ * Note that this can be used to identify either the subchannel or
+ * the attached I/O device, as there's always one I/O device per
+ * subchannel.
+ */
+typedef struct CssDevId {
+ uint8_t cssid;
+ uint8_t ssid;
+ uint16_t devid;
+ bool valid;
+} CssDevId;
+
+extern PropertyInfo css_devid_propinfo;
+
+#define DEFINE_PROP_CSS_DEV_ID(_n, _s, _f) \
+ DEFINE_PROP(_n, _s, _f, css_devid_propinfo, CssDevId)
+
typedef struct IndAddr {
hwaddr addr;
uint64_t map;
@@ -115,6 +133,7 @@ bool css_devno_used(uint8_t cssid, uint8_t ssid, uint16_t devno);
void css_subch_assign(uint8_t cssid, uint8_t ssid, uint16_t schid,
uint16_t devno, SubchDev *sch);
void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type);
+int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id);
uint16_t css_build_subchannel_id(SubchDev *sch);
void css_reset(void);
void css_reset_sch(SubchDev *sch);
@@ -162,23 +181,6 @@ int css_do_rsch(SubchDev *sch);
int css_do_rchp(uint8_t cssid, uint8_t chpid);
bool css_present(uint8_t cssid);
#endif
-/*
- * Identify a device within the channel subsystem.
- * Note that this can be used to identify either the subchannel or
- * the attached I/O device, as there's always one I/O device per
- * subchannel.
- */
-typedef struct CssDevId {
- uint8_t cssid;
- uint8_t ssid;
- uint16_t devid;
- bool valid;
-} CssDevId;
-
-extern PropertyInfo css_devid_propinfo;
-
-#define DEFINE_PROP_CSS_DEV_ID(_n, _s, _f) \
- DEFINE_PROP(_n, _s, _f, css_devid_propinfo, CssDevId)
extern PropertyInfo css_devid_ro_propinfo;
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 04/13] s390x/css: realize css_sch_build_schib
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
The S390 virtual css support already has a mechanism to build virtual
Sub-Channel Information Block and provide virtual subchannels to the
guest. However, to pass-through subchannels to a guest, we need to
introduce a new mechanism to build its schib according to the real
device information. Thus we realize a new css_sch_build_schib function
to extract the path_masks, chpids, chpid type from sysfs. To reuse
the existing code, we refactor css_add_virtual_chpid to css_add_chpid.
Reviewed-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/s390x/css.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++-
include/hw/s390x/css.h | 36 ++++++------
2 files changed, 169 insertions(+), 20 deletions(-)
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index c03bb20..748e2ad 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -13,6 +13,7 @@
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "hw/qdev.h"
+#include "qemu/error-report.h"
#include "qemu/bitops.h"
#include "exec/address-spaces.h"
#include "cpu.h"
@@ -1302,7 +1303,8 @@ bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid)
(MAX_SCHID + 1) / sizeof(unsigned long));
}
-static int css_add_virtual_chpid(uint8_t cssid, uint8_t chpid, uint8_t type)
+static int css_add_chpid(uint8_t cssid, uint8_t chpid, uint8_t type,
+ bool is_virt)
{
CssImage *css;
@@ -1316,7 +1318,7 @@ static int css_add_virtual_chpid(uint8_t cssid, uint8_t chpid, uint8_t type)
}
css->chpids[chpid].in_use = 1;
css->chpids[chpid].type = type;
- css->chpids[chpid].is_virtual = 1;
+ css->chpids[chpid].is_virtual = is_virt;
css_generate_chp_crws(cssid, chpid);
@@ -1340,7 +1342,7 @@ void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type)
p->pam = 0x80;
p->chpid[0] = chpid;
if (!css->chpids[chpid].in_use) {
- css_add_virtual_chpid(sch->cssid, chpid, type);
+ css_add_chpid(sch->cssid, chpid, type, true);
}
memset(s, 0, sizeof(SCSW));
@@ -1954,3 +1956,148 @@ SubchDev *css_create_virtual_sch(CssDevId bus_id, Error **errp)
css_subch_assign(sch->cssid, sch->ssid, schid, sch->devno, sch);
return sch;
}
+
+static int css_sch_get_chpids(SubchDev *sch, CssDevId *dev_id)
+{
+ char *fid_path;
+ FILE *fd;
+ uint32_t chpid[8];
+ int i;
+ PMCW *p = &sch->curr_status.pmcw;
+
+ fid_path = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/chpids",
+ dev_id->cssid, dev_id->ssid, dev_id->devid);
+ fd = fopen(fid_path, "r");
+ if (fd == NULL) {
+ error_report("%s: open %s failed", __func__, fid_path);
+ g_free(fid_path);
+ return -EINVAL;
+ }
+
+ if (fscanf(fd, "%x %x %x %x %x %x %x %x",
+ &chpid[0], &chpid[1], &chpid[2], &chpid[3],
+ &chpid[4], &chpid[5], &chpid[6], &chpid[7]) != 8) {
+ fclose(fd);
+ g_free(fid_path);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(p->chpid); i++) {
+ p->chpid[i] = chpid[i];
+ }
+
+ fclose(fd);
+ g_free(fid_path);
+
+ return 0;
+}
+
+static int css_sch_get_path_masks(SubchDev *sch, CssDevId *dev_id)
+{
+ char *fid_path;
+ FILE *fd;
+ uint32_t pim, pam, pom;
+ PMCW *p = &sch->curr_status.pmcw;
+
+ fid_path = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/pimpampom",
+ dev_id->cssid, dev_id->ssid, dev_id->devid);
+ fd = fopen(fid_path, "r");
+ if (fd == NULL) {
+ error_report("%s: open %s failed", __func__, fid_path);
+ g_free(fid_path);
+ return -EINVAL;
+ }
+
+ if (fscanf(fd, "%x %x %x", &pim, &pam, &pom) != 3) {
+ fclose(fd);
+ g_free(fid_path);
+ return -EINVAL;
+ }
+
+ p->pim = pim;
+ p->pam = pam;
+ p->pom = pom;
+ fclose(fd);
+ g_free(fid_path);
+
+ return 0;
+}
+
+static int css_sch_get_chpid_type(uint8_t chpid, uint32_t *type,
+ CssDevId *dev_id)
+{
+ char *fid_path;
+ FILE *fd;
+
+ fid_path = g_strdup_printf("/sys/devices/css%x/chp0.%02x/type",
+ dev_id->cssid, chpid);
+ fd = fopen(fid_path, "r");
+ if (fd == NULL) {
+ error_report("%s: open %s failed", __func__, fid_path);
+ g_free(fid_path);
+ return -EINVAL;
+ }
+
+ if (fscanf(fd, "%x", type) != 1) {
+ fclose(fd);
+ g_free(fid_path);
+ return -EINVAL;
+ }
+
+ fclose(fd);
+ g_free(fid_path);
+
+ return 0;
+}
+
+/*
+ * We currently retrieve the real device information from sysfs to build the
+ * guest subchannel information block without considering the migration feature.
+ * If migrate, it won't be sure to use the real device information directly,
+ * this point will be handled in the future.
+ */
+int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id)
+{
+ CssImage *css = channel_subsys.css[sch->cssid];
+ PMCW *p = &sch->curr_status.pmcw;
+ SCSW *s = &sch->curr_status.scsw;
+ uint32_t type;
+ int i, ret;
+
+ /* We are dealing with I/O subchannels only. */
+ assert(css != NULL);
+ memset(p, 0, sizeof(PMCW));
+ p->flags |= PMCW_FLAGS_MASK_DNV;
+ p->devno = sch->devno;
+
+ /* Grab path mask from sysfs. */
+ ret = css_sch_get_path_masks(sch, dev_id);
+ if (ret) {
+ return ret;
+ }
+
+ /* Grab chpids from sysfs. */
+ ret = css_sch_get_chpids(sch, dev_id);
+ if (ret) {
+ return ret;
+ }
+
+ /* Build chpid type. */
+ for (i = 0; i < ARRAY_SIZE(p->chpid); i++) {
+ if (p->chpid[i] && !css->chpids[p->chpid[i]].in_use) {
+ ret = css_sch_get_chpid_type(p->chpid[i], &type, dev_id);
+ if (ret) {
+ return ret;
+ }
+ css_add_chpid(sch->cssid, p->chpid[i], type, false);
+ }
+ }
+
+ memset(s, 0, sizeof(SCSW));
+ sch->curr_status.mba = 0;
+ for (i = 0; i < ARRAY_SIZE(sch->curr_status.mda); i++) {
+ sch->curr_status.mda[i] = 0;
+ }
+
+ return 0;
+}
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index f1f0d7f..868c6c7 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -94,6 +94,24 @@ struct SubchDev {
void *driver_data;
};
+/*
+ * Identify a device within the channel subsystem.
+ * Note that this can be used to identify either the subchannel or
+ * the attached I/O device, as there's always one I/O device per
+ * subchannel.
+ */
+typedef struct CssDevId {
+ uint8_t cssid;
+ uint8_t ssid;
+ uint16_t devid;
+ bool valid;
+} CssDevId;
+
+extern PropertyInfo css_devid_propinfo;
+
+#define DEFINE_PROP_CSS_DEV_ID(_n, _s, _f) \
+ DEFINE_PROP(_n, _s, _f, css_devid_propinfo, CssDevId)
+
typedef struct IndAddr {
hwaddr addr;
uint64_t map;
@@ -115,6 +133,7 @@ bool css_devno_used(uint8_t cssid, uint8_t ssid, uint16_t devno);
void css_subch_assign(uint8_t cssid, uint8_t ssid, uint16_t schid,
uint16_t devno, SubchDev *sch);
void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type);
+int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id);
uint16_t css_build_subchannel_id(SubchDev *sch);
void css_reset(void);
void css_reset_sch(SubchDev *sch);
@@ -162,23 +181,6 @@ int css_do_rsch(SubchDev *sch);
int css_do_rchp(uint8_t cssid, uint8_t chpid);
bool css_present(uint8_t cssid);
#endif
-/*
- * Identify a device within the channel subsystem.
- * Note that this can be used to identify either the subchannel or
- * the attached I/O device, as there's always one I/O device per
- * subchannel.
- */
-typedef struct CssDevId {
- uint8_t cssid;
- uint8_t ssid;
- uint16_t devid;
- bool valid;
-} CssDevId;
-
-extern PropertyInfo css_devid_propinfo;
-
-#define DEFINE_PROP_CSS_DEV_ID(_n, _s, _f) \
- DEFINE_PROP(_n, _s, _f, css_devid_propinfo, CssDevId)
extern PropertyInfo css_devid_ro_propinfo;
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v5 05/13] s390x/css: realize css_create_sch
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
The S390 virtual css support already has a mechanism to create a
virtual subchannel and provide it to the guest. However, to
pass-through subchannels to a guest, we need to introduce a new
mechanism to create the subchannel according to the real device
information. Thus we reconstruct css_create_virtual_sch to a new
css_create_sch function to handl all these cases and do allocation
and initialization of the subchannel according to the device type
and machine configuration.
Reviewed-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/s390x/css-bridge.c | 2 ++
hw/s390x/css.c | 45 ++++++++++++++++++++++++++++++++++++-------
hw/s390x/s390-virtio-ccw.c | 12 +++++++++---
hw/s390x/virtio-ccw.c | 6 +++++-
include/hw/s390x/css-bridge.h | 1 +
include/hw/s390x/css.h | 25 ++++++++++++++++--------
6 files changed, 72 insertions(+), 19 deletions(-)
diff --git a/hw/s390x/css-bridge.c b/hw/s390x/css-bridge.c
index b54ac01..823747f 100644
--- a/hw/s390x/css-bridge.c
+++ b/hw/s390x/css-bridge.c
@@ -17,6 +17,7 @@
#include "hw/s390x/css.h"
#include "ccw-device.h"
#include "hw/s390x/css-bridge.h"
+#include "cpu.h"
/*
* Invoke device-specific unplug handler, disable the subchannel
@@ -103,6 +104,7 @@ VirtualCssBus *virtual_css_bus_init(void)
/* Create bus on bridge device */
bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
cbus = VIRTUAL_CSS_BUS(bus);
+ cbus->squash_mcss = s390_get_squash_mcss();
/* Enable hotplugging */
qbus_set_hotplug_handler(bus, dev, &error_abort);
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 748e2ad..1052eea 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1924,28 +1924,59 @@ PropertyInfo css_devid_ro_propinfo = {
.get = get_css_devid,
};
-SubchDev *css_create_virtual_sch(CssDevId bus_id, Error **errp)
+SubchDev *css_create_sch(CssDevId bus_id, bool is_virtio, bool squash_mcss,
+ Error **errp)
{
uint16_t schid = 0;
SubchDev *sch;
if (bus_id.valid) {
- /* Enforce use of virtual cssid. */
- if (bus_id.cssid != VIRTUAL_CSSID) {
- error_setg(errp, "cssid %hhx not valid for virtual devices",
- bus_id.cssid);
+ if (is_virtio != (bus_id.cssid == VIRTUAL_CSSID)) {
+ error_setg(errp, "cssid %hhx not valid for %s devices",
+ bus_id.cssid,
+ (is_virtio ? "virtio" : "non-virtio"));
return NULL;
}
+ }
+
+ if (bus_id.valid) {
+ if (squash_mcss) {
+ bus_id.cssid = channel_subsys.default_cssid;
+ } else if (!channel_subsys.css[bus_id.cssid]) {
+ css_create_css_image(bus_id.cssid, false);
+ }
+
if (!css_find_free_subch_for_devno(bus_id.cssid, bus_id.ssid,
bus_id.devid, &schid, errp)) {
return NULL;
}
- } else {
- bus_id.cssid = VIRTUAL_CSSID;
+ } else if (squash_mcss || is_virtio) {
+ bus_id.cssid = channel_subsys.default_cssid;
+
if (!css_find_free_subch_and_devno(bus_id.cssid, &bus_id.ssid,
&bus_id.devid, &schid, errp)) {
return NULL;
}
+ } else {
+ for (bus_id.cssid = 0; bus_id.cssid < MAX_CSSID; ++bus_id.cssid) {
+ if (bus_id.cssid == VIRTUAL_CSSID) {
+ continue;
+ }
+
+ if (!channel_subsys.css[bus_id.cssid]) {
+ css_create_css_image(bus_id.cssid, false);
+ }
+
+ if (css_find_free_subch_and_devno(bus_id.cssid, &bus_id.ssid,
+ &bus_id.devid, &schid,
+ NULL)) {
+ break ;
+ }
+ if (bus_id.cssid == MAX_CSSID) {
+ error_setg(errp, "Virtual channel subsystem is full!");
+ return NULL;
+ }
+ }
}
sch = g_malloc0(sizeof(*sch));
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index bfa5f60..e10b277 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -136,10 +136,16 @@ static void ccw_init(MachineState *machine)
kvm_s390_enable_css_support(s390_cpu_addr2state(0));
}
/*
- * Create virtual css and set it as default so that non mcss-e
- * enabled guests only see virtio devices.
+ * Non mcss-e enabled guests only see the devices from the default
+ * css, which is determined by the value of the squash_mcss property.
+ * Note: we must not squash non virtio devices to css 0xFE, since
+ * it's reserved for virtio devices only.
*/
- ret = css_create_css_image(VIRTUAL_CSSID, true);
+ if (css_bus->squash_mcss) {
+ ret = css_create_css_image(0, true);
+ } else {
+ ret = css_create_css_image(VIRTUAL_CSSID, true);
+ }
assert(ret == 0);
/* Create VirtIO network adapters */
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index f376381..b1ae05a 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -680,9 +680,13 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
CcwDevice *ccw_dev = CCW_DEVICE(dev);
CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
- SubchDev *sch = css_create_virtual_sch(ccw_dev->devno, errp);
+ DeviceState *parent = DEVICE(ccw_dev);
+ BusState *qbus = qdev_get_parent_bus(parent);
+ VirtualCssBus *cbus = VIRTUAL_CSS_BUS(qbus);
+ SubchDev *sch;
Error *err = NULL;
+ sch = css_create_sch(ccw_dev->devno, true, cbus->squash_mcss, errp);
if (!sch) {
return;
}
diff --git a/include/hw/s390x/css-bridge.h b/include/hw/s390x/css-bridge.h
index 5a0203b..cf08604 100644
--- a/include/hw/s390x/css-bridge.h
+++ b/include/hw/s390x/css-bridge.h
@@ -28,6 +28,7 @@ typedef struct VirtualCssBridge {
/* virtual css bus type */
typedef struct VirtualCssBus {
BusState parent_obj;
+ bool squash_mcss;
} VirtualCssBus;
#define TYPE_VIRTUAL_CSS_BUS "virtual-css-bus"
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index 868c6c7..a8bf1db 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -190,16 +190,25 @@ extern PropertyInfo css_devid_ro_propinfo;
/**
* Create a subchannel for the given bus id.
*
- * If @p bus_id is valid, verify that it uses the virtual channel
- * subsystem id and is not already in use, and find a free subchannel
- * id for it. If @p bus_id is not valid, find a free subchannel id and
- * device number across all subchannel sets. If either of the former
- * actions succeed, allocate a subchannel structure, initialise it
- * with the bus id, subchannel id and device number, register it with
- * the CSS and return it. Otherwise return NULL.
+ * If @p bus_id is valid, and @p squash_mcss is true, verify that it is
+ * not already in use in the default css, and find a free devno from the
+ * default css image for it.
+ * If @p bus_id is valid, and @p squash_mcss is false, verify that it is
+ * not already in use, and find a free devno for it.
+ * If @p bus_id is not valid, and if either @p squash_mcss or @p is_virtio
+ * is true, find a free subchannel id and device number across all
+ * subchannel sets from the default css image.
+ * If @p bus_id is not valid, and if both @p squash_mcss and @p is_virtio
+ * are false, find a non-full css image and find a free subchannel id and
+ * device number across all subchannel sets from it.
+ *
+ * If either of the former actions succeed, allocate a subchannel structure,
+ * initialise it with the bus id, subchannel id and device number, register
+ * it with the CSS and return it. Otherwise return NULL.
*
* The caller becomes owner of the returned subchannel structure and
* is responsible for unregistering and freeing it.
*/
-SubchDev *css_create_virtual_sch(CssDevId bus_id, Error **errp);
+SubchDev *css_create_sch(CssDevId bus_id, bool is_virtio, bool squash_mcss,
+ Error **errp);
#endif
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 05/13] s390x/css: realize css_create_sch
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
The S390 virtual css support already has a mechanism to create a
virtual subchannel and provide it to the guest. However, to
pass-through subchannels to a guest, we need to introduce a new
mechanism to create the subchannel according to the real device
information. Thus we reconstruct css_create_virtual_sch to a new
css_create_sch function to handl all these cases and do allocation
and initialization of the subchannel according to the device type
and machine configuration.
Reviewed-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/s390x/css-bridge.c | 2 ++
hw/s390x/css.c | 45 ++++++++++++++++++++++++++++++++++++-------
hw/s390x/s390-virtio-ccw.c | 12 +++++++++---
hw/s390x/virtio-ccw.c | 6 +++++-
include/hw/s390x/css-bridge.h | 1 +
include/hw/s390x/css.h | 25 ++++++++++++++++--------
6 files changed, 72 insertions(+), 19 deletions(-)
diff --git a/hw/s390x/css-bridge.c b/hw/s390x/css-bridge.c
index b54ac01..823747f 100644
--- a/hw/s390x/css-bridge.c
+++ b/hw/s390x/css-bridge.c
@@ -17,6 +17,7 @@
#include "hw/s390x/css.h"
#include "ccw-device.h"
#include "hw/s390x/css-bridge.h"
+#include "cpu.h"
/*
* Invoke device-specific unplug handler, disable the subchannel
@@ -103,6 +104,7 @@ VirtualCssBus *virtual_css_bus_init(void)
/* Create bus on bridge device */
bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
cbus = VIRTUAL_CSS_BUS(bus);
+ cbus->squash_mcss = s390_get_squash_mcss();
/* Enable hotplugging */
qbus_set_hotplug_handler(bus, dev, &error_abort);
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 748e2ad..1052eea 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1924,28 +1924,59 @@ PropertyInfo css_devid_ro_propinfo = {
.get = get_css_devid,
};
-SubchDev *css_create_virtual_sch(CssDevId bus_id, Error **errp)
+SubchDev *css_create_sch(CssDevId bus_id, bool is_virtio, bool squash_mcss,
+ Error **errp)
{
uint16_t schid = 0;
SubchDev *sch;
if (bus_id.valid) {
- /* Enforce use of virtual cssid. */
- if (bus_id.cssid != VIRTUAL_CSSID) {
- error_setg(errp, "cssid %hhx not valid for virtual devices",
- bus_id.cssid);
+ if (is_virtio != (bus_id.cssid == VIRTUAL_CSSID)) {
+ error_setg(errp, "cssid %hhx not valid for %s devices",
+ bus_id.cssid,
+ (is_virtio ? "virtio" : "non-virtio"));
return NULL;
}
+ }
+
+ if (bus_id.valid) {
+ if (squash_mcss) {
+ bus_id.cssid = channel_subsys.default_cssid;
+ } else if (!channel_subsys.css[bus_id.cssid]) {
+ css_create_css_image(bus_id.cssid, false);
+ }
+
if (!css_find_free_subch_for_devno(bus_id.cssid, bus_id.ssid,
bus_id.devid, &schid, errp)) {
return NULL;
}
- } else {
- bus_id.cssid = VIRTUAL_CSSID;
+ } else if (squash_mcss || is_virtio) {
+ bus_id.cssid = channel_subsys.default_cssid;
+
if (!css_find_free_subch_and_devno(bus_id.cssid, &bus_id.ssid,
&bus_id.devid, &schid, errp)) {
return NULL;
}
+ } else {
+ for (bus_id.cssid = 0; bus_id.cssid < MAX_CSSID; ++bus_id.cssid) {
+ if (bus_id.cssid == VIRTUAL_CSSID) {
+ continue;
+ }
+
+ if (!channel_subsys.css[bus_id.cssid]) {
+ css_create_css_image(bus_id.cssid, false);
+ }
+
+ if (css_find_free_subch_and_devno(bus_id.cssid, &bus_id.ssid,
+ &bus_id.devid, &schid,
+ NULL)) {
+ break ;
+ }
+ if (bus_id.cssid == MAX_CSSID) {
+ error_setg(errp, "Virtual channel subsystem is full!");
+ return NULL;
+ }
+ }
}
sch = g_malloc0(sizeof(*sch));
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index bfa5f60..e10b277 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -136,10 +136,16 @@ static void ccw_init(MachineState *machine)
kvm_s390_enable_css_support(s390_cpu_addr2state(0));
}
/*
- * Create virtual css and set it as default so that non mcss-e
- * enabled guests only see virtio devices.
+ * Non mcss-e enabled guests only see the devices from the default
+ * css, which is determined by the value of the squash_mcss property.
+ * Note: we must not squash non virtio devices to css 0xFE, since
+ * it's reserved for virtio devices only.
*/
- ret = css_create_css_image(VIRTUAL_CSSID, true);
+ if (css_bus->squash_mcss) {
+ ret = css_create_css_image(0, true);
+ } else {
+ ret = css_create_css_image(VIRTUAL_CSSID, true);
+ }
assert(ret == 0);
/* Create VirtIO network adapters */
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index f376381..b1ae05a 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -680,9 +680,13 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
CcwDevice *ccw_dev = CCW_DEVICE(dev);
CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
- SubchDev *sch = css_create_virtual_sch(ccw_dev->devno, errp);
+ DeviceState *parent = DEVICE(ccw_dev);
+ BusState *qbus = qdev_get_parent_bus(parent);
+ VirtualCssBus *cbus = VIRTUAL_CSS_BUS(qbus);
+ SubchDev *sch;
Error *err = NULL;
+ sch = css_create_sch(ccw_dev->devno, true, cbus->squash_mcss, errp);
if (!sch) {
return;
}
diff --git a/include/hw/s390x/css-bridge.h b/include/hw/s390x/css-bridge.h
index 5a0203b..cf08604 100644
--- a/include/hw/s390x/css-bridge.h
+++ b/include/hw/s390x/css-bridge.h
@@ -28,6 +28,7 @@ typedef struct VirtualCssBridge {
/* virtual css bus type */
typedef struct VirtualCssBus {
BusState parent_obj;
+ bool squash_mcss;
} VirtualCssBus;
#define TYPE_VIRTUAL_CSS_BUS "virtual-css-bus"
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index 868c6c7..a8bf1db 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -190,16 +190,25 @@ extern PropertyInfo css_devid_ro_propinfo;
/**
* Create a subchannel for the given bus id.
*
- * If @p bus_id is valid, verify that it uses the virtual channel
- * subsystem id and is not already in use, and find a free subchannel
- * id for it. If @p bus_id is not valid, find a free subchannel id and
- * device number across all subchannel sets. If either of the former
- * actions succeed, allocate a subchannel structure, initialise it
- * with the bus id, subchannel id and device number, register it with
- * the CSS and return it. Otherwise return NULL.
+ * If @p bus_id is valid, and @p squash_mcss is true, verify that it is
+ * not already in use in the default css, and find a free devno from the
+ * default css image for it.
+ * If @p bus_id is valid, and @p squash_mcss is false, verify that it is
+ * not already in use, and find a free devno for it.
+ * If @p bus_id is not valid, and if either @p squash_mcss or @p is_virtio
+ * is true, find a free subchannel id and device number across all
+ * subchannel sets from the default css image.
+ * If @p bus_id is not valid, and if both @p squash_mcss and @p is_virtio
+ * are false, find a non-full css image and find a free subchannel id and
+ * device number across all subchannel sets from it.
+ *
+ * If either of the former actions succeed, allocate a subchannel structure,
+ * initialise it with the bus id, subchannel id and device number, register
+ * it with the CSS and return it. Otherwise return NULL.
*
* The caller becomes owner of the returned subchannel structure and
* is responsible for unregistering and freeing it.
*/
-SubchDev *css_create_virtual_sch(CssDevId bus_id, Error **errp);
+SubchDev *css_create_sch(CssDevId bus_id, bool is_virtio, bool squash_mcss,
+ Error **errp);
#endif
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v5 06/13] s390x/css: device support for s390-ccw passthrough
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
In order to support subchannels pass-through, we introduce a s390
subchannel device called "s390-ccw" to hold the real subchannel info.
The s390-ccw devices inherit from the abstract CcwDevice which connect
to the existing virtual-css-bus.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/s390x/Makefile.objs | 1 +
hw/s390x/s390-ccw.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++
hw/s390x/s390-ccw.h | 38 ++++++++++++++
3 files changed, 173 insertions(+)
create mode 100644 hw/s390x/s390-ccw.c
create mode 100644 hw/s390x/s390-ccw.h
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 41ac4ec..72a3d37 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -13,3 +13,4 @@ obj-y += ccw-device.o
obj-y += s390-pci-bus.o s390-pci-inst.o
obj-y += s390-skeys.o
obj-$(CONFIG_KVM) += s390-skeys-kvm.o
+obj-y += s390-ccw.o
diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
new file mode 100644
index 0000000..f3d5ed1
--- /dev/null
+++ b/hw/s390x/s390-ccw.c
@@ -0,0 +1,134 @@
+/*
+ * s390 CCW Assignment Support
+ *
+ * Copyright 2017 IBM Corp
+ * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
+ * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
+ * Pierre Morel <pmorel@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.
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "libgen.h"
+#include "hw/s390x/css.h"
+#include "hw/s390x/css-bridge.h"
+#include "s390-ccw.h"
+
+static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
+ char *sysfsdev,
+ Error **errp)
+{
+ char dev_path[PATH_MAX], *tmp;
+ unsigned int cssid, ssid, devid;
+
+ if (!sysfsdev) {
+ error_setg(errp, "No host device provided");
+ error_append_hint(errp, "Use -vfio-ccw,sysfsdev=PATH_TO_DEVICE\n");
+ return;
+ }
+
+ if (!realpath(sysfsdev, dev_path)) {
+ error_setg(errp, "Host device '%s' not found", sysfsdev);
+ return;
+ }
+
+ cdev->mdevid = g_strdup(basename(dev_path));
+
+ tmp = basename(dirname(dev_path));
+ sscanf(tmp, "%2x.%1x.%4x", &cssid, &ssid, &devid);
+
+ cdev->hostid.cssid = cssid;
+ cdev->hostid.ssid = ssid;
+ cdev->hostid.devid = devid;
+ cdev->hostid.valid = true;
+}
+
+static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
+{
+ CcwDevice *ccw_dev = CCW_DEVICE(cdev);
+ CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
+ DeviceState *parent = DEVICE(ccw_dev);
+ BusState *qbus = qdev_get_parent_bus(parent);
+ VirtualCssBus *cbus = VIRTUAL_CSS_BUS(qbus);
+ SubchDev *sch;
+ int ret;
+ Error *err = NULL;
+
+ s390_ccw_get_dev_info(cdev, sysfsdev, errp);
+ if (*errp) {
+ return;
+ }
+
+ sch = css_create_sch(ccw_dev->devno, false, cbus->squash_mcss, errp);
+ if (!sch) {
+ return;
+ }
+ sch->driver_data = cdev;
+
+ ccw_dev->sch = sch;
+ ret = css_sch_build_schib(sch, &cdev->hostid);
+ if (ret) {
+ error_setg(&err, "%s: Failed to build initial schib: %d",
+ __func__, ret);
+ goto out_err;
+ }
+
+ ck->realize(ccw_dev, &err);
+ if (err) {
+ goto out_err;
+ }
+
+ css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
+ parent->hotplugged, 1);
+ return;
+
+out_err:
+ error_propagate(errp, err);
+ css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
+ ccw_dev->sch = NULL;
+ g_free(sch);
+}
+
+static void s390_ccw_unrealize(S390CCWDevice *cdev, Error **errp)
+{
+ CcwDevice *ccw_dev = CCW_DEVICE(cdev);
+ SubchDev *sch = ccw_dev->sch;
+
+ if (sch) {
+ css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
+ g_free(sch);
+ ccw_dev->sch = NULL;
+ }
+
+ g_free(cdev->mdevid);
+}
+
+static void s390_ccw_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass);
+
+ dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
+ cdc->realize = s390_ccw_realize;
+ cdc->unrealize = s390_ccw_unrealize;
+}
+
+static const TypeInfo s390_ccw_info = {
+ .name = TYPE_S390_CCW,
+ .parent = TYPE_CCW_DEVICE,
+ .instance_size = sizeof(S390CCWDevice),
+ .class_size = sizeof(S390CCWDeviceClass),
+ .class_init = s390_ccw_class_init,
+ .abstract = true,
+};
+
+static void register_s390_ccw_type(void)
+{
+ type_register_static(&s390_ccw_info);
+}
+
+type_init(register_s390_ccw_type)
diff --git a/hw/s390x/s390-ccw.h b/hw/s390x/s390-ccw.h
new file mode 100644
index 0000000..b58d8e9
--- /dev/null
+++ b/hw/s390x/s390-ccw.h
@@ -0,0 +1,38 @@
+/*
+ * s390 CCW Assignment Support
+ *
+ * Copyright 2017 IBM Corp.
+ * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
+ * Xiao Feng Ren <renxiaof@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 HW_S390_CCW_H
+#define HW_S390_CCW_H
+
+#include "hw/s390x/ccw-device.h"
+
+#define TYPE_S390_CCW "s390-ccw"
+#define S390_CCW_DEVICE(obj) \
+ OBJECT_CHECK(S390CCWDevice, (obj), TYPE_S390_CCW)
+#define S390_CCW_DEVICE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(S390CCWDeviceClass, (klass), TYPE_S390_CCW)
+#define S390_CCW_DEVICE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(S390CCWDeviceClass, (obj), TYPE_S390_CCW)
+
+typedef struct S390CCWDevice {
+ CcwDevice parent_obj;
+ CssDevId hostid;
+ char *mdevid;
+} S390CCWDevice;
+
+typedef struct S390CCWDeviceClass {
+ CCWDeviceClass parent_class;
+ void (*realize)(S390CCWDevice *dev, char *sysfsdev, Error **errp);
+ void (*unrealize)(S390CCWDevice *dev, Error **errp);
+} S390CCWDeviceClass;
+
+#endif
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 06/13] s390x/css: device support for s390-ccw passthrough
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
In order to support subchannels pass-through, we introduce a s390
subchannel device called "s390-ccw" to hold the real subchannel info.
The s390-ccw devices inherit from the abstract CcwDevice which connect
to the existing virtual-css-bus.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/s390x/Makefile.objs | 1 +
hw/s390x/s390-ccw.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++
hw/s390x/s390-ccw.h | 38 ++++++++++++++
3 files changed, 173 insertions(+)
create mode 100644 hw/s390x/s390-ccw.c
create mode 100644 hw/s390x/s390-ccw.h
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 41ac4ec..72a3d37 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -13,3 +13,4 @@ obj-y += ccw-device.o
obj-y += s390-pci-bus.o s390-pci-inst.o
obj-y += s390-skeys.o
obj-$(CONFIG_KVM) += s390-skeys-kvm.o
+obj-y += s390-ccw.o
diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
new file mode 100644
index 0000000..f3d5ed1
--- /dev/null
+++ b/hw/s390x/s390-ccw.c
@@ -0,0 +1,134 @@
+/*
+ * s390 CCW Assignment Support
+ *
+ * Copyright 2017 IBM Corp
+ * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
+ * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
+ * Pierre Morel <pmorel@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.
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "libgen.h"
+#include "hw/s390x/css.h"
+#include "hw/s390x/css-bridge.h"
+#include "s390-ccw.h"
+
+static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
+ char *sysfsdev,
+ Error **errp)
+{
+ char dev_path[PATH_MAX], *tmp;
+ unsigned int cssid, ssid, devid;
+
+ if (!sysfsdev) {
+ error_setg(errp, "No host device provided");
+ error_append_hint(errp, "Use -vfio-ccw,sysfsdev=PATH_TO_DEVICE\n");
+ return;
+ }
+
+ if (!realpath(sysfsdev, dev_path)) {
+ error_setg(errp, "Host device '%s' not found", sysfsdev);
+ return;
+ }
+
+ cdev->mdevid = g_strdup(basename(dev_path));
+
+ tmp = basename(dirname(dev_path));
+ sscanf(tmp, "%2x.%1x.%4x", &cssid, &ssid, &devid);
+
+ cdev->hostid.cssid = cssid;
+ cdev->hostid.ssid = ssid;
+ cdev->hostid.devid = devid;
+ cdev->hostid.valid = true;
+}
+
+static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
+{
+ CcwDevice *ccw_dev = CCW_DEVICE(cdev);
+ CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
+ DeviceState *parent = DEVICE(ccw_dev);
+ BusState *qbus = qdev_get_parent_bus(parent);
+ VirtualCssBus *cbus = VIRTUAL_CSS_BUS(qbus);
+ SubchDev *sch;
+ int ret;
+ Error *err = NULL;
+
+ s390_ccw_get_dev_info(cdev, sysfsdev, errp);
+ if (*errp) {
+ return;
+ }
+
+ sch = css_create_sch(ccw_dev->devno, false, cbus->squash_mcss, errp);
+ if (!sch) {
+ return;
+ }
+ sch->driver_data = cdev;
+
+ ccw_dev->sch = sch;
+ ret = css_sch_build_schib(sch, &cdev->hostid);
+ if (ret) {
+ error_setg(&err, "%s: Failed to build initial schib: %d",
+ __func__, ret);
+ goto out_err;
+ }
+
+ ck->realize(ccw_dev, &err);
+ if (err) {
+ goto out_err;
+ }
+
+ css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
+ parent->hotplugged, 1);
+ return;
+
+out_err:
+ error_propagate(errp, err);
+ css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
+ ccw_dev->sch = NULL;
+ g_free(sch);
+}
+
+static void s390_ccw_unrealize(S390CCWDevice *cdev, Error **errp)
+{
+ CcwDevice *ccw_dev = CCW_DEVICE(cdev);
+ SubchDev *sch = ccw_dev->sch;
+
+ if (sch) {
+ css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
+ g_free(sch);
+ ccw_dev->sch = NULL;
+ }
+
+ g_free(cdev->mdevid);
+}
+
+static void s390_ccw_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass);
+
+ dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
+ cdc->realize = s390_ccw_realize;
+ cdc->unrealize = s390_ccw_unrealize;
+}
+
+static const TypeInfo s390_ccw_info = {
+ .name = TYPE_S390_CCW,
+ .parent = TYPE_CCW_DEVICE,
+ .instance_size = sizeof(S390CCWDevice),
+ .class_size = sizeof(S390CCWDeviceClass),
+ .class_init = s390_ccw_class_init,
+ .abstract = true,
+};
+
+static void register_s390_ccw_type(void)
+{
+ type_register_static(&s390_ccw_info);
+}
+
+type_init(register_s390_ccw_type)
diff --git a/hw/s390x/s390-ccw.h b/hw/s390x/s390-ccw.h
new file mode 100644
index 0000000..b58d8e9
--- /dev/null
+++ b/hw/s390x/s390-ccw.h
@@ -0,0 +1,38 @@
+/*
+ * s390 CCW Assignment Support
+ *
+ * Copyright 2017 IBM Corp.
+ * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
+ * Xiao Feng Ren <renxiaof@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 HW_S390_CCW_H
+#define HW_S390_CCW_H
+
+#include "hw/s390x/ccw-device.h"
+
+#define TYPE_S390_CCW "s390-ccw"
+#define S390_CCW_DEVICE(obj) \
+ OBJECT_CHECK(S390CCWDevice, (obj), TYPE_S390_CCW)
+#define S390_CCW_DEVICE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(S390CCWDeviceClass, (klass), TYPE_S390_CCW)
+#define S390_CCW_DEVICE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(S390CCWDeviceClass, (obj), TYPE_S390_CCW)
+
+typedef struct S390CCWDevice {
+ CcwDevice parent_obj;
+ CssDevId hostid;
+ char *mdevid;
+} S390CCWDevice;
+
+typedef struct S390CCWDeviceClass {
+ CCWDeviceClass parent_class;
+ void (*realize)(S390CCWDevice *dev, char *sysfsdev, Error **errp);
+ void (*unrealize)(S390CCWDevice *dev, Error **errp);
+} S390CCWDeviceClass;
+
+#endif
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
We use the IOMMU_TYPE1 of VFIO to realize the subchannels
passthrough, implement a vfio based subchannels passthrough
driver called "vfio-ccw".
Support qemu parameters in the style of:
"-device vfio-ccw,sysfsdev=$mdev_file_path,devno=xx.x.xxxx'
Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
default-configs/s390x-softmmu.mak | 1 +
hw/vfio/Makefile.objs | 1 +
hw/vfio/ccw.c | 207 ++++++++++++++++++++++++++++++++++++++
include/hw/vfio/vfio-common.h | 1 +
4 files changed, 210 insertions(+)
create mode 100644 hw/vfio/ccw.c
diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak
index 36e15de..5576b0a 100644
--- a/default-configs/s390x-softmmu.mak
+++ b/default-configs/s390x-softmmu.mak
@@ -4,4 +4,5 @@ CONFIG_VIRTIO=y
CONFIG_SCLPCONSOLE=y
CONFIG_S390_FLIC=y
CONFIG_S390_FLIC_KVM=$(CONFIG_KVM)
+CONFIG_VFIO_CCW=$(CONFIG_LINUX)
CONFIG_WDT_DIAG288=y
diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs
index 05e7fbb..c3ab909 100644
--- a/hw/vfio/Makefile.objs
+++ b/hw/vfio/Makefile.objs
@@ -1,6 +1,7 @@
ifeq ($(CONFIG_LINUX), y)
obj-$(CONFIG_SOFTMMU) += common.o
obj-$(CONFIG_PCI) += pci.o pci-quirks.o
+obj-$(CONFIG_VFIO_CCW) += ccw.o
obj-$(CONFIG_SOFTMMU) += platform.o
obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o
obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
new file mode 100644
index 0000000..c491bee
--- /dev/null
+++ b/hw/vfio/ccw.c
@@ -0,0 +1,207 @@
+/*
+ * vfio based subchannel assignment support
+ *
+ * Copyright 2017 IBM Corp.
+ * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
+ * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
+ * Pierre Morel <pmorel@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or(at
+ * your option) any version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include <linux/vfio.h>
+#include <sys/ioctl.h>
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "hw/vfio/vfio.h"
+#include "hw/vfio/vfio-common.h"
+#include "hw/s390x/s390-ccw.h"
+#include "hw/s390x/ccw-device.h"
+
+#define TYPE_VFIO_CCW "vfio-ccw"
+typedef struct VFIOCCWDevice {
+ S390CCWDevice cdev;
+ VFIODevice vdev;
+} VFIOCCWDevice;
+
+static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
+{
+ vdev->needs_reset = false;
+}
+
+/*
+ * We don't need vfio_hot_reset_multi and vfio_eoi operationis for
+ * vfio_ccw device now.
+ */
+struct VFIODeviceOps vfio_ccw_ops = {
+ .vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
+};
+
+static void vfio_ccw_reset(DeviceState *dev)
+{
+ CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
+ S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
+ VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+
+ ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
+}
+
+static void vfio_put_device(VFIOCCWDevice *vcdev)
+{
+ g_free(vcdev->vdev.name);
+ vfio_put_base_device(&vcdev->vdev);
+}
+
+static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, char **path,
+ Error **errp)
+{
+ struct stat st;
+ int groupid;
+ GError *gerror = NULL;
+
+ /* Check that host subchannel exists. */
+ path[0] = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x",
+ cdev->hostid.cssid,
+ cdev->hostid.ssid,
+ cdev->hostid.devid);
+ if (stat(path[0], &st) < 0) {
+ error_setg(errp, "vfio: no such host subchannel %s", path[0]);
+ return NULL;
+ }
+
+ /* Check that mediated device exists. */
+ path[1] = g_strdup_printf("%s/%s", path[0], cdev->mdevid);
+ if (stat(path[0], &st) < 0) {
+ error_setg(errp, "vfio: no such mediated device %s", path[1]);
+ return NULL;
+ }
+
+ /* Get the iommu_group patch as the interim variable. */
+ path[2] = g_strconcat(path[1], "/iommu_group", NULL);
+
+ /* Get the link file path of the device iommu_group. */
+ path[3] = g_file_read_link(path[2], &gerror);
+ if (!path[3]) {
+ error_setg(errp, "vfio: error no iommu_group for subchannel");
+ return NULL;
+ }
+
+ /* Get the device groupid. */
+ if (sscanf(basename(path[3]), "%d", &groupid) != 1) {
+ error_setg(errp, "vfio: error reading %s:%m", path[3]);
+ return NULL;
+ }
+
+ return vfio_get_group(groupid, &address_space_memory, errp);
+}
+
+static void vfio_ccw_put_group(VFIOGroup *group, char **path)
+{
+ g_free(path);
+ vfio_put_group(group);
+}
+
+static void vfio_ccw_realize(DeviceState *dev, Error **errp)
+{
+ VFIODevice *vbasedev;
+ VFIOGroup *group;
+ CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
+ S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
+ VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+ S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
+ char *path[4] = {NULL, NULL, NULL, NULL};
+
+ /* Call the class init function for subchannel. */
+ if (cdc->realize) {
+ cdc->realize(cdev, vcdev->vdev.sysfsdev, errp);
+ if (*errp) {
+ return;
+ }
+ }
+
+ group = vfio_ccw_get_group(cdev, path, errp);
+ if (!group) {
+ goto out_group_err;
+ }
+
+ vcdev->vdev.ops = &vfio_ccw_ops;
+ vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
+ vcdev->vdev.name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
+ cdev->hostid.ssid, cdev->hostid.devid);
+ QLIST_FOREACH(vbasedev, &group->device_list, next) {
+ if (strcmp(vbasedev->name, vcdev->vdev.name) == 0) {
+ error_setg(errp, "vfio: subchannel %s has already been attached",
+ basename(path[0]));
+ goto out_device_err;
+ }
+ }
+
+ if (vfio_get_device(group, cdev->mdevid, &vcdev->vdev, errp)) {
+ goto out_device_err;
+ }
+
+ return;
+
+out_device_err:
+ vfio_ccw_put_group(group, path);
+out_group_err:
+ if (cdc->unrealize) {
+ cdc->unrealize(cdev, errp);
+ }
+}
+
+static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
+{
+ CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
+ S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
+ VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+ S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
+ VFIOGroup *group = vcdev->vdev.group;
+
+ if (cdc->unrealize) {
+ cdc->unrealize(cdev, errp);
+ }
+
+ vfio_put_device(vcdev);
+ vfio_put_group(group);
+}
+
+static Property vfio_ccw_properties[] = {
+ DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription vfio_ccw_vmstate = {
+ .name = TYPE_VFIO_CCW,
+ .unmigratable = 1,
+};
+
+static void vfio_ccw_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->props = vfio_ccw_properties;
+ dc->vmsd = &vfio_ccw_vmstate;
+ dc->desc = "VFIO-based subchannel assignment";
+ dc->realize = vfio_ccw_realize;
+ dc->unrealize = vfio_ccw_unrealize;
+ dc->reset = vfio_ccw_reset;
+}
+
+static const TypeInfo vfio_ccw_info = {
+ .name = TYPE_VFIO_CCW,
+ .parent = TYPE_S390_CCW,
+ .instance_size = sizeof(VFIOCCWDevice),
+ .class_init = vfio_ccw_class_init,
+};
+
+static void register_vfio_ccw_type(void)
+{
+ type_register_static(&vfio_ccw_info);
+}
+
+type_init(register_vfio_ccw_type)
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index c582de1..9521013 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -45,6 +45,7 @@
enum {
VFIO_DEVICE_TYPE_PCI = 0,
VFIO_DEVICE_TYPE_PLATFORM = 1,
+ VFIO_DEVICE_TYPE_CCW = 2,
};
typedef struct VFIOMmap {
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
We use the IOMMU_TYPE1 of VFIO to realize the subchannels
passthrough, implement a vfio based subchannels passthrough
driver called "vfio-ccw".
Support qemu parameters in the style of:
"-device vfio-ccw,sysfsdev=$mdev_file_path,devno=xx.x.xxxx'
Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
default-configs/s390x-softmmu.mak | 1 +
hw/vfio/Makefile.objs | 1 +
hw/vfio/ccw.c | 207 ++++++++++++++++++++++++++++++++++++++
include/hw/vfio/vfio-common.h | 1 +
4 files changed, 210 insertions(+)
create mode 100644 hw/vfio/ccw.c
diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak
index 36e15de..5576b0a 100644
--- a/default-configs/s390x-softmmu.mak
+++ b/default-configs/s390x-softmmu.mak
@@ -4,4 +4,5 @@ CONFIG_VIRTIO=y
CONFIG_SCLPCONSOLE=y
CONFIG_S390_FLIC=y
CONFIG_S390_FLIC_KVM=$(CONFIG_KVM)
+CONFIG_VFIO_CCW=$(CONFIG_LINUX)
CONFIG_WDT_DIAG288=y
diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs
index 05e7fbb..c3ab909 100644
--- a/hw/vfio/Makefile.objs
+++ b/hw/vfio/Makefile.objs
@@ -1,6 +1,7 @@
ifeq ($(CONFIG_LINUX), y)
obj-$(CONFIG_SOFTMMU) += common.o
obj-$(CONFIG_PCI) += pci.o pci-quirks.o
+obj-$(CONFIG_VFIO_CCW) += ccw.o
obj-$(CONFIG_SOFTMMU) += platform.o
obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o
obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
new file mode 100644
index 0000000..c491bee
--- /dev/null
+++ b/hw/vfio/ccw.c
@@ -0,0 +1,207 @@
+/*
+ * vfio based subchannel assignment support
+ *
+ * Copyright 2017 IBM Corp.
+ * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
+ * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
+ * Pierre Morel <pmorel@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or(at
+ * your option) any version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include <linux/vfio.h>
+#include <sys/ioctl.h>
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "hw/vfio/vfio.h"
+#include "hw/vfio/vfio-common.h"
+#include "hw/s390x/s390-ccw.h"
+#include "hw/s390x/ccw-device.h"
+
+#define TYPE_VFIO_CCW "vfio-ccw"
+typedef struct VFIOCCWDevice {
+ S390CCWDevice cdev;
+ VFIODevice vdev;
+} VFIOCCWDevice;
+
+static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
+{
+ vdev->needs_reset = false;
+}
+
+/*
+ * We don't need vfio_hot_reset_multi and vfio_eoi operationis for
+ * vfio_ccw device now.
+ */
+struct VFIODeviceOps vfio_ccw_ops = {
+ .vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
+};
+
+static void vfio_ccw_reset(DeviceState *dev)
+{
+ CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
+ S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
+ VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+
+ ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
+}
+
+static void vfio_put_device(VFIOCCWDevice *vcdev)
+{
+ g_free(vcdev->vdev.name);
+ vfio_put_base_device(&vcdev->vdev);
+}
+
+static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, char **path,
+ Error **errp)
+{
+ struct stat st;
+ int groupid;
+ GError *gerror = NULL;
+
+ /* Check that host subchannel exists. */
+ path[0] = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x",
+ cdev->hostid.cssid,
+ cdev->hostid.ssid,
+ cdev->hostid.devid);
+ if (stat(path[0], &st) < 0) {
+ error_setg(errp, "vfio: no such host subchannel %s", path[0]);
+ return NULL;
+ }
+
+ /* Check that mediated device exists. */
+ path[1] = g_strdup_printf("%s/%s", path[0], cdev->mdevid);
+ if (stat(path[0], &st) < 0) {
+ error_setg(errp, "vfio: no such mediated device %s", path[1]);
+ return NULL;
+ }
+
+ /* Get the iommu_group patch as the interim variable. */
+ path[2] = g_strconcat(path[1], "/iommu_group", NULL);
+
+ /* Get the link file path of the device iommu_group. */
+ path[3] = g_file_read_link(path[2], &gerror);
+ if (!path[3]) {
+ error_setg(errp, "vfio: error no iommu_group for subchannel");
+ return NULL;
+ }
+
+ /* Get the device groupid. */
+ if (sscanf(basename(path[3]), "%d", &groupid) != 1) {
+ error_setg(errp, "vfio: error reading %s:%m", path[3]);
+ return NULL;
+ }
+
+ return vfio_get_group(groupid, &address_space_memory, errp);
+}
+
+static void vfio_ccw_put_group(VFIOGroup *group, char **path)
+{
+ g_free(path);
+ vfio_put_group(group);
+}
+
+static void vfio_ccw_realize(DeviceState *dev, Error **errp)
+{
+ VFIODevice *vbasedev;
+ VFIOGroup *group;
+ CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
+ S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
+ VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+ S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
+ char *path[4] = {NULL, NULL, NULL, NULL};
+
+ /* Call the class init function for subchannel. */
+ if (cdc->realize) {
+ cdc->realize(cdev, vcdev->vdev.sysfsdev, errp);
+ if (*errp) {
+ return;
+ }
+ }
+
+ group = vfio_ccw_get_group(cdev, path, errp);
+ if (!group) {
+ goto out_group_err;
+ }
+
+ vcdev->vdev.ops = &vfio_ccw_ops;
+ vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
+ vcdev->vdev.name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
+ cdev->hostid.ssid, cdev->hostid.devid);
+ QLIST_FOREACH(vbasedev, &group->device_list, next) {
+ if (strcmp(vbasedev->name, vcdev->vdev.name) == 0) {
+ error_setg(errp, "vfio: subchannel %s has already been attached",
+ basename(path[0]));
+ goto out_device_err;
+ }
+ }
+
+ if (vfio_get_device(group, cdev->mdevid, &vcdev->vdev, errp)) {
+ goto out_device_err;
+ }
+
+ return;
+
+out_device_err:
+ vfio_ccw_put_group(group, path);
+out_group_err:
+ if (cdc->unrealize) {
+ cdc->unrealize(cdev, errp);
+ }
+}
+
+static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
+{
+ CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
+ S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
+ VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+ S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
+ VFIOGroup *group = vcdev->vdev.group;
+
+ if (cdc->unrealize) {
+ cdc->unrealize(cdev, errp);
+ }
+
+ vfio_put_device(vcdev);
+ vfio_put_group(group);
+}
+
+static Property vfio_ccw_properties[] = {
+ DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription vfio_ccw_vmstate = {
+ .name = TYPE_VFIO_CCW,
+ .unmigratable = 1,
+};
+
+static void vfio_ccw_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->props = vfio_ccw_properties;
+ dc->vmsd = &vfio_ccw_vmstate;
+ dc->desc = "VFIO-based subchannel assignment";
+ dc->realize = vfio_ccw_realize;
+ dc->unrealize = vfio_ccw_unrealize;
+ dc->reset = vfio_ccw_reset;
+}
+
+static const TypeInfo vfio_ccw_info = {
+ .name = TYPE_VFIO_CCW,
+ .parent = TYPE_S390_CCW,
+ .instance_size = sizeof(VFIOCCWDevice),
+ .class_init = vfio_ccw_class_init,
+};
+
+static void register_vfio_ccw_type(void)
+{
+ type_register_static(&vfio_ccw_info);
+}
+
+type_init(register_vfio_ccw_type)
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index c582de1..9521013 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -45,6 +45,7 @@
enum {
VFIO_DEVICE_TYPE_PCI = 0,
VFIO_DEVICE_TYPE_PLATFORM = 1,
+ VFIO_DEVICE_TYPE_CCW = 2,
};
typedef struct VFIOMmap {
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v5 08/13] vfio/ccw: get io region info
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
vfio-ccw provides an MMIO region for I/O operations. We fetch its
information via ioctls here, then we can use it performing I/O
instructions and retrieving I/O results later on.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/vfio/ccw.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index c491bee..20a4d1a 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -12,6 +12,7 @@
*/
#include <linux/vfio.h>
+#include <linux/vfio_ccw.h>
#include <sys/ioctl.h>
#include "qemu/osdep.h"
@@ -26,6 +27,9 @@
typedef struct VFIOCCWDevice {
S390CCWDevice cdev;
VFIODevice vdev;
+ uint64_t io_region_size;
+ uint64_t io_region_offset;
+ struct ccw_io_region *io_region;
} VFIOCCWDevice;
static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
@@ -50,6 +54,46 @@ static void vfio_ccw_reset(DeviceState *dev)
ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
}
+static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
+{
+ VFIODevice *vdev = &vcdev->vdev;
+ struct vfio_region_info *info;
+ int ret;
+
+ /* Sanity check device */
+ if (!(vdev->flags & VFIO_DEVICE_FLAGS_CCW)) {
+ error_setg(errp, "vfio: Um, this isn't a vfio-ccw device");
+ return;
+ }
+
+ if (vdev->num_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) {
+ error_setg(errp, "vfio: Unexpected number of the I/O region %u",
+ vdev->num_regions);
+ return;
+ }
+
+ ret = vfio_get_region_info(vdev, VFIO_CCW_CONFIG_REGION_INDEX, &info);
+ if (ret) {
+ error_setg(errp, "vfio: Error getting config info: %d", ret);
+ return;
+ }
+
+ vcdev->io_region_size = info->size;
+ if (sizeof(*vcdev->io_region) != vcdev->io_region_size) {
+ error_setg(errp, "vfio: Unexpected size of the I/O region");
+ return;
+ }
+ vcdev->io_region_offset = info->offset;
+ vcdev->io_region = g_malloc0(info->size);
+
+ g_free(info);
+}
+
+static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
+{
+ g_free(vcdev->io_region);
+}
+
static void vfio_put_device(VFIOCCWDevice *vcdev)
{
g_free(vcdev->vdev.name);
@@ -144,8 +188,15 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
goto out_device_err;
}
+ vfio_ccw_get_region(vcdev, errp);
+ if (*errp) {
+ goto out_region_err;
+ }
+
return;
+out_region_err:
+ vfio_put_device(vcdev);
out_device_err:
vfio_ccw_put_group(group, path);
out_group_err:
@@ -166,6 +217,7 @@ static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
cdc->unrealize(cdev, errp);
}
+ vfio_ccw_put_region(vcdev);
vfio_put_device(vcdev);
vfio_put_group(group);
}
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 08/13] vfio/ccw: get io region info
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
vfio-ccw provides an MMIO region for I/O operations. We fetch its
information via ioctls here, then we can use it performing I/O
instructions and retrieving I/O results later on.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/vfio/ccw.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index c491bee..20a4d1a 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -12,6 +12,7 @@
*/
#include <linux/vfio.h>
+#include <linux/vfio_ccw.h>
#include <sys/ioctl.h>
#include "qemu/osdep.h"
@@ -26,6 +27,9 @@
typedef struct VFIOCCWDevice {
S390CCWDevice cdev;
VFIODevice vdev;
+ uint64_t io_region_size;
+ uint64_t io_region_offset;
+ struct ccw_io_region *io_region;
} VFIOCCWDevice;
static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
@@ -50,6 +54,46 @@ static void vfio_ccw_reset(DeviceState *dev)
ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
}
+static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
+{
+ VFIODevice *vdev = &vcdev->vdev;
+ struct vfio_region_info *info;
+ int ret;
+
+ /* Sanity check device */
+ if (!(vdev->flags & VFIO_DEVICE_FLAGS_CCW)) {
+ error_setg(errp, "vfio: Um, this isn't a vfio-ccw device");
+ return;
+ }
+
+ if (vdev->num_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) {
+ error_setg(errp, "vfio: Unexpected number of the I/O region %u",
+ vdev->num_regions);
+ return;
+ }
+
+ ret = vfio_get_region_info(vdev, VFIO_CCW_CONFIG_REGION_INDEX, &info);
+ if (ret) {
+ error_setg(errp, "vfio: Error getting config info: %d", ret);
+ return;
+ }
+
+ vcdev->io_region_size = info->size;
+ if (sizeof(*vcdev->io_region) != vcdev->io_region_size) {
+ error_setg(errp, "vfio: Unexpected size of the I/O region");
+ return;
+ }
+ vcdev->io_region_offset = info->offset;
+ vcdev->io_region = g_malloc0(info->size);
+
+ g_free(info);
+}
+
+static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
+{
+ g_free(vcdev->io_region);
+}
+
static void vfio_put_device(VFIOCCWDevice *vcdev)
{
g_free(vcdev->vdev.name);
@@ -144,8 +188,15 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
goto out_device_err;
}
+ vfio_ccw_get_region(vcdev, errp);
+ if (*errp) {
+ goto out_region_err;
+ }
+
return;
+out_region_err:
+ vfio_put_device(vcdev);
out_device_err:
vfio_ccw_put_group(group, path);
out_group_err:
@@ -166,6 +217,7 @@ static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
cdc->unrealize(cdev, errp);
}
+ vfio_ccw_put_region(vcdev);
vfio_put_device(vcdev);
vfio_put_group(group);
}
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v5 09/13] vfio/ccw: get irqs info and set the eventfd fd
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
vfio-ccw resorts to the eventfd mechanism to communicate with userspace.
We fetch the irqs info via the ioctl VFIO_DEVICE_GET_IRQ_INFO,
register a event notifier to get the eventfd fd which is sent
to kernel via the ioctl VFIO_DEVICE_SET_IRQS, then we can implement
read operation once kernel sends the signal.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/vfio/ccw.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+)
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 20a4d1a..5127c87 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -22,6 +22,7 @@
#include "hw/vfio/vfio-common.h"
#include "hw/s390x/s390-ccw.h"
#include "hw/s390x/ccw-device.h"
+#include "qemu/error-report.h"
#define TYPE_VFIO_CCW "vfio-ccw"
typedef struct VFIOCCWDevice {
@@ -30,6 +31,7 @@ typedef struct VFIOCCWDevice {
uint64_t io_region_size;
uint64_t io_region_offset;
struct ccw_io_region *io_region;
+ EventNotifier io_notifier;
} VFIOCCWDevice;
static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
@@ -54,6 +56,98 @@ static void vfio_ccw_reset(DeviceState *dev)
ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
}
+static void vfio_ccw_io_notifier_handler(void *opaque)
+{
+ VFIOCCWDevice *vcdev = opaque;
+
+ if (!event_notifier_test_and_clear(&vcdev->io_notifier)) {
+ return;
+ }
+}
+
+static void vfio_ccw_register_io_notifier(VFIOCCWDevice *vcdev, Error **errp)
+{
+ VFIODevice *vdev = &vcdev->vdev;
+ struct vfio_irq_info *irq_info;
+ struct vfio_irq_set *irq_set;
+ size_t argsz;
+ int32_t *pfd;
+
+ if (vdev->num_irqs < VFIO_CCW_IO_IRQ_INDEX + 1) {
+ error_setg(errp, "vfio: unexpected number of io irqs %u",
+ vdev->num_irqs);
+ return;
+ }
+
+ argsz = sizeof(*irq_set);
+ irq_info = g_malloc0(argsz);
+ irq_info->index = VFIO_CCW_IO_IRQ_INDEX;
+ irq_info->argsz = argsz;
+ if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
+ irq_info) < 0 || irq_info->count < 1) {
+ error_setg(errp, "vfio: Error getting irq info");
+ goto get_error;
+ }
+
+ if (event_notifier_init(&vcdev->io_notifier, 0)) {
+ error_setg(errp, "vfio: Unable to init event notifier for IO");
+ goto get_error;
+ }
+
+ argsz = sizeof(*irq_set) + sizeof(*pfd);
+ irq_set = g_malloc0(argsz);
+ irq_set->argsz = argsz;
+ irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+ VFIO_IRQ_SET_ACTION_TRIGGER;
+ irq_set->index = VFIO_CCW_IO_IRQ_INDEX;
+ irq_set->start = 0;
+ irq_set->count = 1;
+ pfd = (int32_t *) &irq_set->data;
+
+ *pfd = event_notifier_get_fd(&vcdev->io_notifier);
+ qemu_set_fd_handler(*pfd, vfio_ccw_io_notifier_handler, NULL, vcdev);
+ if (ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
+ error_setg(errp, "vfio: Failed to set up io notification");
+ qemu_set_fd_handler(*pfd, NULL, NULL, vcdev);
+ event_notifier_cleanup(&vcdev->io_notifier);
+ goto set_error;
+ }
+
+set_error:
+ g_free(irq_set);
+
+get_error:
+ g_free(irq_info);
+}
+
+static void vfio_ccw_unregister_io_notifier(VFIOCCWDevice *vcdev)
+{
+ struct vfio_irq_set *irq_set;
+ size_t argsz;
+ int32_t *pfd;
+
+ argsz = sizeof(*irq_set) + sizeof(*pfd);
+ irq_set = g_malloc0(argsz);
+ irq_set->argsz = argsz;
+ irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+ VFIO_IRQ_SET_ACTION_TRIGGER;
+ irq_set->index = VFIO_CCW_IO_IRQ_INDEX;
+ irq_set->start = 0;
+ irq_set->count = 1;
+ pfd = (int32_t *) &irq_set->data;
+ *pfd = -1;
+
+ if (ioctl(vcdev->vdev.fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
+ error_report("vfio: Failed to de-assign device io fd");
+ }
+
+ qemu_set_fd_handler(event_notifier_get_fd(&vcdev->io_notifier),
+ NULL, NULL, vcdev);
+ event_notifier_cleanup(&vcdev->io_notifier);
+
+ g_free(irq_set);
+}
+
static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
{
VFIODevice *vdev = &vcdev->vdev;
@@ -193,8 +287,15 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
goto out_region_err;
}
+ vfio_ccw_register_io_notifier(vcdev, errp);
+ if (*errp) {
+ goto out_notifier_err;
+ }
+
return;
+out_notifier_err:
+ vfio_ccw_put_region(vcdev);
out_region_err:
vfio_put_device(vcdev);
out_device_err:
@@ -217,6 +318,7 @@ static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
cdc->unrealize(cdev, errp);
}
+ vfio_ccw_unregister_io_notifier(vcdev);
vfio_ccw_put_region(vcdev);
vfio_put_device(vcdev);
vfio_put_group(group);
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 09/13] vfio/ccw: get irqs info and set the eventfd fd
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
vfio-ccw resorts to the eventfd mechanism to communicate with userspace.
We fetch the irqs info via the ioctl VFIO_DEVICE_GET_IRQ_INFO,
register a event notifier to get the eventfd fd which is sent
to kernel via the ioctl VFIO_DEVICE_SET_IRQS, then we can implement
read operation once kernel sends the signal.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/vfio/ccw.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+)
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 20a4d1a..5127c87 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -22,6 +22,7 @@
#include "hw/vfio/vfio-common.h"
#include "hw/s390x/s390-ccw.h"
#include "hw/s390x/ccw-device.h"
+#include "qemu/error-report.h"
#define TYPE_VFIO_CCW "vfio-ccw"
typedef struct VFIOCCWDevice {
@@ -30,6 +31,7 @@ typedef struct VFIOCCWDevice {
uint64_t io_region_size;
uint64_t io_region_offset;
struct ccw_io_region *io_region;
+ EventNotifier io_notifier;
} VFIOCCWDevice;
static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
@@ -54,6 +56,98 @@ static void vfio_ccw_reset(DeviceState *dev)
ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
}
+static void vfio_ccw_io_notifier_handler(void *opaque)
+{
+ VFIOCCWDevice *vcdev = opaque;
+
+ if (!event_notifier_test_and_clear(&vcdev->io_notifier)) {
+ return;
+ }
+}
+
+static void vfio_ccw_register_io_notifier(VFIOCCWDevice *vcdev, Error **errp)
+{
+ VFIODevice *vdev = &vcdev->vdev;
+ struct vfio_irq_info *irq_info;
+ struct vfio_irq_set *irq_set;
+ size_t argsz;
+ int32_t *pfd;
+
+ if (vdev->num_irqs < VFIO_CCW_IO_IRQ_INDEX + 1) {
+ error_setg(errp, "vfio: unexpected number of io irqs %u",
+ vdev->num_irqs);
+ return;
+ }
+
+ argsz = sizeof(*irq_set);
+ irq_info = g_malloc0(argsz);
+ irq_info->index = VFIO_CCW_IO_IRQ_INDEX;
+ irq_info->argsz = argsz;
+ if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
+ irq_info) < 0 || irq_info->count < 1) {
+ error_setg(errp, "vfio: Error getting irq info");
+ goto get_error;
+ }
+
+ if (event_notifier_init(&vcdev->io_notifier, 0)) {
+ error_setg(errp, "vfio: Unable to init event notifier for IO");
+ goto get_error;
+ }
+
+ argsz = sizeof(*irq_set) + sizeof(*pfd);
+ irq_set = g_malloc0(argsz);
+ irq_set->argsz = argsz;
+ irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+ VFIO_IRQ_SET_ACTION_TRIGGER;
+ irq_set->index = VFIO_CCW_IO_IRQ_INDEX;
+ irq_set->start = 0;
+ irq_set->count = 1;
+ pfd = (int32_t *) &irq_set->data;
+
+ *pfd = event_notifier_get_fd(&vcdev->io_notifier);
+ qemu_set_fd_handler(*pfd, vfio_ccw_io_notifier_handler, NULL, vcdev);
+ if (ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
+ error_setg(errp, "vfio: Failed to set up io notification");
+ qemu_set_fd_handler(*pfd, NULL, NULL, vcdev);
+ event_notifier_cleanup(&vcdev->io_notifier);
+ goto set_error;
+ }
+
+set_error:
+ g_free(irq_set);
+
+get_error:
+ g_free(irq_info);
+}
+
+static void vfio_ccw_unregister_io_notifier(VFIOCCWDevice *vcdev)
+{
+ struct vfio_irq_set *irq_set;
+ size_t argsz;
+ int32_t *pfd;
+
+ argsz = sizeof(*irq_set) + sizeof(*pfd);
+ irq_set = g_malloc0(argsz);
+ irq_set->argsz = argsz;
+ irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+ VFIO_IRQ_SET_ACTION_TRIGGER;
+ irq_set->index = VFIO_CCW_IO_IRQ_INDEX;
+ irq_set->start = 0;
+ irq_set->count = 1;
+ pfd = (int32_t *) &irq_set->data;
+ *pfd = -1;
+
+ if (ioctl(vcdev->vdev.fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
+ error_report("vfio: Failed to de-assign device io fd");
+ }
+
+ qemu_set_fd_handler(event_notifier_get_fd(&vcdev->io_notifier),
+ NULL, NULL, vcdev);
+ event_notifier_cleanup(&vcdev->io_notifier);
+
+ g_free(irq_set);
+}
+
static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
{
VFIODevice *vdev = &vcdev->vdev;
@@ -193,8 +287,15 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
goto out_region_err;
}
+ vfio_ccw_register_io_notifier(vcdev, errp);
+ if (*errp) {
+ goto out_notifier_err;
+ }
+
return;
+out_notifier_err:
+ vfio_ccw_put_region(vcdev);
out_region_err:
vfio_put_device(vcdev);
out_device_err:
@@ -217,6 +318,7 @@ static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
cdc->unrealize(cdev, errp);
}
+ vfio_ccw_unregister_io_notifier(vcdev);
vfio_ccw_put_region(vcdev);
vfio_put_device(vcdev);
vfio_put_group(group);
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v5 10/13] s390x/css: introduce and realize ccw-request callback
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Introduce a new callback on subchannel to handle ccw-request.
Realize the callback in vfio-ccw device. Besides, resort to
the event notifier handler to handling the ccw-request results.
1. Pread the I/O results via MMIO region.
2. Update the scsw info to guest.
3. Inject an I/O interrupt to notify guest the I/O result.
Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/s390x/css.c | 4 +--
hw/s390x/s390-ccw.h | 1 +
hw/vfio/ccw.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/hw/s390x/css.h | 2 ++
4 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 1052eea..507c60f 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -259,7 +259,7 @@ uint16_t css_build_subchannel_id(SubchDev *sch)
return css_do_build_subchannel_id(sch->cssid, sch->ssid);
}
-static void css_inject_io_interrupt(SubchDev *sch)
+void css_inject_io_interrupt(SubchDev *sch)
{
uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 11;
@@ -668,7 +668,7 @@ static void copy_pmcw_to_guest(PMCW *dest, const PMCW *src)
dest->chars = cpu_to_be32(src->chars);
}
-static void copy_scsw_to_guest(SCSW *dest, const SCSW *src)
+void copy_scsw_to_guest(SCSW *dest, const SCSW *src)
{
dest->flags = cpu_to_be16(src->flags);
dest->ctrl = cpu_to_be16(src->ctrl);
diff --git a/hw/s390x/s390-ccw.h b/hw/s390x/s390-ccw.h
index b58d8e9..4e2fa65 100644
--- a/hw/s390x/s390-ccw.h
+++ b/hw/s390x/s390-ccw.h
@@ -27,6 +27,7 @@ typedef struct S390CCWDevice {
CcwDevice parent_obj;
CssDevId hostid;
char *mdevid;
+ int (*handle_request) (ORB *, SCSW *, void *);
} S390CCWDevice;
typedef struct S390CCWDeviceClass {
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 5127c87..ed17d6e 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -47,6 +47,36 @@ struct VFIODeviceOps vfio_ccw_ops = {
.vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
};
+static int vfio_ccw_handle_request(ORB *orb, SCSW *scsw, void *data)
+{
+ S390CCWDevice *cdev = data;
+ VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+ struct ccw_io_region *region = vcdev->io_region;
+ int ret;
+
+ QEMU_BUILD_BUG_ON(sizeof(region->orb_area) != sizeof(ORB));
+ QEMU_BUILD_BUG_ON(sizeof(region->scsw_area) != sizeof(SCSW));
+ QEMU_BUILD_BUG_ON(sizeof(region->irb_area) != sizeof(IRB));
+
+ memset(region, 0, sizeof(*region));
+
+ memcpy(region->orb_area, orb, sizeof(ORB));
+ memcpy(region->scsw_area, scsw, sizeof(SCSW));
+
+again:
+ ret = pwrite(vcdev->vdev.fd, region,
+ vcdev->io_region_size, vcdev->io_region_offset);
+ if (ret != vcdev->io_region_size) {
+ if (errno == EAGAIN) {
+ goto again;
+ }
+ error_report("vfio-ccw: wirte I/O region failed with errno=%d", errno);
+ return -errno;
+ }
+
+ return region->ret_code;
+}
+
static void vfio_ccw_reset(DeviceState *dev)
{
CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
@@ -59,10 +89,52 @@ static void vfio_ccw_reset(DeviceState *dev)
static void vfio_ccw_io_notifier_handler(void *opaque)
{
VFIOCCWDevice *vcdev = opaque;
+ struct ccw_io_region *region = vcdev->io_region;
+ S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
+ CcwDevice *ccw_dev = CCW_DEVICE(cdev);
+ SubchDev *sch = ccw_dev->sch;
+ SCSW *s = &sch->curr_status.scsw;
+ IRB irb;
if (!event_notifier_test_and_clear(&vcdev->io_notifier)) {
return;
}
+
+ if (pread(vcdev->vdev.fd, region,
+ vcdev->io_region_size, vcdev->io_region_offset) == -1) {
+ switch (errno) {
+ case ENODEV:
+ /* Generate a deferred cc 3 condition. */
+ s->flags |= SCSW_FLAGS_MASK_CC;
+ s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
+ goto read_err;
+ case EFAULT:
+ /* memory problem, generate channel data check */
+ s->ctrl &= ~SCSW_ACTL_START_PEND;
+ s->cstat = SCSW_CSTAT_DATA_CHECK;
+ s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
+ SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
+ goto read_err;
+ default:
+ /* error, generate channel program check */
+ s->ctrl &= ~SCSW_ACTL_START_PEND;
+ s->cstat = SCSW_CSTAT_PROG_CHECK;
+ s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
+ SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
+ goto read_err;
+ }
+ }
+
+ memcpy(&irb, region->irb_area, sizeof(IRB));
+
+ /* Update control block via irb. */
+ copy_scsw_to_guest(s, &irb.scsw);
+
+read_err:
+ css_inject_io_interrupt(sch);
}
static void vfio_ccw_register_io_notifier(VFIOCCWDevice *vcdev, Error **errp)
@@ -253,6 +325,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
char *path[4] = {NULL, NULL, NULL, NULL};
+ cdev->handle_request = vfio_ccw_handle_request;
/* Call the class init function for subchannel. */
if (cdc->realize) {
cdc->realize(cdev, vcdev->vdev.sysfsdev, errp);
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index a8bf1db..c8c283a 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -135,6 +135,8 @@ void css_subch_assign(uint8_t cssid, uint8_t ssid, uint16_t schid,
void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type);
int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id);
uint16_t css_build_subchannel_id(SubchDev *sch);
+void copy_scsw_to_guest(SCSW *dest, const SCSW *src);
+void css_inject_io_interrupt(SubchDev *sch);
void css_reset(void);
void css_reset_sch(SubchDev *sch);
void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, uint16_t rsid);
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 10/13] s390x/css: introduce and realize ccw-request callback
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Introduce a new callback on subchannel to handle ccw-request.
Realize the callback in vfio-ccw device. Besides, resort to
the event notifier handler to handling the ccw-request results.
1. Pread the I/O results via MMIO region.
2. Update the scsw info to guest.
3. Inject an I/O interrupt to notify guest the I/O result.
Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/s390x/css.c | 4 +--
hw/s390x/s390-ccw.h | 1 +
hw/vfio/ccw.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/hw/s390x/css.h | 2 ++
4 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 1052eea..507c60f 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -259,7 +259,7 @@ uint16_t css_build_subchannel_id(SubchDev *sch)
return css_do_build_subchannel_id(sch->cssid, sch->ssid);
}
-static void css_inject_io_interrupt(SubchDev *sch)
+void css_inject_io_interrupt(SubchDev *sch)
{
uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 11;
@@ -668,7 +668,7 @@ static void copy_pmcw_to_guest(PMCW *dest, const PMCW *src)
dest->chars = cpu_to_be32(src->chars);
}
-static void copy_scsw_to_guest(SCSW *dest, const SCSW *src)
+void copy_scsw_to_guest(SCSW *dest, const SCSW *src)
{
dest->flags = cpu_to_be16(src->flags);
dest->ctrl = cpu_to_be16(src->ctrl);
diff --git a/hw/s390x/s390-ccw.h b/hw/s390x/s390-ccw.h
index b58d8e9..4e2fa65 100644
--- a/hw/s390x/s390-ccw.h
+++ b/hw/s390x/s390-ccw.h
@@ -27,6 +27,7 @@ typedef struct S390CCWDevice {
CcwDevice parent_obj;
CssDevId hostid;
char *mdevid;
+ int (*handle_request) (ORB *, SCSW *, void *);
} S390CCWDevice;
typedef struct S390CCWDeviceClass {
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 5127c87..ed17d6e 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -47,6 +47,36 @@ struct VFIODeviceOps vfio_ccw_ops = {
.vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
};
+static int vfio_ccw_handle_request(ORB *orb, SCSW *scsw, void *data)
+{
+ S390CCWDevice *cdev = data;
+ VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+ struct ccw_io_region *region = vcdev->io_region;
+ int ret;
+
+ QEMU_BUILD_BUG_ON(sizeof(region->orb_area) != sizeof(ORB));
+ QEMU_BUILD_BUG_ON(sizeof(region->scsw_area) != sizeof(SCSW));
+ QEMU_BUILD_BUG_ON(sizeof(region->irb_area) != sizeof(IRB));
+
+ memset(region, 0, sizeof(*region));
+
+ memcpy(region->orb_area, orb, sizeof(ORB));
+ memcpy(region->scsw_area, scsw, sizeof(SCSW));
+
+again:
+ ret = pwrite(vcdev->vdev.fd, region,
+ vcdev->io_region_size, vcdev->io_region_offset);
+ if (ret != vcdev->io_region_size) {
+ if (errno == EAGAIN) {
+ goto again;
+ }
+ error_report("vfio-ccw: wirte I/O region failed with errno=%d", errno);
+ return -errno;
+ }
+
+ return region->ret_code;
+}
+
static void vfio_ccw_reset(DeviceState *dev)
{
CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
@@ -59,10 +89,52 @@ static void vfio_ccw_reset(DeviceState *dev)
static void vfio_ccw_io_notifier_handler(void *opaque)
{
VFIOCCWDevice *vcdev = opaque;
+ struct ccw_io_region *region = vcdev->io_region;
+ S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
+ CcwDevice *ccw_dev = CCW_DEVICE(cdev);
+ SubchDev *sch = ccw_dev->sch;
+ SCSW *s = &sch->curr_status.scsw;
+ IRB irb;
if (!event_notifier_test_and_clear(&vcdev->io_notifier)) {
return;
}
+
+ if (pread(vcdev->vdev.fd, region,
+ vcdev->io_region_size, vcdev->io_region_offset) == -1) {
+ switch (errno) {
+ case ENODEV:
+ /* Generate a deferred cc 3 condition. */
+ s->flags |= SCSW_FLAGS_MASK_CC;
+ s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
+ goto read_err;
+ case EFAULT:
+ /* memory problem, generate channel data check */
+ s->ctrl &= ~SCSW_ACTL_START_PEND;
+ s->cstat = SCSW_CSTAT_DATA_CHECK;
+ s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
+ SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
+ goto read_err;
+ default:
+ /* error, generate channel program check */
+ s->ctrl &= ~SCSW_ACTL_START_PEND;
+ s->cstat = SCSW_CSTAT_PROG_CHECK;
+ s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
+ s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
+ SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
+ goto read_err;
+ }
+ }
+
+ memcpy(&irb, region->irb_area, sizeof(IRB));
+
+ /* Update control block via irb. */
+ copy_scsw_to_guest(s, &irb.scsw);
+
+read_err:
+ css_inject_io_interrupt(sch);
}
static void vfio_ccw_register_io_notifier(VFIOCCWDevice *vcdev, Error **errp)
@@ -253,6 +325,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
char *path[4] = {NULL, NULL, NULL, NULL};
+ cdev->handle_request = vfio_ccw_handle_request;
/* Call the class init function for subchannel. */
if (cdc->realize) {
cdc->realize(cdev, vcdev->vdev.sysfsdev, errp);
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index a8bf1db..c8c283a 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -135,6 +135,8 @@ void css_subch_assign(uint8_t cssid, uint8_t ssid, uint16_t schid,
void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type);
int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id);
uint16_t css_build_subchannel_id(SubchDev *sch);
+void copy_scsw_to_guest(SCSW *dest, const SCSW *src);
+void css_inject_io_interrupt(SubchDev *sch);
void css_reset(void);
void css_reset_sch(SubchDev *sch);
void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, uint16_t rsid);
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v5 11/13] s390x/css: ccw translation infrastructure
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Implement a basic infrastructure of handling channel I/O instruction
interception for passed through subchannels:
1. Branch the code path of instruction interception handling by
SubChannel type.
2. For a passed-through subchannel, issue the ORB to kernel to do ccw
translation and perform an I/O operation.
3. Assign different condition code based on the I/O result, or
trigger a program check.
Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/s390x/css.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++----
hw/s390x/s390-ccw.c | 12 +++++++
hw/s390x/virtio-ccw.c | 1 +
include/hw/s390x/css.h | 4 +++
target/s390x/ioinst.c | 9 ++++++
5 files changed, 108 insertions(+), 6 deletions(-)
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 507c60f..0979867 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -524,7 +524,7 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
return ret;
}
-static void sch_handle_start_func(SubchDev *sch, ORB *orb)
+static void sch_handle_start_func_virtual(SubchDev *sch, ORB *orb)
{
PMCW *p = &sch->curr_status.pmcw;
@@ -623,13 +623,57 @@ static void sch_handle_start_func(SubchDev *sch, ORB *orb)
}
+static int sch_handle_start_func_passthrough(SubchDev *sch, ORB *orb)
+{
+
+ PMCW *p = &sch->curr_status.pmcw;
+ SCSW *s = &sch->curr_status.scsw;
+ int ret;
+
+ if (!(s->ctrl & SCSW_ACTL_SUSP)) {
+ assert(orb != NULL);
+ p->intparm = orb->intparm;
+ }
+
+ /*
+ * Only support prefetch enable mode.
+ * Only support 64bit addressing idal.
+ */
+ if (!(orb->ctrl0 & ORB_CTRL0_MASK_PFCH) ||
+ !(orb->ctrl0 & ORB_CTRL0_MASK_C64)) {
+ return -EINVAL;
+ }
+
+ ret = s390_ccw_cmd_request(orb, s, sch->driver_data);
+ switch (ret) {
+ /* Currently we don't update control block and just return the cc code. */
+ case 0:
+ break;
+ case -EBUSY:
+ break;
+ case -ENODEV:
+ break;
+ case -EACCES:
+ /* Let's reflect an inaccessible host device by cc 3. */
+ ret = -ENODEV;
+ break;
+ default:
+ /* All other return codes will trigger a program check,
+ * or set cc to 1.
+ */
+ break;
+ };
+
+ return ret;
+}
+
/*
* On real machines, this would run asynchronously to the main vcpus.
* We might want to make some parts of the ssch handling (interpreting
* read/writes) asynchronous later on if we start supporting more than
* our current very simple devices.
*/
-static void do_subchannel_work(SubchDev *sch, ORB *orb)
+int do_subchannel_work_virtual(SubchDev *sch, ORB *orb)
{
SCSW *s = &sch->curr_status.scsw;
@@ -640,12 +684,45 @@ static void do_subchannel_work(SubchDev *sch, ORB *orb)
sch_handle_halt_func(sch);
} else if (s->ctrl & SCSW_FCTL_START_FUNC) {
/* Triggered by both ssch and rsch. */
- sch_handle_start_func(sch, orb);
+ sch_handle_start_func_virtual(sch, orb);
} else {
/* Cannot happen. */
- return;
+ return 0;
}
css_inject_io_interrupt(sch);
+ return 0;
+}
+
+int do_subchannel_work_passthrough(SubchDev *sch, ORB *orb)
+{
+ int ret;
+ SCSW *s = &sch->curr_status.scsw;
+
+ if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
+ /* TODO: Clear handling */
+ sch_handle_clear_func(sch);
+ ret = 0;
+ } else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
+ /* TODO: Halt handling */
+ sch_handle_halt_func(sch);
+ ret = 0;
+ } else if (s->ctrl & SCSW_FCTL_START_FUNC) {
+ ret = sch_handle_start_func_passthrough(sch, orb);
+ } else {
+ /* Cannot happen. */
+ return -ENODEV;
+ }
+
+ return ret;
+}
+
+static int do_subchannel_work(SubchDev *sch, ORB *orb)
+{
+ if (sch->do_subchannel_work) {
+ return sch->do_subchannel_work(sch, orb);
+ } else {
+ return -EINVAL;
+ }
}
static void copy_pmcw_to_guest(PMCW *dest, const PMCW *src)
@@ -964,8 +1041,7 @@ int css_do_ssch(SubchDev *sch, ORB *orb)
s->ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
s->flags &= ~SCSW_FLAGS_MASK_PNO;
- do_subchannel_work(sch, orb);
- ret = 0;
+ ret = do_subchannel_work(sch, orb);
out:
return ret;
diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
index f3d5ed1..4f44778 100644
--- a/hw/s390x/s390-ccw.c
+++ b/hw/s390x/s390-ccw.c
@@ -18,6 +18,17 @@
#include "hw/s390x/css-bridge.h"
#include "s390-ccw.h"
+int s390_ccw_cmd_request(ORB *orb, SCSW *scsw, void *data)
+{
+ S390CCWDevice *cdev = data;
+
+ if (cdev->handle_request) {
+ return cdev->handle_request(orb, scsw, data);
+ } else {
+ return -ENOSYS;
+ }
+}
+
static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
char *sysfsdev,
Error **errp)
@@ -68,6 +79,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
return;
}
sch->driver_data = cdev;
+ sch->do_subchannel_work = do_subchannel_work_passthrough;
ccw_dev->sch = sch;
ret = css_sch_build_schib(sch, &cdev->hostid);
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index b1ae05a..1d4c248 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -701,6 +701,7 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
sch->disable_cb = virtio_sch_disable_cb;
sch->id.reserved = 0xff;
sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
+ sch->do_subchannel_work = do_subchannel_work_virtual;
ccw_dev->sch = sch;
dev->indicators = NULL;
dev->revision = -1;
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index c8c283a..ae687c5 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -90,6 +90,7 @@ struct SubchDev {
/* transport-provided data: */
int (*ccw_cb) (SubchDev *, CCW1);
void (*disable_cb)(SubchDev *);
+ int (*do_subchannel_work) (SubchDev *, ORB *);
SenseId id;
void *driver_data;
};
@@ -146,6 +147,9 @@ 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);
typedef enum {
CSS_IO_ADAPTER_VIRTIO = 0,
diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
index 590bfa4..62a7771 100644
--- a/target/s390x/ioinst.c
+++ b/target/s390x/ioinst.c
@@ -244,6 +244,15 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
case -EBUSY:
cc = 2;
break;
+ case -EFAULT:
+ /*
+ * TODO:
+ * I'm wondering whether there is something better
+ * to do for us here (like setting some device or
+ * subchannel status).
+ */
+ program_interrupt(env, PGM_ADDRESSING, 4);
+ return;
case 0:
cc = 0;
break;
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 11/13] s390x/css: ccw translation infrastructure
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Implement a basic infrastructure of handling channel I/O instruction
interception for passed through subchannels:
1. Branch the code path of instruction interception handling by
SubChannel type.
2. For a passed-through subchannel, issue the ORB to kernel to do ccw
translation and perform an I/O operation.
3. Assign different condition code based on the I/O result, or
trigger a program check.
Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/s390x/css.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++----
hw/s390x/s390-ccw.c | 12 +++++++
hw/s390x/virtio-ccw.c | 1 +
include/hw/s390x/css.h | 4 +++
target/s390x/ioinst.c | 9 ++++++
5 files changed, 108 insertions(+), 6 deletions(-)
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 507c60f..0979867 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -524,7 +524,7 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
return ret;
}
-static void sch_handle_start_func(SubchDev *sch, ORB *orb)
+static void sch_handle_start_func_virtual(SubchDev *sch, ORB *orb)
{
PMCW *p = &sch->curr_status.pmcw;
@@ -623,13 +623,57 @@ static void sch_handle_start_func(SubchDev *sch, ORB *orb)
}
+static int sch_handle_start_func_passthrough(SubchDev *sch, ORB *orb)
+{
+
+ PMCW *p = &sch->curr_status.pmcw;
+ SCSW *s = &sch->curr_status.scsw;
+ int ret;
+
+ if (!(s->ctrl & SCSW_ACTL_SUSP)) {
+ assert(orb != NULL);
+ p->intparm = orb->intparm;
+ }
+
+ /*
+ * Only support prefetch enable mode.
+ * Only support 64bit addressing idal.
+ */
+ if (!(orb->ctrl0 & ORB_CTRL0_MASK_PFCH) ||
+ !(orb->ctrl0 & ORB_CTRL0_MASK_C64)) {
+ return -EINVAL;
+ }
+
+ ret = s390_ccw_cmd_request(orb, s, sch->driver_data);
+ switch (ret) {
+ /* Currently we don't update control block and just return the cc code. */
+ case 0:
+ break;
+ case -EBUSY:
+ break;
+ case -ENODEV:
+ break;
+ case -EACCES:
+ /* Let's reflect an inaccessible host device by cc 3. */
+ ret = -ENODEV;
+ break;
+ default:
+ /* All other return codes will trigger a program check,
+ * or set cc to 1.
+ */
+ break;
+ };
+
+ return ret;
+}
+
/*
* On real machines, this would run asynchronously to the main vcpus.
* We might want to make some parts of the ssch handling (interpreting
* read/writes) asynchronous later on if we start supporting more than
* our current very simple devices.
*/
-static void do_subchannel_work(SubchDev *sch, ORB *orb)
+int do_subchannel_work_virtual(SubchDev *sch, ORB *orb)
{
SCSW *s = &sch->curr_status.scsw;
@@ -640,12 +684,45 @@ static void do_subchannel_work(SubchDev *sch, ORB *orb)
sch_handle_halt_func(sch);
} else if (s->ctrl & SCSW_FCTL_START_FUNC) {
/* Triggered by both ssch and rsch. */
- sch_handle_start_func(sch, orb);
+ sch_handle_start_func_virtual(sch, orb);
} else {
/* Cannot happen. */
- return;
+ return 0;
}
css_inject_io_interrupt(sch);
+ return 0;
+}
+
+int do_subchannel_work_passthrough(SubchDev *sch, ORB *orb)
+{
+ int ret;
+ SCSW *s = &sch->curr_status.scsw;
+
+ if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
+ /* TODO: Clear handling */
+ sch_handle_clear_func(sch);
+ ret = 0;
+ } else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
+ /* TODO: Halt handling */
+ sch_handle_halt_func(sch);
+ ret = 0;
+ } else if (s->ctrl & SCSW_FCTL_START_FUNC) {
+ ret = sch_handle_start_func_passthrough(sch, orb);
+ } else {
+ /* Cannot happen. */
+ return -ENODEV;
+ }
+
+ return ret;
+}
+
+static int do_subchannel_work(SubchDev *sch, ORB *orb)
+{
+ if (sch->do_subchannel_work) {
+ return sch->do_subchannel_work(sch, orb);
+ } else {
+ return -EINVAL;
+ }
}
static void copy_pmcw_to_guest(PMCW *dest, const PMCW *src)
@@ -964,8 +1041,7 @@ int css_do_ssch(SubchDev *sch, ORB *orb)
s->ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
s->flags &= ~SCSW_FLAGS_MASK_PNO;
- do_subchannel_work(sch, orb);
- ret = 0;
+ ret = do_subchannel_work(sch, orb);
out:
return ret;
diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
index f3d5ed1..4f44778 100644
--- a/hw/s390x/s390-ccw.c
+++ b/hw/s390x/s390-ccw.c
@@ -18,6 +18,17 @@
#include "hw/s390x/css-bridge.h"
#include "s390-ccw.h"
+int s390_ccw_cmd_request(ORB *orb, SCSW *scsw, void *data)
+{
+ S390CCWDevice *cdev = data;
+
+ if (cdev->handle_request) {
+ return cdev->handle_request(orb, scsw, data);
+ } else {
+ return -ENOSYS;
+ }
+}
+
static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
char *sysfsdev,
Error **errp)
@@ -68,6 +79,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
return;
}
sch->driver_data = cdev;
+ sch->do_subchannel_work = do_subchannel_work_passthrough;
ccw_dev->sch = sch;
ret = css_sch_build_schib(sch, &cdev->hostid);
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index b1ae05a..1d4c248 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -701,6 +701,7 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
sch->disable_cb = virtio_sch_disable_cb;
sch->id.reserved = 0xff;
sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
+ sch->do_subchannel_work = do_subchannel_work_virtual;
ccw_dev->sch = sch;
dev->indicators = NULL;
dev->revision = -1;
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index c8c283a..ae687c5 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -90,6 +90,7 @@ struct SubchDev {
/* transport-provided data: */
int (*ccw_cb) (SubchDev *, CCW1);
void (*disable_cb)(SubchDev *);
+ int (*do_subchannel_work) (SubchDev *, ORB *);
SenseId id;
void *driver_data;
};
@@ -146,6 +147,9 @@ 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);
typedef enum {
CSS_IO_ADAPTER_VIRTIO = 0,
diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
index 590bfa4..62a7771 100644
--- a/target/s390x/ioinst.c
+++ b/target/s390x/ioinst.c
@@ -244,6 +244,15 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
case -EBUSY:
cc = 2;
break;
+ case -EFAULT:
+ /*
+ * TODO:
+ * I'm wondering whether there is something better
+ * to do for us here (like setting some device or
+ * subchannel status).
+ */
+ program_interrupt(env, PGM_ADDRESSING, 4);
+ return;
case 0:
cc = 0;
break;
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v5 12/13] vfio/ccw: update sense data if a unit check is pending
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
Concurrent-sense data is currently not delivered. This patch stores
the concurrent-sense data to the subchannel if a unit check is pending
and the concurrent-sense bit is enabled. Then a TSCH can retreive the
right IRB data back to the guest.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/vfio/ccw.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index ed17d6e..fd174c1 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -94,6 +94,7 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
CcwDevice *ccw_dev = CCW_DEVICE(cdev);
SubchDev *sch = ccw_dev->sch;
SCSW *s = &sch->curr_status.scsw;
+ PMCW *p = &sch->curr_status.pmcw;
IRB irb;
if (!event_notifier_test_and_clear(&vcdev->io_notifier)) {
@@ -133,6 +134,12 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
/* Update control block via irb. */
copy_scsw_to_guest(s, &irb.scsw);
+ /* If a uint check is pending, copy sense data. */
+ if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) &&
+ (p->chars & PMCW_CHARS_MASK_CSENSE)) {
+ memcpy(sch->sense_data, irb.ecw, sizeof(irb.ecw));
+ }
+
read_err:
css_inject_io_interrupt(sch);
}
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 12/13] vfio/ccw: update sense data if a unit check is pending
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
Concurrent-sense data is currently not delivered. This patch stores
the concurrent-sense data to the subchannel if a unit check is pending
and the concurrent-sense bit is enabled. Then a TSCH can retreive the
right IRB data back to the guest.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
hw/vfio/ccw.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index ed17d6e..fd174c1 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -94,6 +94,7 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
CcwDevice *ccw_dev = CCW_DEVICE(cdev);
SubchDev *sch = ccw_dev->sch;
SCSW *s = &sch->curr_status.scsw;
+ PMCW *p = &sch->curr_status.pmcw;
IRB irb;
if (!event_notifier_test_and_clear(&vcdev->io_notifier)) {
@@ -133,6 +134,12 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
/* Update control block via irb. */
copy_scsw_to_guest(s, &irb.scsw);
+ /* If a uint check is pending, copy sense data. */
+ if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) &&
+ (p->chars & PMCW_CHARS_MASK_CSENSE)) {
+ memcpy(sch->sense_data, irb.ecw, sizeof(irb.ecw));
+ }
+
read_err:
css_inject_io_interrupt(sch);
}
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH v5 13/13] MAINTAINERS: Add vfio-ccw maintainer
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-12 5:21 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
Add Cornelia Huck as the vfio-ccw maintainer.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
MAINTAINERS | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index c60235e..5bac5f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -999,6 +999,11 @@ S: Supported
F: hw/vfio/*
F: include/hw/vfio/
+vfio-ccw
+M: Cornelia Huck <cornelia.huck@de.ibm.com>
+S: Supported
+F: hw/vfio/ccw.c
+
vhost
M: Michael S. Tsirkin <mst@redhat.com>
S: Supported
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [Qemu-devel] [PATCH v5 13/13] MAINTAINERS: Add vfio-ccw maintainer
@ 2017-04-12 5:21 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-12 5:21 UTC (permalink / raw)
To: kvm, linux-s390, qemu-devel
Cc: bjsdjshi, renxiaof, cornelia.huck, borntraeger, agraf, alex.williamson
Add Cornelia Huck as the vfio-ccw maintainer.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
---
MAINTAINERS | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index c60235e..5bac5f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -999,6 +999,11 @@ S: Supported
F: hw/vfio/*
F: include/hw/vfio/
+vfio-ccw
+M: Cornelia Huck <cornelia.huck@de.ibm.com>
+S: Supported
+F: hw/vfio/ccw.c
+
vhost
M: Michael S. Tsirkin <mst@redhat.com>
S: Supported
--
2.10.2
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-24 22:43 ` Alex Williamson
-1 siblings, 0 replies; 40+ messages in thread
From: Alex Williamson @ 2017-04-24 22:43 UTC (permalink / raw)
To: Dong Jia Shi
Cc: kvm, linux-s390, qemu-devel, renxiaof, cornelia.huck, borntraeger, agraf
On Wed, 12 Apr 2017 07:21:09 +0200
Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> wrote:
> From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
>
> We use the IOMMU_TYPE1 of VFIO to realize the subchannels
> passthrough, implement a vfio based subchannels passthrough
> driver called "vfio-ccw".
>
> Support qemu parameters in the style of:
> "-device vfio-ccw,sysfsdev=$mdev_file_path,devno=xx.x.xxxx'
>
> Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> ---
> default-configs/s390x-softmmu.mak | 1 +
> hw/vfio/Makefile.objs | 1 +
> hw/vfio/ccw.c | 207 ++++++++++++++++++++++++++++++++++++++
> include/hw/vfio/vfio-common.h | 1 +
> 4 files changed, 210 insertions(+)
> create mode 100644 hw/vfio/ccw.c
>
> diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak
> index 36e15de..5576b0a 100644
> --- a/default-configs/s390x-softmmu.mak
> +++ b/default-configs/s390x-softmmu.mak
> @@ -4,4 +4,5 @@ CONFIG_VIRTIO=y
> CONFIG_SCLPCONSOLE=y
> CONFIG_S390_FLIC=y
> CONFIG_S390_FLIC_KVM=$(CONFIG_KVM)
> +CONFIG_VFIO_CCW=$(CONFIG_LINUX)
> CONFIG_WDT_DIAG288=y
> diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs
> index 05e7fbb..c3ab909 100644
> --- a/hw/vfio/Makefile.objs
> +++ b/hw/vfio/Makefile.objs
> @@ -1,6 +1,7 @@
> ifeq ($(CONFIG_LINUX), y)
> obj-$(CONFIG_SOFTMMU) += common.o
> obj-$(CONFIG_PCI) += pci.o pci-quirks.o
> +obj-$(CONFIG_VFIO_CCW) += ccw.o
> obj-$(CONFIG_SOFTMMU) += platform.o
> obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o
> obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o
> diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
> new file mode 100644
> index 0000000..c491bee
> --- /dev/null
> +++ b/hw/vfio/ccw.c
> @@ -0,0 +1,207 @@
> +/*
> + * vfio based subchannel assignment support
> + *
> + * Copyright 2017 IBM Corp.
> + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> + * Pierre Morel <pmorel@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or(at
> + * your option) any version. See the COPYING file in the top-level
> + * directory.
> + */
> +
> +#include <linux/vfio.h>
> +#include <sys/ioctl.h>
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "hw/sysbus.h"
> +#include "hw/vfio/vfio.h"
> +#include "hw/vfio/vfio-common.h"
> +#include "hw/s390x/s390-ccw.h"
> +#include "hw/s390x/ccw-device.h"
> +
> +#define TYPE_VFIO_CCW "vfio-ccw"
> +typedef struct VFIOCCWDevice {
> + S390CCWDevice cdev;
> + VFIODevice vdev;
> +} VFIOCCWDevice;
> +
> +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
> +{
> + vdev->needs_reset = false;
> +}
> +
> +/*
> + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for
> + * vfio_ccw device now.
> + */
> +struct VFIODeviceOps vfio_ccw_ops = {
> + .vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
> +};
> +
> +static void vfio_ccw_reset(DeviceState *dev)
> +{
> + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> +
> + ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
> +}
> +
> +static void vfio_put_device(VFIOCCWDevice *vcdev)
> +{
> + g_free(vcdev->vdev.name);
> + vfio_put_base_device(&vcdev->vdev);
> +}
> +
> +static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, char **path,
> + Error **errp)
> +{
> + struct stat st;
> + int groupid;
> + GError *gerror = NULL;
> +
> + /* Check that host subchannel exists. */
> + path[0] = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x",
> + cdev->hostid.cssid,
> + cdev->hostid.ssid,
> + cdev->hostid.devid);
> + if (stat(path[0], &st) < 0) {
> + error_setg(errp, "vfio: no such host subchannel %s", path[0]);
> + return NULL;
> + }
> +
> + /* Check that mediated device exists. */
> + path[1] = g_strdup_printf("%s/%s", path[0], cdev->mdevid);
> + if (stat(path[0], &st) < 0) {
> + error_setg(errp, "vfio: no such mediated device %s", path[1]);
> + return NULL;
> + }
Isn't this all a bit circular since we build the S390CCWDevice based on
the sysfsdev mdev path?
> +
> + /* Get the iommu_group patch as the interim variable. */
> + path[2] = g_strconcat(path[1], "/iommu_group", NULL);
> +
> + /* Get the link file path of the device iommu_group. */
> + path[3] = g_file_read_link(path[2], &gerror);
> + if (!path[3]) {
> + error_setg(errp, "vfio: error no iommu_group for subchannel");
> + return NULL;
> + }
> +
> + /* Get the device groupid. */
> + if (sscanf(basename(path[3]), "%d", &groupid) != 1) {
> + error_setg(errp, "vfio: error reading %s:%m", path[3]);
> + return NULL;
> + }
> +
> + return vfio_get_group(groupid, &address_space_memory, errp);
> +}
> +
> +static void vfio_ccw_put_group(VFIOGroup *group, char **path)
> +{
> + g_free(path);
> + vfio_put_group(group);
> +}
> +
> +static void vfio_ccw_realize(DeviceState *dev, Error **errp)
> +{
> + VFIODevice *vbasedev;
> + VFIOGroup *group;
> + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
> + char *path[4] = {NULL, NULL, NULL, NULL};
I don't understand what's happening with 'path' throughout this
function. vfio_ccw_get_group() allocates strings into this array, we
only seem to use one in an error path below, it's only freed on an error
path and I don't see it getting linked to the VFIOCCWDevice, so it
seems to be leaked, and even the g_free() above looks quite a bit
suspicious.
> +
> + /* Call the class init function for subchannel. */
> + if (cdc->realize) {
> + cdc->realize(cdev, vcdev->vdev.sysfsdev, errp);
> + if (*errp) {
> + return;
> + }
> + }
> +
> + group = vfio_ccw_get_group(cdev, path, errp);
> + if (!group) {
> + goto out_group_err;
> + }
> +
> + vcdev->vdev.ops = &vfio_ccw_ops;
> + vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
> + vcdev->vdev.name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
> + cdev->hostid.ssid, cdev->hostid.devid);
> + QLIST_FOREACH(vbasedev, &group->device_list, next) {
> + if (strcmp(vbasedev->name, vcdev->vdev.name) == 0) {
> + error_setg(errp, "vfio: subchannel %s has already been attached",
> + basename(path[0]));
> + goto out_device_err;
> + }
> + }
> +
> + if (vfio_get_device(group, cdev->mdevid, &vcdev->vdev, errp)) {
> + goto out_device_err;
> + }
> +
> + return;
> +
> +out_device_err:
> + vfio_ccw_put_group(group, path);
> +out_group_err:
> + if (cdc->unrealize) {
> + cdc->unrealize(cdev, errp);
> + }
> +}
> +
> +static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
> +{
> + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
> + VFIOGroup *group = vcdev->vdev.group;
> +
> + if (cdc->unrealize) {
> + cdc->unrealize(cdev, errp);
> + }
> +
> + vfio_put_device(vcdev);
> + vfio_put_group(group);
> +}
Doesn't seem to matter here, but I would have expected the
cdc->unrealize to occur at the end to unwind the order of the realize
function.
> +
> +static Property vfio_ccw_properties[] = {
> + DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev),
> + DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static const VMStateDescription vfio_ccw_vmstate = {
> + .name = TYPE_VFIO_CCW,
> + .unmigratable = 1,
> +};
> +
> +static void vfio_ccw_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> +
> + dc->props = vfio_ccw_properties;
> + dc->vmsd = &vfio_ccw_vmstate;
> + dc->desc = "VFIO-based subchannel assignment";
> + dc->realize = vfio_ccw_realize;
> + dc->unrealize = vfio_ccw_unrealize;
> + dc->reset = vfio_ccw_reset;
> +}
> +
> +static const TypeInfo vfio_ccw_info = {
> + .name = TYPE_VFIO_CCW,
> + .parent = TYPE_S390_CCW,
> + .instance_size = sizeof(VFIOCCWDevice),
> + .class_init = vfio_ccw_class_init,
> +};
> +
> +static void register_vfio_ccw_type(void)
> +{
> + type_register_static(&vfio_ccw_info);
> +}
> +
> +type_init(register_vfio_ccw_type)
> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
> index c582de1..9521013 100644
> --- a/include/hw/vfio/vfio-common.h
> +++ b/include/hw/vfio/vfio-common.h
> @@ -45,6 +45,7 @@
> enum {
> VFIO_DEVICE_TYPE_PCI = 0,
> VFIO_DEVICE_TYPE_PLATFORM = 1,
> + VFIO_DEVICE_TYPE_CCW = 2,
> };
>
> typedef struct VFIOMmap {
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
@ 2017-04-24 22:43 ` Alex Williamson
0 siblings, 0 replies; 40+ messages in thread
From: Alex Williamson @ 2017-04-24 22:43 UTC (permalink / raw)
To: Dong Jia Shi
Cc: kvm, linux-s390, qemu-devel, renxiaof, cornelia.huck, borntraeger, agraf
On Wed, 12 Apr 2017 07:21:09 +0200
Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> wrote:
> From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
>
> We use the IOMMU_TYPE1 of VFIO to realize the subchannels
> passthrough, implement a vfio based subchannels passthrough
> driver called "vfio-ccw".
>
> Support qemu parameters in the style of:
> "-device vfio-ccw,sysfsdev=$mdev_file_path,devno=xx.x.xxxx'
>
> Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> ---
> default-configs/s390x-softmmu.mak | 1 +
> hw/vfio/Makefile.objs | 1 +
> hw/vfio/ccw.c | 207 ++++++++++++++++++++++++++++++++++++++
> include/hw/vfio/vfio-common.h | 1 +
> 4 files changed, 210 insertions(+)
> create mode 100644 hw/vfio/ccw.c
>
> diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak
> index 36e15de..5576b0a 100644
> --- a/default-configs/s390x-softmmu.mak
> +++ b/default-configs/s390x-softmmu.mak
> @@ -4,4 +4,5 @@ CONFIG_VIRTIO=y
> CONFIG_SCLPCONSOLE=y
> CONFIG_S390_FLIC=y
> CONFIG_S390_FLIC_KVM=$(CONFIG_KVM)
> +CONFIG_VFIO_CCW=$(CONFIG_LINUX)
> CONFIG_WDT_DIAG288=y
> diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs
> index 05e7fbb..c3ab909 100644
> --- a/hw/vfio/Makefile.objs
> +++ b/hw/vfio/Makefile.objs
> @@ -1,6 +1,7 @@
> ifeq ($(CONFIG_LINUX), y)
> obj-$(CONFIG_SOFTMMU) += common.o
> obj-$(CONFIG_PCI) += pci.o pci-quirks.o
> +obj-$(CONFIG_VFIO_CCW) += ccw.o
> obj-$(CONFIG_SOFTMMU) += platform.o
> obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o
> obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o
> diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
> new file mode 100644
> index 0000000..c491bee
> --- /dev/null
> +++ b/hw/vfio/ccw.c
> @@ -0,0 +1,207 @@
> +/*
> + * vfio based subchannel assignment support
> + *
> + * Copyright 2017 IBM Corp.
> + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> + * Pierre Morel <pmorel@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or(at
> + * your option) any version. See the COPYING file in the top-level
> + * directory.
> + */
> +
> +#include <linux/vfio.h>
> +#include <sys/ioctl.h>
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "hw/sysbus.h"
> +#include "hw/vfio/vfio.h"
> +#include "hw/vfio/vfio-common.h"
> +#include "hw/s390x/s390-ccw.h"
> +#include "hw/s390x/ccw-device.h"
> +
> +#define TYPE_VFIO_CCW "vfio-ccw"
> +typedef struct VFIOCCWDevice {
> + S390CCWDevice cdev;
> + VFIODevice vdev;
> +} VFIOCCWDevice;
> +
> +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
> +{
> + vdev->needs_reset = false;
> +}
> +
> +/*
> + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for
> + * vfio_ccw device now.
> + */
> +struct VFIODeviceOps vfio_ccw_ops = {
> + .vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
> +};
> +
> +static void vfio_ccw_reset(DeviceState *dev)
> +{
> + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> +
> + ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
> +}
> +
> +static void vfio_put_device(VFIOCCWDevice *vcdev)
> +{
> + g_free(vcdev->vdev.name);
> + vfio_put_base_device(&vcdev->vdev);
> +}
> +
> +static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, char **path,
> + Error **errp)
> +{
> + struct stat st;
> + int groupid;
> + GError *gerror = NULL;
> +
> + /* Check that host subchannel exists. */
> + path[0] = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x",
> + cdev->hostid.cssid,
> + cdev->hostid.ssid,
> + cdev->hostid.devid);
> + if (stat(path[0], &st) < 0) {
> + error_setg(errp, "vfio: no such host subchannel %s", path[0]);
> + return NULL;
> + }
> +
> + /* Check that mediated device exists. */
> + path[1] = g_strdup_printf("%s/%s", path[0], cdev->mdevid);
> + if (stat(path[0], &st) < 0) {
> + error_setg(errp, "vfio: no such mediated device %s", path[1]);
> + return NULL;
> + }
Isn't this all a bit circular since we build the S390CCWDevice based on
the sysfsdev mdev path?
> +
> + /* Get the iommu_group patch as the interim variable. */
> + path[2] = g_strconcat(path[1], "/iommu_group", NULL);
> +
> + /* Get the link file path of the device iommu_group. */
> + path[3] = g_file_read_link(path[2], &gerror);
> + if (!path[3]) {
> + error_setg(errp, "vfio: error no iommu_group for subchannel");
> + return NULL;
> + }
> +
> + /* Get the device groupid. */
> + if (sscanf(basename(path[3]), "%d", &groupid) != 1) {
> + error_setg(errp, "vfio: error reading %s:%m", path[3]);
> + return NULL;
> + }
> +
> + return vfio_get_group(groupid, &address_space_memory, errp);
> +}
> +
> +static void vfio_ccw_put_group(VFIOGroup *group, char **path)
> +{
> + g_free(path);
> + vfio_put_group(group);
> +}
> +
> +static void vfio_ccw_realize(DeviceState *dev, Error **errp)
> +{
> + VFIODevice *vbasedev;
> + VFIOGroup *group;
> + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
> + char *path[4] = {NULL, NULL, NULL, NULL};
I don't understand what's happening with 'path' throughout this
function. vfio_ccw_get_group() allocates strings into this array, we
only seem to use one in an error path below, it's only freed on an error
path and I don't see it getting linked to the VFIOCCWDevice, so it
seems to be leaked, and even the g_free() above looks quite a bit
suspicious.
> +
> + /* Call the class init function for subchannel. */
> + if (cdc->realize) {
> + cdc->realize(cdev, vcdev->vdev.sysfsdev, errp);
> + if (*errp) {
> + return;
> + }
> + }
> +
> + group = vfio_ccw_get_group(cdev, path, errp);
> + if (!group) {
> + goto out_group_err;
> + }
> +
> + vcdev->vdev.ops = &vfio_ccw_ops;
> + vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
> + vcdev->vdev.name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
> + cdev->hostid.ssid, cdev->hostid.devid);
> + QLIST_FOREACH(vbasedev, &group->device_list, next) {
> + if (strcmp(vbasedev->name, vcdev->vdev.name) == 0) {
> + error_setg(errp, "vfio: subchannel %s has already been attached",
> + basename(path[0]));
> + goto out_device_err;
> + }
> + }
> +
> + if (vfio_get_device(group, cdev->mdevid, &vcdev->vdev, errp)) {
> + goto out_device_err;
> + }
> +
> + return;
> +
> +out_device_err:
> + vfio_ccw_put_group(group, path);
> +out_group_err:
> + if (cdc->unrealize) {
> + cdc->unrealize(cdev, errp);
> + }
> +}
> +
> +static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
> +{
> + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
> + VFIOGroup *group = vcdev->vdev.group;
> +
> + if (cdc->unrealize) {
> + cdc->unrealize(cdev, errp);
> + }
> +
> + vfio_put_device(vcdev);
> + vfio_put_group(group);
> +}
Doesn't seem to matter here, but I would have expected the
cdc->unrealize to occur at the end to unwind the order of the realize
function.
> +
> +static Property vfio_ccw_properties[] = {
> + DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev),
> + DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static const VMStateDescription vfio_ccw_vmstate = {
> + .name = TYPE_VFIO_CCW,
> + .unmigratable = 1,
> +};
> +
> +static void vfio_ccw_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> +
> + dc->props = vfio_ccw_properties;
> + dc->vmsd = &vfio_ccw_vmstate;
> + dc->desc = "VFIO-based subchannel assignment";
> + dc->realize = vfio_ccw_realize;
> + dc->unrealize = vfio_ccw_unrealize;
> + dc->reset = vfio_ccw_reset;
> +}
> +
> +static const TypeInfo vfio_ccw_info = {
> + .name = TYPE_VFIO_CCW,
> + .parent = TYPE_S390_CCW,
> + .instance_size = sizeof(VFIOCCWDevice),
> + .class_init = vfio_ccw_class_init,
> +};
> +
> +static void register_vfio_ccw_type(void)
> +{
> + type_register_static(&vfio_ccw_info);
> +}
> +
> +type_init(register_vfio_ccw_type)
> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
> index c582de1..9521013 100644
> --- a/include/hw/vfio/vfio-common.h
> +++ b/include/hw/vfio/vfio-common.h
> @@ -45,6 +45,7 @@
> enum {
> VFIO_DEVICE_TYPE_PCI = 0,
> VFIO_DEVICE_TYPE_PLATFORM = 1,
> + VFIO_DEVICE_TYPE_CCW = 2,
> };
>
> typedef struct VFIOMmap {
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 06/13] s390x/css: device support for s390-ccw passthrough
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
@ 2017-04-24 22:52 ` Alex Williamson
-1 siblings, 0 replies; 40+ messages in thread
From: Alex Williamson @ 2017-04-24 22:52 UTC (permalink / raw)
To: Dong Jia Shi
Cc: kvm, linux-s390, qemu-devel, renxiaof, cornelia.huck, borntraeger, agraf
On Wed, 12 Apr 2017 07:21:08 +0200
Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> wrote:
> In order to support subchannels pass-through, we introduce a s390
> subchannel device called "s390-ccw" to hold the real subchannel info.
> The s390-ccw devices inherit from the abstract CcwDevice which connect
> to the existing virtual-css-bus.
>
> Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> ---
> hw/s390x/Makefile.objs | 1 +
> hw/s390x/s390-ccw.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++
> hw/s390x/s390-ccw.h | 38 ++++++++++++++
> 3 files changed, 173 insertions(+)
> create mode 100644 hw/s390x/s390-ccw.c
> create mode 100644 hw/s390x/s390-ccw.h
>
> diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
> index 41ac4ec..72a3d37 100644
> --- a/hw/s390x/Makefile.objs
> +++ b/hw/s390x/Makefile.objs
> @@ -13,3 +13,4 @@ obj-y += ccw-device.o
> obj-y += s390-pci-bus.o s390-pci-inst.o
> obj-y += s390-skeys.o
> obj-$(CONFIG_KVM) += s390-skeys-kvm.o
> +obj-y += s390-ccw.o
> diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
> new file mode 100644
> index 0000000..f3d5ed1
> --- /dev/null
> +++ b/hw/s390x/s390-ccw.c
> @@ -0,0 +1,134 @@
> +/*
> + * s390 CCW Assignment Support
> + *
> + * Copyright 2017 IBM Corp
> + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> + * Pierre Morel <pmorel@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.
> + */
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "hw/sysbus.h"
> +#include "libgen.h"
> +#include "hw/s390x/css.h"
> +#include "hw/s390x/css-bridge.h"
> +#include "s390-ccw.h"
> +
> +static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
> + char *sysfsdev,
> + Error **errp)
> +{
> + char dev_path[PATH_MAX], *tmp;
> + unsigned int cssid, ssid, devid;
> +
> + if (!sysfsdev) {
> + error_setg(errp, "No host device provided");
> + error_append_hint(errp, "Use -vfio-ccw,sysfsdev=PATH_TO_DEVICE\n");
nit, the leading '-' here seems strange, either you're describing
'-device vfio-ccw,...', or only the 'vfio-ccw,...' part. Maybe I
notice this because sometimes I do accidentally type -vfio-pci instead
of -device vfio-pci. Thanks,
Alex
> + return;
> + }
> +
> + if (!realpath(sysfsdev, dev_path)) {
> + error_setg(errp, "Host device '%s' not found", sysfsdev);
> + return;
> + }
> +
> + cdev->mdevid = g_strdup(basename(dev_path));
> +
> + tmp = basename(dirname(dev_path));
> + sscanf(tmp, "%2x.%1x.%4x", &cssid, &ssid, &devid);
> +
> + cdev->hostid.cssid = cssid;
> + cdev->hostid.ssid = ssid;
> + cdev->hostid.devid = devid;
> + cdev->hostid.valid = true;
> +}
> +
> +static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
> +{
> + CcwDevice *ccw_dev = CCW_DEVICE(cdev);
> + CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
> + DeviceState *parent = DEVICE(ccw_dev);
> + BusState *qbus = qdev_get_parent_bus(parent);
> + VirtualCssBus *cbus = VIRTUAL_CSS_BUS(qbus);
> + SubchDev *sch;
> + int ret;
> + Error *err = NULL;
> +
> + s390_ccw_get_dev_info(cdev, sysfsdev, errp);
> + if (*errp) {
> + return;
> + }
> +
> + sch = css_create_sch(ccw_dev->devno, false, cbus->squash_mcss, errp);
> + if (!sch) {
> + return;
> + }
> + sch->driver_data = cdev;
> +
> + ccw_dev->sch = sch;
> + ret = css_sch_build_schib(sch, &cdev->hostid);
> + if (ret) {
> + error_setg(&err, "%s: Failed to build initial schib: %d",
> + __func__, ret);
> + goto out_err;
> + }
> +
> + ck->realize(ccw_dev, &err);
> + if (err) {
> + goto out_err;
> + }
> +
> + css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
> + parent->hotplugged, 1);
> + return;
> +
> +out_err:
> + error_propagate(errp, err);
> + css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
> + ccw_dev->sch = NULL;
> + g_free(sch);
> +}
> +
> +static void s390_ccw_unrealize(S390CCWDevice *cdev, Error **errp)
> +{
> + CcwDevice *ccw_dev = CCW_DEVICE(cdev);
> + SubchDev *sch = ccw_dev->sch;
> +
> + if (sch) {
> + css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
> + g_free(sch);
> + ccw_dev->sch = NULL;
> + }
> +
> + g_free(cdev->mdevid);
> +}
> +
> +static void s390_ccw_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass);
> +
> + dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
> + cdc->realize = s390_ccw_realize;
> + cdc->unrealize = s390_ccw_unrealize;
> +}
> +
> +static const TypeInfo s390_ccw_info = {
> + .name = TYPE_S390_CCW,
> + .parent = TYPE_CCW_DEVICE,
> + .instance_size = sizeof(S390CCWDevice),
> + .class_size = sizeof(S390CCWDeviceClass),
> + .class_init = s390_ccw_class_init,
> + .abstract = true,
> +};
> +
> +static void register_s390_ccw_type(void)
> +{
> + type_register_static(&s390_ccw_info);
> +}
> +
> +type_init(register_s390_ccw_type)
> diff --git a/hw/s390x/s390-ccw.h b/hw/s390x/s390-ccw.h
> new file mode 100644
> index 0000000..b58d8e9
> --- /dev/null
> +++ b/hw/s390x/s390-ccw.h
> @@ -0,0 +1,38 @@
> +/*
> + * s390 CCW Assignment Support
> + *
> + * Copyright 2017 IBM Corp.
> + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> + * Xiao Feng Ren <renxiaof@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 HW_S390_CCW_H
> +#define HW_S390_CCW_H
> +
> +#include "hw/s390x/ccw-device.h"
> +
> +#define TYPE_S390_CCW "s390-ccw"
> +#define S390_CCW_DEVICE(obj) \
> + OBJECT_CHECK(S390CCWDevice, (obj), TYPE_S390_CCW)
> +#define S390_CCW_DEVICE_CLASS(klass) \
> + OBJECT_CLASS_CHECK(S390CCWDeviceClass, (klass), TYPE_S390_CCW)
> +#define S390_CCW_DEVICE_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(S390CCWDeviceClass, (obj), TYPE_S390_CCW)
> +
> +typedef struct S390CCWDevice {
> + CcwDevice parent_obj;
> + CssDevId hostid;
> + char *mdevid;
> +} S390CCWDevice;
> +
> +typedef struct S390CCWDeviceClass {
> + CCWDeviceClass parent_class;
> + void (*realize)(S390CCWDevice *dev, char *sysfsdev, Error **errp);
> + void (*unrealize)(S390CCWDevice *dev, Error **errp);
> +} S390CCWDeviceClass;
> +
> +#endif
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [Qemu-devel] [PATCH v5 06/13] s390x/css: device support for s390-ccw passthrough
@ 2017-04-24 22:52 ` Alex Williamson
0 siblings, 0 replies; 40+ messages in thread
From: Alex Williamson @ 2017-04-24 22:52 UTC (permalink / raw)
To: Dong Jia Shi
Cc: kvm, linux-s390, qemu-devel, renxiaof, cornelia.huck, borntraeger, agraf
On Wed, 12 Apr 2017 07:21:08 +0200
Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> wrote:
> In order to support subchannels pass-through, we introduce a s390
> subchannel device called "s390-ccw" to hold the real subchannel info.
> The s390-ccw devices inherit from the abstract CcwDevice which connect
> to the existing virtual-css-bus.
>
> Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> ---
> hw/s390x/Makefile.objs | 1 +
> hw/s390x/s390-ccw.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++
> hw/s390x/s390-ccw.h | 38 ++++++++++++++
> 3 files changed, 173 insertions(+)
> create mode 100644 hw/s390x/s390-ccw.c
> create mode 100644 hw/s390x/s390-ccw.h
>
> diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
> index 41ac4ec..72a3d37 100644
> --- a/hw/s390x/Makefile.objs
> +++ b/hw/s390x/Makefile.objs
> @@ -13,3 +13,4 @@ obj-y += ccw-device.o
> obj-y += s390-pci-bus.o s390-pci-inst.o
> obj-y += s390-skeys.o
> obj-$(CONFIG_KVM) += s390-skeys-kvm.o
> +obj-y += s390-ccw.o
> diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
> new file mode 100644
> index 0000000..f3d5ed1
> --- /dev/null
> +++ b/hw/s390x/s390-ccw.c
> @@ -0,0 +1,134 @@
> +/*
> + * s390 CCW Assignment Support
> + *
> + * Copyright 2017 IBM Corp
> + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> + * Pierre Morel <pmorel@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.
> + */
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "hw/sysbus.h"
> +#include "libgen.h"
> +#include "hw/s390x/css.h"
> +#include "hw/s390x/css-bridge.h"
> +#include "s390-ccw.h"
> +
> +static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
> + char *sysfsdev,
> + Error **errp)
> +{
> + char dev_path[PATH_MAX], *tmp;
> + unsigned int cssid, ssid, devid;
> +
> + if (!sysfsdev) {
> + error_setg(errp, "No host device provided");
> + error_append_hint(errp, "Use -vfio-ccw,sysfsdev=PATH_TO_DEVICE\n");
nit, the leading '-' here seems strange, either you're describing
'-device vfio-ccw,...', or only the 'vfio-ccw,...' part. Maybe I
notice this because sometimes I do accidentally type -vfio-pci instead
of -device vfio-pci. Thanks,
Alex
> + return;
> + }
> +
> + if (!realpath(sysfsdev, dev_path)) {
> + error_setg(errp, "Host device '%s' not found", sysfsdev);
> + return;
> + }
> +
> + cdev->mdevid = g_strdup(basename(dev_path));
> +
> + tmp = basename(dirname(dev_path));
> + sscanf(tmp, "%2x.%1x.%4x", &cssid, &ssid, &devid);
> +
> + cdev->hostid.cssid = cssid;
> + cdev->hostid.ssid = ssid;
> + cdev->hostid.devid = devid;
> + cdev->hostid.valid = true;
> +}
> +
> +static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
> +{
> + CcwDevice *ccw_dev = CCW_DEVICE(cdev);
> + CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
> + DeviceState *parent = DEVICE(ccw_dev);
> + BusState *qbus = qdev_get_parent_bus(parent);
> + VirtualCssBus *cbus = VIRTUAL_CSS_BUS(qbus);
> + SubchDev *sch;
> + int ret;
> + Error *err = NULL;
> +
> + s390_ccw_get_dev_info(cdev, sysfsdev, errp);
> + if (*errp) {
> + return;
> + }
> +
> + sch = css_create_sch(ccw_dev->devno, false, cbus->squash_mcss, errp);
> + if (!sch) {
> + return;
> + }
> + sch->driver_data = cdev;
> +
> + ccw_dev->sch = sch;
> + ret = css_sch_build_schib(sch, &cdev->hostid);
> + if (ret) {
> + error_setg(&err, "%s: Failed to build initial schib: %d",
> + __func__, ret);
> + goto out_err;
> + }
> +
> + ck->realize(ccw_dev, &err);
> + if (err) {
> + goto out_err;
> + }
> +
> + css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
> + parent->hotplugged, 1);
> + return;
> +
> +out_err:
> + error_propagate(errp, err);
> + css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
> + ccw_dev->sch = NULL;
> + g_free(sch);
> +}
> +
> +static void s390_ccw_unrealize(S390CCWDevice *cdev, Error **errp)
> +{
> + CcwDevice *ccw_dev = CCW_DEVICE(cdev);
> + SubchDev *sch = ccw_dev->sch;
> +
> + if (sch) {
> + css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
> + g_free(sch);
> + ccw_dev->sch = NULL;
> + }
> +
> + g_free(cdev->mdevid);
> +}
> +
> +static void s390_ccw_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass);
> +
> + dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
> + cdc->realize = s390_ccw_realize;
> + cdc->unrealize = s390_ccw_unrealize;
> +}
> +
> +static const TypeInfo s390_ccw_info = {
> + .name = TYPE_S390_CCW,
> + .parent = TYPE_CCW_DEVICE,
> + .instance_size = sizeof(S390CCWDevice),
> + .class_size = sizeof(S390CCWDeviceClass),
> + .class_init = s390_ccw_class_init,
> + .abstract = true,
> +};
> +
> +static void register_s390_ccw_type(void)
> +{
> + type_register_static(&s390_ccw_info);
> +}
> +
> +type_init(register_s390_ccw_type)
> diff --git a/hw/s390x/s390-ccw.h b/hw/s390x/s390-ccw.h
> new file mode 100644
> index 0000000..b58d8e9
> --- /dev/null
> +++ b/hw/s390x/s390-ccw.h
> @@ -0,0 +1,38 @@
> +/*
> + * s390 CCW Assignment Support
> + *
> + * Copyright 2017 IBM Corp.
> + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> + * Xiao Feng Ren <renxiaof@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 HW_S390_CCW_H
> +#define HW_S390_CCW_H
> +
> +#include "hw/s390x/ccw-device.h"
> +
> +#define TYPE_S390_CCW "s390-ccw"
> +#define S390_CCW_DEVICE(obj) \
> + OBJECT_CHECK(S390CCWDevice, (obj), TYPE_S390_CCW)
> +#define S390_CCW_DEVICE_CLASS(klass) \
> + OBJECT_CLASS_CHECK(S390CCWDeviceClass, (klass), TYPE_S390_CCW)
> +#define S390_CCW_DEVICE_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(S390CCWDeviceClass, (obj), TYPE_S390_CCW)
> +
> +typedef struct S390CCWDevice {
> + CcwDevice parent_obj;
> + CssDevId hostid;
> + char *mdevid;
> +} S390CCWDevice;
> +
> +typedef struct S390CCWDeviceClass {
> + CCWDeviceClass parent_class;
> + void (*realize)(S390CCWDevice *dev, char *sysfsdev, Error **errp);
> + void (*unrealize)(S390CCWDevice *dev, Error **errp);
> +} S390CCWDeviceClass;
> +
> +#endif
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
2017-04-24 22:43 ` [Qemu-devel] " Alex Williamson
@ 2017-04-24 22:56 ` Alex Williamson
-1 siblings, 0 replies; 40+ messages in thread
From: Alex Williamson @ 2017-04-24 22:56 UTC (permalink / raw)
To: Dong Jia Shi
Cc: kvm, linux-s390, qemu-devel, renxiaof, cornelia.huck, borntraeger, agraf
On Mon, 24 Apr 2017 16:43:38 -0600
Alex Williamson <alex.williamson@redhat.com> wrote:
> On Wed, 12 Apr 2017 07:21:09 +0200
> Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> wrote:
>
> > From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> >
> > We use the IOMMU_TYPE1 of VFIO to realize the subchannels
> > passthrough, implement a vfio based subchannels passthrough
> > driver called "vfio-ccw".
> >
> > Support qemu parameters in the style of:
> > "-device vfio-ccw,sysfsdev=$mdev_file_path,devno=xx.x.xxxx'
> >
> > Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> > Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> > ---
> > default-configs/s390x-softmmu.mak | 1 +
> > hw/vfio/Makefile.objs | 1 +
> > hw/vfio/ccw.c | 207 ++++++++++++++++++++++++++++++++++++++
> > include/hw/vfio/vfio-common.h | 1 +
> > 4 files changed, 210 insertions(+)
> > create mode 100644 hw/vfio/ccw.c
> >
> > diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak
> > index 36e15de..5576b0a 100644
> > --- a/default-configs/s390x-softmmu.mak
> > +++ b/default-configs/s390x-softmmu.mak
> > @@ -4,4 +4,5 @@ CONFIG_VIRTIO=y
> > CONFIG_SCLPCONSOLE=y
> > CONFIG_S390_FLIC=y
> > CONFIG_S390_FLIC_KVM=$(CONFIG_KVM)
> > +CONFIG_VFIO_CCW=$(CONFIG_LINUX)
> > CONFIG_WDT_DIAG288=y
> > diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs
> > index 05e7fbb..c3ab909 100644
> > --- a/hw/vfio/Makefile.objs
> > +++ b/hw/vfio/Makefile.objs
> > @@ -1,6 +1,7 @@
> > ifeq ($(CONFIG_LINUX), y)
> > obj-$(CONFIG_SOFTMMU) += common.o
> > obj-$(CONFIG_PCI) += pci.o pci-quirks.o
> > +obj-$(CONFIG_VFIO_CCW) += ccw.o
> > obj-$(CONFIG_SOFTMMU) += platform.o
> > obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o
> > obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o
> > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
> > new file mode 100644
> > index 0000000..c491bee
> > --- /dev/null
> > +++ b/hw/vfio/ccw.c
> > @@ -0,0 +1,207 @@
> > +/*
> > + * vfio based subchannel assignment support
> > + *
> > + * Copyright 2017 IBM Corp.
> > + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> > + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> > + * Pierre Morel <pmorel@linux.vnet.ibm.com>
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or(at
> > + * your option) any version. See the COPYING file in the top-level
> > + * directory.
> > + */
> > +
> > +#include <linux/vfio.h>
> > +#include <sys/ioctl.h>
> > +
> > +#include "qemu/osdep.h"
> > +#include "qapi/error.h"
> > +#include "hw/sysbus.h"
> > +#include "hw/vfio/vfio.h"
> > +#include "hw/vfio/vfio-common.h"
> > +#include "hw/s390x/s390-ccw.h"
> > +#include "hw/s390x/ccw-device.h"
> > +
> > +#define TYPE_VFIO_CCW "vfio-ccw"
> > +typedef struct VFIOCCWDevice {
> > + S390CCWDevice cdev;
> > + VFIODevice vdev;
> > +} VFIOCCWDevice;
> > +
> > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
> > +{
> > + vdev->needs_reset = false;
> > +}
> > +
> > +/*
> > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for
One more:
s/operationis/operations/
> > + * vfio_ccw device now.
> > + */
> > +struct VFIODeviceOps vfio_ccw_ops = {
> > + .vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
> > +};
> > +
> > +static void vfio_ccw_reset(DeviceState *dev)
> > +{
> > + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> > + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> > + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> > +
> > + ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
> > +}
> > +
> > +static void vfio_put_device(VFIOCCWDevice *vcdev)
> > +{
> > + g_free(vcdev->vdev.name);
> > + vfio_put_base_device(&vcdev->vdev);
> > +}
> > +
> > +static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, char **path,
> > + Error **errp)
> > +{
> > + struct stat st;
> > + int groupid;
> > + GError *gerror = NULL;
> > +
> > + /* Check that host subchannel exists. */
> > + path[0] = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x",
> > + cdev->hostid.cssid,
> > + cdev->hostid.ssid,
> > + cdev->hostid.devid);
> > + if (stat(path[0], &st) < 0) {
> > + error_setg(errp, "vfio: no such host subchannel %s", path[0]);
> > + return NULL;
> > + }
> > +
> > + /* Check that mediated device exists. */
> > + path[1] = g_strdup_printf("%s/%s", path[0], cdev->mdevid);
> > + if (stat(path[0], &st) < 0) {
> > + error_setg(errp, "vfio: no such mediated device %s", path[1]);
> > + return NULL;
> > + }
>
> Isn't this all a bit circular since we build the S390CCWDevice based on
> the sysfsdev mdev path?
>
> > +
> > + /* Get the iommu_group patch as the interim variable. */
> > + path[2] = g_strconcat(path[1], "/iommu_group", NULL);
> > +
> > + /* Get the link file path of the device iommu_group. */
> > + path[3] = g_file_read_link(path[2], &gerror);
> > + if (!path[3]) {
> > + error_setg(errp, "vfio: error no iommu_group for subchannel");
> > + return NULL;
> > + }
> > +
> > + /* Get the device groupid. */
> > + if (sscanf(basename(path[3]), "%d", &groupid) != 1) {
> > + error_setg(errp, "vfio: error reading %s:%m", path[3]);
> > + return NULL;
> > + }
> > +
> > + return vfio_get_group(groupid, &address_space_memory, errp);
> > +}
> > +
> > +static void vfio_ccw_put_group(VFIOGroup *group, char **path)
> > +{
> > + g_free(path);
> > + vfio_put_group(group);
> > +}
> > +
> > +static void vfio_ccw_realize(DeviceState *dev, Error **errp)
> > +{
> > + VFIODevice *vbasedev;
> > + VFIOGroup *group;
> > + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> > + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> > + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> > + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
> > + char *path[4] = {NULL, NULL, NULL, NULL};
>
> I don't understand what's happening with 'path' throughout this
> function. vfio_ccw_get_group() allocates strings into this array, we
> only seem to use one in an error path below, it's only freed on an error
> path and I don't see it getting linked to the VFIOCCWDevice, so it
> seems to be leaked, and even the g_free() above looks quite a bit
> suspicious.
>
> > +
> > + /* Call the class init function for subchannel. */
> > + if (cdc->realize) {
> > + cdc->realize(cdev, vcdev->vdev.sysfsdev, errp);
> > + if (*errp) {
> > + return;
> > + }
> > + }
> > +
> > + group = vfio_ccw_get_group(cdev, path, errp);
> > + if (!group) {
> > + goto out_group_err;
> > + }
> > +
> > + vcdev->vdev.ops = &vfio_ccw_ops;
> > + vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
> > + vcdev->vdev.name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
> > + cdev->hostid.ssid, cdev->hostid.devid);
> > + QLIST_FOREACH(vbasedev, &group->device_list, next) {
> > + if (strcmp(vbasedev->name, vcdev->vdev.name) == 0) {
> > + error_setg(errp, "vfio: subchannel %s has already been attached",
> > + basename(path[0]));
> > + goto out_device_err;
> > + }
> > + }
> > +
> > + if (vfio_get_device(group, cdev->mdevid, &vcdev->vdev, errp)) {
> > + goto out_device_err;
> > + }
> > +
> > + return;
> > +
> > +out_device_err:
> > + vfio_ccw_put_group(group, path);
> > +out_group_err:
> > + if (cdc->unrealize) {
> > + cdc->unrealize(cdev, errp);
> > + }
> > +}
> > +
> > +static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
> > +{
> > + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> > + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> > + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> > + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
> > + VFIOGroup *group = vcdev->vdev.group;
> > +
> > + if (cdc->unrealize) {
> > + cdc->unrealize(cdev, errp);
> > + }
> > +
> > + vfio_put_device(vcdev);
> > + vfio_put_group(group);
> > +}
>
> Doesn't seem to matter here, but I would have expected the
> cdc->unrealize to occur at the end to unwind the order of the realize
> function.
>
> > +
> > +static Property vfio_ccw_properties[] = {
> > + DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev),
> > + DEFINE_PROP_END_OF_LIST(),
> > +};
> > +
> > +static const VMStateDescription vfio_ccw_vmstate = {
> > + .name = TYPE_VFIO_CCW,
> > + .unmigratable = 1,
> > +};
> > +
> > +static void vfio_ccw_class_init(ObjectClass *klass, void *data)
> > +{
> > + DeviceClass *dc = DEVICE_CLASS(klass);
> > +
> > + dc->props = vfio_ccw_properties;
> > + dc->vmsd = &vfio_ccw_vmstate;
> > + dc->desc = "VFIO-based subchannel assignment";
> > + dc->realize = vfio_ccw_realize;
> > + dc->unrealize = vfio_ccw_unrealize;
> > + dc->reset = vfio_ccw_reset;
> > +}
> > +
> > +static const TypeInfo vfio_ccw_info = {
> > + .name = TYPE_VFIO_CCW,
> > + .parent = TYPE_S390_CCW,
> > + .instance_size = sizeof(VFIOCCWDevice),
> > + .class_init = vfio_ccw_class_init,
> > +};
> > +
> > +static void register_vfio_ccw_type(void)
> > +{
> > + type_register_static(&vfio_ccw_info);
> > +}
> > +
> > +type_init(register_vfio_ccw_type)
> > diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
> > index c582de1..9521013 100644
> > --- a/include/hw/vfio/vfio-common.h
> > +++ b/include/hw/vfio/vfio-common.h
> > @@ -45,6 +45,7 @@
> > enum {
> > VFIO_DEVICE_TYPE_PCI = 0,
> > VFIO_DEVICE_TYPE_PLATFORM = 1,
> > + VFIO_DEVICE_TYPE_CCW = 2,
> > };
> >
> > typedef struct VFIOMmap {
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
@ 2017-04-24 22:56 ` Alex Williamson
0 siblings, 0 replies; 40+ messages in thread
From: Alex Williamson @ 2017-04-24 22:56 UTC (permalink / raw)
To: Dong Jia Shi
Cc: kvm, linux-s390, qemu-devel, renxiaof, cornelia.huck, borntraeger, agraf
On Mon, 24 Apr 2017 16:43:38 -0600
Alex Williamson <alex.williamson@redhat.com> wrote:
> On Wed, 12 Apr 2017 07:21:09 +0200
> Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> wrote:
>
> > From: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> >
> > We use the IOMMU_TYPE1 of VFIO to realize the subchannels
> > passthrough, implement a vfio based subchannels passthrough
> > driver called "vfio-ccw".
> >
> > Support qemu parameters in the style of:
> > "-device vfio-ccw,sysfsdev=$mdev_file_path,devno=xx.x.xxxx'
> >
> > Signed-off-by: Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> > Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> > ---
> > default-configs/s390x-softmmu.mak | 1 +
> > hw/vfio/Makefile.objs | 1 +
> > hw/vfio/ccw.c | 207 ++++++++++++++++++++++++++++++++++++++
> > include/hw/vfio/vfio-common.h | 1 +
> > 4 files changed, 210 insertions(+)
> > create mode 100644 hw/vfio/ccw.c
> >
> > diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak
> > index 36e15de..5576b0a 100644
> > --- a/default-configs/s390x-softmmu.mak
> > +++ b/default-configs/s390x-softmmu.mak
> > @@ -4,4 +4,5 @@ CONFIG_VIRTIO=y
> > CONFIG_SCLPCONSOLE=y
> > CONFIG_S390_FLIC=y
> > CONFIG_S390_FLIC_KVM=$(CONFIG_KVM)
> > +CONFIG_VFIO_CCW=$(CONFIG_LINUX)
> > CONFIG_WDT_DIAG288=y
> > diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs
> > index 05e7fbb..c3ab909 100644
> > --- a/hw/vfio/Makefile.objs
> > +++ b/hw/vfio/Makefile.objs
> > @@ -1,6 +1,7 @@
> > ifeq ($(CONFIG_LINUX), y)
> > obj-$(CONFIG_SOFTMMU) += common.o
> > obj-$(CONFIG_PCI) += pci.o pci-quirks.o
> > +obj-$(CONFIG_VFIO_CCW) += ccw.o
> > obj-$(CONFIG_SOFTMMU) += platform.o
> > obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o
> > obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o
> > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
> > new file mode 100644
> > index 0000000..c491bee
> > --- /dev/null
> > +++ b/hw/vfio/ccw.c
> > @@ -0,0 +1,207 @@
> > +/*
> > + * vfio based subchannel assignment support
> > + *
> > + * Copyright 2017 IBM Corp.
> > + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> > + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> > + * Pierre Morel <pmorel@linux.vnet.ibm.com>
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or(at
> > + * your option) any version. See the COPYING file in the top-level
> > + * directory.
> > + */
> > +
> > +#include <linux/vfio.h>
> > +#include <sys/ioctl.h>
> > +
> > +#include "qemu/osdep.h"
> > +#include "qapi/error.h"
> > +#include "hw/sysbus.h"
> > +#include "hw/vfio/vfio.h"
> > +#include "hw/vfio/vfio-common.h"
> > +#include "hw/s390x/s390-ccw.h"
> > +#include "hw/s390x/ccw-device.h"
> > +
> > +#define TYPE_VFIO_CCW "vfio-ccw"
> > +typedef struct VFIOCCWDevice {
> > + S390CCWDevice cdev;
> > + VFIODevice vdev;
> > +} VFIOCCWDevice;
> > +
> > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
> > +{
> > + vdev->needs_reset = false;
> > +}
> > +
> > +/*
> > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for
One more:
s/operationis/operations/
> > + * vfio_ccw device now.
> > + */
> > +struct VFIODeviceOps vfio_ccw_ops = {
> > + .vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
> > +};
> > +
> > +static void vfio_ccw_reset(DeviceState *dev)
> > +{
> > + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> > + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> > + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> > +
> > + ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
> > +}
> > +
> > +static void vfio_put_device(VFIOCCWDevice *vcdev)
> > +{
> > + g_free(vcdev->vdev.name);
> > + vfio_put_base_device(&vcdev->vdev);
> > +}
> > +
> > +static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, char **path,
> > + Error **errp)
> > +{
> > + struct stat st;
> > + int groupid;
> > + GError *gerror = NULL;
> > +
> > + /* Check that host subchannel exists. */
> > + path[0] = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x",
> > + cdev->hostid.cssid,
> > + cdev->hostid.ssid,
> > + cdev->hostid.devid);
> > + if (stat(path[0], &st) < 0) {
> > + error_setg(errp, "vfio: no such host subchannel %s", path[0]);
> > + return NULL;
> > + }
> > +
> > + /* Check that mediated device exists. */
> > + path[1] = g_strdup_printf("%s/%s", path[0], cdev->mdevid);
> > + if (stat(path[0], &st) < 0) {
> > + error_setg(errp, "vfio: no such mediated device %s", path[1]);
> > + return NULL;
> > + }
>
> Isn't this all a bit circular since we build the S390CCWDevice based on
> the sysfsdev mdev path?
>
> > +
> > + /* Get the iommu_group patch as the interim variable. */
> > + path[2] = g_strconcat(path[1], "/iommu_group", NULL);
> > +
> > + /* Get the link file path of the device iommu_group. */
> > + path[3] = g_file_read_link(path[2], &gerror);
> > + if (!path[3]) {
> > + error_setg(errp, "vfio: error no iommu_group for subchannel");
> > + return NULL;
> > + }
> > +
> > + /* Get the device groupid. */
> > + if (sscanf(basename(path[3]), "%d", &groupid) != 1) {
> > + error_setg(errp, "vfio: error reading %s:%m", path[3]);
> > + return NULL;
> > + }
> > +
> > + return vfio_get_group(groupid, &address_space_memory, errp);
> > +}
> > +
> > +static void vfio_ccw_put_group(VFIOGroup *group, char **path)
> > +{
> > + g_free(path);
> > + vfio_put_group(group);
> > +}
> > +
> > +static void vfio_ccw_realize(DeviceState *dev, Error **errp)
> > +{
> > + VFIODevice *vbasedev;
> > + VFIOGroup *group;
> > + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> > + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> > + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> > + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
> > + char *path[4] = {NULL, NULL, NULL, NULL};
>
> I don't understand what's happening with 'path' throughout this
> function. vfio_ccw_get_group() allocates strings into this array, we
> only seem to use one in an error path below, it's only freed on an error
> path and I don't see it getting linked to the VFIOCCWDevice, so it
> seems to be leaked, and even the g_free() above looks quite a bit
> suspicious.
>
> > +
> > + /* Call the class init function for subchannel. */
> > + if (cdc->realize) {
> > + cdc->realize(cdev, vcdev->vdev.sysfsdev, errp);
> > + if (*errp) {
> > + return;
> > + }
> > + }
> > +
> > + group = vfio_ccw_get_group(cdev, path, errp);
> > + if (!group) {
> > + goto out_group_err;
> > + }
> > +
> > + vcdev->vdev.ops = &vfio_ccw_ops;
> > + vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
> > + vcdev->vdev.name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
> > + cdev->hostid.ssid, cdev->hostid.devid);
> > + QLIST_FOREACH(vbasedev, &group->device_list, next) {
> > + if (strcmp(vbasedev->name, vcdev->vdev.name) == 0) {
> > + error_setg(errp, "vfio: subchannel %s has already been attached",
> > + basename(path[0]));
> > + goto out_device_err;
> > + }
> > + }
> > +
> > + if (vfio_get_device(group, cdev->mdevid, &vcdev->vdev, errp)) {
> > + goto out_device_err;
> > + }
> > +
> > + return;
> > +
> > +out_device_err:
> > + vfio_ccw_put_group(group, path);
> > +out_group_err:
> > + if (cdc->unrealize) {
> > + cdc->unrealize(cdev, errp);
> > + }
> > +}
> > +
> > +static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
> > +{
> > + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> > + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> > + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> > + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
> > + VFIOGroup *group = vcdev->vdev.group;
> > +
> > + if (cdc->unrealize) {
> > + cdc->unrealize(cdev, errp);
> > + }
> > +
> > + vfio_put_device(vcdev);
> > + vfio_put_group(group);
> > +}
>
> Doesn't seem to matter here, but I would have expected the
> cdc->unrealize to occur at the end to unwind the order of the realize
> function.
>
> > +
> > +static Property vfio_ccw_properties[] = {
> > + DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev),
> > + DEFINE_PROP_END_OF_LIST(),
> > +};
> > +
> > +static const VMStateDescription vfio_ccw_vmstate = {
> > + .name = TYPE_VFIO_CCW,
> > + .unmigratable = 1,
> > +};
> > +
> > +static void vfio_ccw_class_init(ObjectClass *klass, void *data)
> > +{
> > + DeviceClass *dc = DEVICE_CLASS(klass);
> > +
> > + dc->props = vfio_ccw_properties;
> > + dc->vmsd = &vfio_ccw_vmstate;
> > + dc->desc = "VFIO-based subchannel assignment";
> > + dc->realize = vfio_ccw_realize;
> > + dc->unrealize = vfio_ccw_unrealize;
> > + dc->reset = vfio_ccw_reset;
> > +}
> > +
> > +static const TypeInfo vfio_ccw_info = {
> > + .name = TYPE_VFIO_CCW,
> > + .parent = TYPE_S390_CCW,
> > + .instance_size = sizeof(VFIOCCWDevice),
> > + .class_init = vfio_ccw_class_init,
> > +};
> > +
> > +static void register_vfio_ccw_type(void)
> > +{
> > + type_register_static(&vfio_ccw_info);
> > +}
> > +
> > +type_init(register_vfio_ccw_type)
> > diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
> > index c582de1..9521013 100644
> > --- a/include/hw/vfio/vfio-common.h
> > +++ b/include/hw/vfio/vfio-common.h
> > @@ -45,6 +45,7 @@
> > enum {
> > VFIO_DEVICE_TYPE_PCI = 0,
> > VFIO_DEVICE_TYPE_PLATFORM = 1,
> > + VFIO_DEVICE_TYPE_CCW = 2,
> > };
> >
> > typedef struct VFIOMmap {
>
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [Qemu-devel] [PATCH v5 06/13] s390x/css: device support for s390-ccw passthrough
[not found] ` <20170424201618.0d3ffd81@w520.home>
@ 2017-04-25 3:32 ` Dong Jia Shi
0 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-25 3:32 UTC (permalink / raw)
To: Alex Williamson
Cc: Dong Jia Shi, kvm, linux-s390, qemu-devel, renxiaof,
cornelia.huck, borntraeger, agraf
* Alex Williamson <alex.williamson@redhat.com> [2017-04-24 20:16:18 -0600]:
> On Tue, 25 Apr 2017 10:10:22 +0800
> Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> wrote:
>
> > * Alex Williamson <alex.williamson@redhat.com> [2017-04-24 16:52:58 -0600]:
> >
> > > On Wed, 12 Apr 2017 07:21:08 +0200
> > > Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> wrote:
> > >
> > > > In order to support subchannels pass-through, we introduce a s390
> > > > subchannel device called "s390-ccw" to hold the real subchannel info.
> > > > The s390-ccw devices inherit from the abstract CcwDevice which connect
> > > > to the existing virtual-css-bus.
> > > >
> > > > Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> > > > ---
> > > > hw/s390x/Makefile.objs | 1 +
> > > > hw/s390x/s390-ccw.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++
> > > > hw/s390x/s390-ccw.h | 38 ++++++++++++++
> > > > 3 files changed, 173 insertions(+)
> > > > create mode 100644 hw/s390x/s390-ccw.c
> > > > create mode 100644 hw/s390x/s390-ccw.h
> > > >
> > > > diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
> > > > index 41ac4ec..72a3d37 100644
> > > > --- a/hw/s390x/Makefile.objs
> > > > +++ b/hw/s390x/Makefile.objs
> > > > @@ -13,3 +13,4 @@ obj-y += ccw-device.o
> > > > obj-y += s390-pci-bus.o s390-pci-inst.o
> > > > obj-y += s390-skeys.o
> > > > obj-$(CONFIG_KVM) += s390-skeys-kvm.o
> > > > +obj-y += s390-ccw.o
> > > > diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
> > > > new file mode 100644
> > > > index 0000000..f3d5ed1
> > > > --- /dev/null
> > > > +++ b/hw/s390x/s390-ccw.c
> > > > @@ -0,0 +1,134 @@
> > > > +/*
> > > > + * s390 CCW Assignment Support
> > > > + *
> > > > + * Copyright 2017 IBM Corp
> > > > + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> > > > + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> > > > + * Pierre Morel <pmorel@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.
> > > > + */
> > > > +#include "qemu/osdep.h"
> > > > +#include "qapi/error.h"
> > > > +#include "hw/sysbus.h"
> > > > +#include "libgen.h"
> > > > +#include "hw/s390x/css.h"
> > > > +#include "hw/s390x/css-bridge.h"
> > > > +#include "s390-ccw.h"
> > > > +
> > > > +static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
> > > > + char *sysfsdev,
> > > > + Error **errp)
> > > > +{
> > > > + char dev_path[PATH_MAX], *tmp;
> > > > + unsigned int cssid, ssid, devid;
> > > > +
> > > > + if (!sysfsdev) {
> > > > + error_setg(errp, "No host device provided");
> > > > + error_append_hint(errp, "Use -vfio-ccw,sysfsdev=PATH_TO_DEVICE\n");
> > >
> > > nit, the leading '-' here seems strange, either you're describing
> > > '-device vfio-ccw,...', or only the 'vfio-ccw,...' part. Maybe I
> > > notice this because sometimes I do accidentally type -vfio-pci instead
> > > of -device vfio-pci. Thanks,
> > >
> > > Alex
> > >
> > Ok. I will change it to:
> > error_append_hint(errp,
> > "Use -device vfio-ccw,sysfsdev=PATH_TO_DEVICE\n");
> >
> > BTW, I learned this from the pci code.
> > hw/vfio/pci.c:2628:
> > error_append_hint(errp, "Use -vfio-pci,host=DDDD:BB:DD.F "
> > "or -vfio-pci,sysfsdev=PATH_TO_DEVICE\n")
> > Welcome a fix to that too?
>
> Aha, maybe that's where I learned my bad habit. Yes, please send a
> patch separate from this series. Thanks,
>
> Alex
>
Will do soon. ;>
> > > > + return;
> > > > + }
> > > > +
> > > > + if (!realpath(sysfsdev, dev_path)) {
> > > > + error_setg(errp, "Host device '%s' not found", sysfsdev);
> > > > + return;
> > > > + }
> > > > +
> > > > + cdev->mdevid = g_strdup(basename(dev_path));
> > > > +
> > > > + tmp = basename(dirname(dev_path));
> > > > + sscanf(tmp, "%2x.%1x.%4x", &cssid, &ssid, &devid);
> > > > +
> > > > + cdev->hostid.cssid = cssid;
> > > > + cdev->hostid.ssid = ssid;
> > > > + cdev->hostid.devid = devid;
> > > > + cdev->hostid.valid = true;
> > > > +}
> > > > +
> > [...]
> >
>
--
Dong Jia Shi
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
2017-04-24 22:56 ` [Qemu-devel] " Alex Williamson
(?)
@ 2017-04-25 5:15 ` Dong Jia Shi
2017-04-26 8:49 ` Dong Jia Shi
-1 siblings, 1 reply; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-25 5:15 UTC (permalink / raw)
To: Alex Williamson
Cc: Dong Jia Shi, kvm, linux-s390, qemu-devel, renxiaof,
cornelia.huck, borntraeger, agraf
* Alex Williamson <alex.williamson@redhat.com> [2017-04-24 16:56:28 -0600]:
[...]
> > > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
> > > new file mode 100644
> > > index 0000000..c491bee
> > > --- /dev/null
> > > +++ b/hw/vfio/ccw.c
> > > @@ -0,0 +1,207 @@
> > > +/*
> > > + * vfio based subchannel assignment support
> > > + *
> > > + * Copyright 2017 IBM Corp.
> > > + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> > > + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> > > + * Pierre Morel <pmorel@linux.vnet.ibm.com>
> > > + *
> > > + * This work is licensed under the terms of the GNU GPL, version 2 or(at
> > > + * your option) any version. See the COPYING file in the top-level
> > > + * directory.
> > > + */
> > > +
> > > +#include <linux/vfio.h>
> > > +#include <sys/ioctl.h>
> > > +
> > > +#include "qemu/osdep.h"
> > > +#include "qapi/error.h"
> > > +#include "hw/sysbus.h"
> > > +#include "hw/vfio/vfio.h"
> > > +#include "hw/vfio/vfio-common.h"
> > > +#include "hw/s390x/s390-ccw.h"
> > > +#include "hw/s390x/ccw-device.h"
> > > +
> > > +#define TYPE_VFIO_CCW "vfio-ccw"
> > > +typedef struct VFIOCCWDevice {
> > > + S390CCWDevice cdev;
> > > + VFIODevice vdev;
> > > +} VFIOCCWDevice;
> > > +
> > > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
> > > +{
> > > + vdev->needs_reset = false;
> > > +}
> > > +
> > > +/*
> > > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for
>
> One more:
>
> s/operationis/operations/
>
Ok.
> > > + * vfio_ccw device now.
> > > + */
> > > +struct VFIODeviceOps vfio_ccw_ops = {
> > > + .vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
> > > +};
> > > +
> > > +static void vfio_ccw_reset(DeviceState *dev)
> > > +{
> > > + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> > > + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> > > + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> > > +
> > > + ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
> > > +}
> > > +
> > > +static void vfio_put_device(VFIOCCWDevice *vcdev)
> > > +{
> > > + g_free(vcdev->vdev.name);
> > > + vfio_put_base_device(&vcdev->vdev);
> > > +}
> > > +
> > > +static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, char **path,
> > > + Error **errp)
> > > +{
> > > + struct stat st;
> > > + int groupid;
> > > + GError *gerror = NULL;
> > > +
> > > + /* Check that host subchannel exists. */
> > > + path[0] = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x",
> > > + cdev->hostid.cssid,
> > > + cdev->hostid.ssid,
> > > + cdev->hostid.devid);
> > > + if (stat(path[0], &st) < 0) {
> > > + error_setg(errp, "vfio: no such host subchannel %s", path[0]);
> > > + return NULL;
> > > + }
> > > +
> > > + /* Check that mediated device exists. */
> > > + path[1] = g_strdup_printf("%s/%s", path[0], cdev->mdevid);
> > > + if (stat(path[0], &st) < 0) {
> > > + error_setg(errp, "vfio: no such mediated device %s", path[1]);
> > > + return NULL;
> > > + }
> >
> > Isn't this all a bit circular since we build the S390CCWDevice based on
> > the sysfsdev mdev path?
> >
Right! We don't need to verify the existance of the path here again,
since we already did that during the realization of the S390CCWDevice,
which is triggered by calling cdc->realize before vfio_ccw_get_group in
vfio_ccw_realize.
> > > +
> > > + /* Get the iommu_group patch as the interim variable. */
> > > + path[2] = g_strconcat(path[1], "/iommu_group", NULL);
> > > +
> > > + /* Get the link file path of the device iommu_group. */
> > > + path[3] = g_file_read_link(path[2], &gerror);
> > > + if (!path[3]) {
> > > + error_setg(errp, "vfio: error no iommu_group for subchannel");
> > > + return NULL;
> > > + }
> > > +
> > > + /* Get the device groupid. */
> > > + if (sscanf(basename(path[3]), "%d", &groupid) != 1) {
> > > + error_setg(errp, "vfio: error reading %s:%m", path[3]);
> > > + return NULL;
> > > + }
> > > +
> > > + return vfio_get_group(groupid, &address_space_memory, errp);
> > > +}
> > > +
> > > +static void vfio_ccw_put_group(VFIOGroup *group, char **path)
> > > +{
> > > + g_free(path);
> > > + vfio_put_group(group);
> > > +}
> > > +
> > > +static void vfio_ccw_realize(DeviceState *dev, Error **errp)
> > > +{
> > > + VFIODevice *vbasedev;
> > > + VFIOGroup *group;
> > > + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> > > + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> > > + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> > > + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
> > > + char *path[4] = {NULL, NULL, NULL, NULL};
> >
> > I don't understand what's happening with 'path' throughout this
> > function. vfio_ccw_get_group() allocates strings into this array, we
> > only seem to use one in an error path below, it's only freed on an error
> > path and I don't see it getting linked to the VFIOCCWDevice, so it
> > seems to be leaked, and even the g_free() above looks quite a bit
> > suspicious.
This @path, together with the operations on it, must be a leftover of a
previous implementation. I will rewrite these stuff. Thanks for the
catch!
> >
> > > +
> > > + /* Call the class init function for subchannel. */
> > > + if (cdc->realize) {
> > > + cdc->realize(cdev, vcdev->vdev.sysfsdev, errp);
> > > + if (*errp) {
> > > + return;
> > > + }
> > > + }
> > > +
> > > + group = vfio_ccw_get_group(cdev, path, errp);
> > > + if (!group) {
> > > + goto out_group_err;
> > > + }
> > > +
> > > + vcdev->vdev.ops = &vfio_ccw_ops;
> > > + vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
> > > + vcdev->vdev.name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
> > > + cdev->hostid.ssid, cdev->hostid.devid);
> > > + QLIST_FOREACH(vbasedev, &group->device_list, next) {
> > > + if (strcmp(vbasedev->name, vcdev->vdev.name) == 0) {
> > > + error_setg(errp, "vfio: subchannel %s has already been attached",
> > > + basename(path[0]));
> > > + goto out_device_err;
> > > + }
> > > + }
> > > +
> > > + if (vfio_get_device(group, cdev->mdevid, &vcdev->vdev, errp)) {
> > > + goto out_device_err;
> > > + }
> > > +
> > > + return;
> > > +
> > > +out_device_err:
> > > + vfio_ccw_put_group(group, path);
> > > +out_group_err:
> > > + if (cdc->unrealize) {
> > > + cdc->unrealize(cdev, errp);
> > > + }
> > > +}
> > > +
> > > +static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
> > > +{
> > > + CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
> > > + S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
> > > + VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
> > > + S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
> > > + VFIOGroup *group = vcdev->vdev.group;
> > > +
> > > + if (cdc->unrealize) {
> > > + cdc->unrealize(cdev, errp);
> > > + }
> > > +
> > > + vfio_put_device(vcdev);
> > > + vfio_put_group(group);
> > > +}
> >
> > Doesn't seem to matter here, but I would have expected the
> > cdc->unrealize to occur at the end to unwind the order of the realize
> > function.
Ok! Will do.
> >
> > > +
[...]
--
Dong Jia Shi
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
2017-04-25 5:15 ` Dong Jia Shi
@ 2017-04-26 8:49 ` Dong Jia Shi
2017-04-28 11:04 ` [Qemu-devel] " Cornelia Huck
0 siblings, 1 reply; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-26 8:49 UTC (permalink / raw)
To: cornelia.huck
Cc: Alex Williamson, Dong Jia Shi, kvm, linux-s390, qemu-devel,
renxiaof, borntraeger, agraf
* Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> [2017-04-25 13:15:19 +0800]:
> * Alex Williamson <alex.williamson@redhat.com> [2017-04-24 16:56:28 -0600]:
>
> [...]
> > > > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
> > > > new file mode 100644
> > > > index 0000000..c491bee
> > > > --- /dev/null
> > > > +++ b/hw/vfio/ccw.c
> > > > @@ -0,0 +1,207 @@
> > > > +/*
> > > > + * vfio based subchannel assignment support
> > > > + *
> > > > + * Copyright 2017 IBM Corp.
> > > > + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> > > > + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> > > > + * Pierre Morel <pmorel@linux.vnet.ibm.com>
> > > > + *
> > > > + * This work is licensed under the terms of the GNU GPL, version 2 or(at
> > > > + * your option) any version. See the COPYING file in the top-level
> > > > + * directory.
> > > > + */
> > > > +
> > > > +#include <linux/vfio.h>
> > > > +#include <sys/ioctl.h>
> > > > +
> > > > +#include "qemu/osdep.h"
> > > > +#include "qapi/error.h"
> > > > +#include "hw/sysbus.h"
> > > > +#include "hw/vfio/vfio.h"
> > > > +#include "hw/vfio/vfio-common.h"
> > > > +#include "hw/s390x/s390-ccw.h"
> > > > +#include "hw/s390x/ccw-device.h"
> > > > +
> > > > +#define TYPE_VFIO_CCW "vfio-ccw"
> > > > +typedef struct VFIOCCWDevice {
> > > > + S390CCWDevice cdev;
> > > > + VFIODevice vdev;
> > > > +} VFIOCCWDevice;
> > > > +
> > > > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
> > > > +{
> > > > + vdev->needs_reset = false;
> > > > +}
> > > > +
> > > > +/*
> > > > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for
> >
> > One more:
> >
> > s/operationis/operations/
> >
> Ok.
>
Hi Conny,
I have pulled your cohuck-qemu/s390-next branch, and prepared a new
patch set with all of these problems fixed directly on the coressponding
commits on it. Fine to send out the new version as that?
Or I should rebase them against the latest master branch?
Thanks.
[...]
--
Dong Jia Shi
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
2017-04-26 8:49 ` Dong Jia Shi
@ 2017-04-28 11:04 ` Cornelia Huck
0 siblings, 0 replies; 40+ messages in thread
From: Cornelia Huck @ 2017-04-28 11:04 UTC (permalink / raw)
To: Dong Jia Shi
Cc: Alex Williamson, kvm, linux-s390, qemu-devel, renxiaof,
borntraeger, agraf
On Wed, 26 Apr 2017 16:49:20 +0800
Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> wrote:
> * Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> [2017-04-25 13:15:19 +0800]:
>
> > * Alex Williamson <alex.williamson@redhat.com> [2017-04-24 16:56:28 -0600]:
> >
> > [...]
> > > > > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
> > > > > new file mode 100644
> > > > > index 0000000..c491bee
> > > > > --- /dev/null
> > > > > +++ b/hw/vfio/ccw.c
> > > > > @@ -0,0 +1,207 @@
> > > > > +/*
> > > > > + * vfio based subchannel assignment support
> > > > > + *
> > > > > + * Copyright 2017 IBM Corp.
> > > > > + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> > > > > + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> > > > > + * Pierre Morel <pmorel@linux.vnet.ibm.com>
> > > > > + *
> > > > > + * This work is licensed under the terms of the GNU GPL, version 2 or(at
> > > > > + * your option) any version. See the COPYING file in the top-level
> > > > > + * directory.
> > > > > + */
> > > > > +
> > > > > +#include <linux/vfio.h>
> > > > > +#include <sys/ioctl.h>
> > > > > +
> > > > > +#include "qemu/osdep.h"
> > > > > +#include "qapi/error.h"
> > > > > +#include "hw/sysbus.h"
> > > > > +#include "hw/vfio/vfio.h"
> > > > > +#include "hw/vfio/vfio-common.h"
> > > > > +#include "hw/s390x/s390-ccw.h"
> > > > > +#include "hw/s390x/ccw-device.h"
> > > > > +
> > > > > +#define TYPE_VFIO_CCW "vfio-ccw"
> > > > > +typedef struct VFIOCCWDevice {
> > > > > + S390CCWDevice cdev;
> > > > > + VFIODevice vdev;
> > > > > +} VFIOCCWDevice;
> > > > > +
> > > > > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
> > > > > +{
> > > > > + vdev->needs_reset = false;
> > > > > +}
> > > > > +
> > > > > +/*
> > > > > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for
> > >
> > > One more:
> > >
> > > s/operationis/operations/
> > >
> > Ok.
> >
>
> Hi Conny,
>
> I have pulled your cohuck-qemu/s390-next branch, and prepared a new
> patch set with all of these problems fixed directly on the coressponding
> commits on it. Fine to send out the new version as that?
>
> Or I should rebase them against the latest master branch?
As I currently don't have things in my next branch that should interact
with your changes, either is fine :)
[I'll take a look at the new version then]
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
@ 2017-04-28 11:04 ` Cornelia Huck
0 siblings, 0 replies; 40+ messages in thread
From: Cornelia Huck @ 2017-04-28 11:04 UTC (permalink / raw)
To: Dong Jia Shi
Cc: Alex Williamson, kvm, linux-s390, qemu-devel, renxiaof,
borntraeger, agraf
On Wed, 26 Apr 2017 16:49:20 +0800
Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> wrote:
> * Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> [2017-04-25 13:15:19 +0800]:
>
> > * Alex Williamson <alex.williamson@redhat.com> [2017-04-24 16:56:28 -0600]:
> >
> > [...]
> > > > > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
> > > > > new file mode 100644
> > > > > index 0000000..c491bee
> > > > > --- /dev/null
> > > > > +++ b/hw/vfio/ccw.c
> > > > > @@ -0,0 +1,207 @@
> > > > > +/*
> > > > > + * vfio based subchannel assignment support
> > > > > + *
> > > > > + * Copyright 2017 IBM Corp.
> > > > > + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> > > > > + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> > > > > + * Pierre Morel <pmorel@linux.vnet.ibm.com>
> > > > > + *
> > > > > + * This work is licensed under the terms of the GNU GPL, version 2 or(at
> > > > > + * your option) any version. See the COPYING file in the top-level
> > > > > + * directory.
> > > > > + */
> > > > > +
> > > > > +#include <linux/vfio.h>
> > > > > +#include <sys/ioctl.h>
> > > > > +
> > > > > +#include "qemu/osdep.h"
> > > > > +#include "qapi/error.h"
> > > > > +#include "hw/sysbus.h"
> > > > > +#include "hw/vfio/vfio.h"
> > > > > +#include "hw/vfio/vfio-common.h"
> > > > > +#include "hw/s390x/s390-ccw.h"
> > > > > +#include "hw/s390x/ccw-device.h"
> > > > > +
> > > > > +#define TYPE_VFIO_CCW "vfio-ccw"
> > > > > +typedef struct VFIOCCWDevice {
> > > > > + S390CCWDevice cdev;
> > > > > + VFIODevice vdev;
> > > > > +} VFIOCCWDevice;
> > > > > +
> > > > > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
> > > > > +{
> > > > > + vdev->needs_reset = false;
> > > > > +}
> > > > > +
> > > > > +/*
> > > > > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for
> > >
> > > One more:
> > >
> > > s/operationis/operations/
> > >
> > Ok.
> >
>
> Hi Conny,
>
> I have pulled your cohuck-qemu/s390-next branch, and prepared a new
> patch set with all of these problems fixed directly on the coressponding
> commits on it. Fine to send out the new version as that?
>
> Or I should rebase them against the latest master branch?
As I currently don't have things in my next branch that should interact
with your changes, either is fine :)
[I'll take a look at the new version then]
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [Qemu-devel] [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver
2017-04-28 11:04 ` [Qemu-devel] " Cornelia Huck
(?)
@ 2017-04-28 13:12 ` Dong Jia Shi
-1 siblings, 0 replies; 40+ messages in thread
From: Dong Jia Shi @ 2017-04-28 13:12 UTC (permalink / raw)
To: Cornelia Huck
Cc: Dong Jia Shi, Alex Williamson, kvm, linux-s390, qemu-devel,
renxiaof, borntraeger, agraf
* Cornelia Huck <cornelia.huck@de.ibm.com> [2017-04-28 13:04:07 +0200]:
> On Wed, 26 Apr 2017 16:49:20 +0800
> Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> wrote:
>
> > * Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> [2017-04-25 13:15:19 +0800]:
> >
> > > * Alex Williamson <alex.williamson@redhat.com> [2017-04-24 16:56:28 -0600]:
> > >
> > > [...]
> > > > > > diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
> > > > > > new file mode 100644
> > > > > > index 0000000..c491bee
> > > > > > --- /dev/null
> > > > > > +++ b/hw/vfio/ccw.c
> > > > > > @@ -0,0 +1,207 @@
> > > > > > +/*
> > > > > > + * vfio based subchannel assignment support
> > > > > > + *
> > > > > > + * Copyright 2017 IBM Corp.
> > > > > > + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> > > > > > + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> > > > > > + * Pierre Morel <pmorel@linux.vnet.ibm.com>
> > > > > > + *
> > > > > > + * This work is licensed under the terms of the GNU GPL, version 2 or(at
> > > > > > + * your option) any version. See the COPYING file in the top-level
> > > > > > + * directory.
> > > > > > + */
> > > > > > +
> > > > > > +#include <linux/vfio.h>
> > > > > > +#include <sys/ioctl.h>
> > > > > > +
> > > > > > +#include "qemu/osdep.h"
> > > > > > +#include "qapi/error.h"
> > > > > > +#include "hw/sysbus.h"
> > > > > > +#include "hw/vfio/vfio.h"
> > > > > > +#include "hw/vfio/vfio-common.h"
> > > > > > +#include "hw/s390x/s390-ccw.h"
> > > > > > +#include "hw/s390x/ccw-device.h"
> > > > > > +
> > > > > > +#define TYPE_VFIO_CCW "vfio-ccw"
> > > > > > +typedef struct VFIOCCWDevice {
> > > > > > + S390CCWDevice cdev;
> > > > > > + VFIODevice vdev;
> > > > > > +} VFIOCCWDevice;
> > > > > > +
> > > > > > +static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
> > > > > > +{
> > > > > > + vdev->needs_reset = false;
> > > > > > +}
> > > > > > +
> > > > > > +/*
> > > > > > + * We don't need vfio_hot_reset_multi and vfio_eoi operationis for
> > > >
> > > > One more:
> > > >
> > > > s/operationis/operations/
> > > >
> > > Ok.
> > >
> >
> > Hi Conny,
> >
> > I have pulled your cohuck-qemu/s390-next branch, and prepared a new
> > patch set with all of these problems fixed directly on the coressponding
> > commits on it. Fine to send out the new version as that?
> >
> > Or I should rebase them against the latest master branch?
>
> As I currently don't have things in my next branch that should interact
> with your changes, either is fine :)
Thanks! :>
I used your branch as the code base and just sent out the v6 patches.
>
> [I'll take a look at the new version then]
--
Dong Jia Shi
^ permalink raw reply [flat|nested] 40+ messages in thread
end of thread, other threads:[~2017-04-28 13:12 UTC | newest]
Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-12 5:21 [PATCH v5 00/13] basic channel IO passthrough infrastructure based on vfio Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 01/13] update-linux-headers: update for vfio-ccw Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 02/13] vfio: linux-headers " Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 03/13] s390x/css: add s390-squash-mcss machine option Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 04/13] s390x/css: realize css_sch_build_schib Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 05/13] s390x/css: realize css_create_sch Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 06/13] s390x/css: device support for s390-ccw passthrough Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-24 22:52 ` Alex Williamson
2017-04-24 22:52 ` [Qemu-devel] " Alex Williamson
[not found] ` <20170425021022.GE31848@bjsdjshi@linux.vnet.ibm.com>
[not found] ` <20170424201618.0d3ffd81@w520.home>
2017-04-25 3:32 ` Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 07/13] vfio/ccw: vfio based subchannel passthrough driver Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-24 22:43 ` Alex Williamson
2017-04-24 22:43 ` [Qemu-devel] " Alex Williamson
2017-04-24 22:56 ` Alex Williamson
2017-04-24 22:56 ` [Qemu-devel] " Alex Williamson
2017-04-25 5:15 ` Dong Jia Shi
2017-04-26 8:49 ` Dong Jia Shi
2017-04-28 11:04 ` Cornelia Huck
2017-04-28 11:04 ` [Qemu-devel] " Cornelia Huck
2017-04-28 13:12 ` Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 08/13] vfio/ccw: get io region info Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 09/13] vfio/ccw: get irqs info and set the eventfd fd Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 10/13] s390x/css: introduce and realize ccw-request callback Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 11/13] s390x/css: ccw translation infrastructure Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 12/13] vfio/ccw: update sense data if a unit check is pending Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
2017-04-12 5:21 ` [PATCH v5 13/13] MAINTAINERS: Add vfio-ccw maintainer Dong Jia Shi
2017-04-12 5:21 ` [Qemu-devel] " Dong Jia Shi
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.