[Qemu-devel] [RFC] s390: virtual channel subsystem and new virtio transport.

2012-08-07 Thread Cornelia Huck
Hi,

I've been working on a new virtio transport for s390 replacing the
existing s390-virtio transport. Patches to Linux, qemu and the virtio
spec will follow.


Why?

s390-virtio is quite limited in the number of supported devices (all
related structures need to fit into a single specially mapped page),
and does not support hotunplug. It is also completely dissimilar to
other devices on s390.


What's the alternative?

The classic method of discovering and addressing devices on s390 is via
channel I/O. Devices are accessed through subchannels and driven via
control units. A set of instructions operates on subchannels and allows
the operating system to send channel programs to the control
unit/device. Hot(un)plug of devices is reported via channel reports.

This method of accessing devices is well architectured and supported by
every s390 operating system (for Linux, the common I/O layer under
drivers/s390/cio handles the non device-specific work).

More information about channel I/O can be found in the z/Architecture
Principles of Operation (SA22-7832), chapter 13 ff. Also of interest
might be Common I/O-Device Commands and Self-Description (SA22-7204).

My patches implement support for virtual subchannels in kvm/s390
(Linux) and qemu (!kvm).


How does this tie in with virtio?

virtio devices in the host show up with a special (architectured)
control unit type (0x3832). The type (block,...) of the virtio device
is reflected in the control unit model. All virtual subchannels/devices
are in a special virtual channel subsystem (architectured id 0xfe).

For setting up virtqueues etc., a set of channel commands has been
defined for the virtio control unit type. Setting up thus works
completely through channel programs.

Guest -> host notification is implemented through normal I/O
interrupts; host -> guest notification is done via a new subcode to the
kvm diagnose (hypercall).

Host support for virtio-ccw is implemented in qemu.


How does this look in action?

The Linux guest looks like a normal s390 Linux guest with some channel
devices:

[root@localhost ~]# lscss
Device   Subchan.  DevType CU Type Use  PIM PAM POM  CHPIDs
--
0.0. 0.0.  /00 3832/01 yes  80  80  ff     
0.0.0815 0.0.0001  /00 3832/02 yes  80  80  ff     
0.0. 0.0.0002  /00 3832/03 yes  80  80  ff     
0.1.abcd 0.1.  /00 3832/05 yes  80  80  ff     

[root@localhost ~]# lschp
CHPID  Vary  Cfg.  Type  Cmg  Shared  PCHID

0.00   1 - 32-0   -


How can you try this out?

The patches should apply on top of kvm-next (Linux) resp. qemu head.

qemu device drivers are called virtio-xxx-ccw, the default machine type
is s390-ccw(-virtio).

You can specify an optional device id with the 'devno' property:

-device virtio-balloon-ccw,devno=fe.1.abcd

Note that the virtual channel subsystem id 0xfe needs to be specified;
in the guest, the devices will show in the default channel subsystem
(0x00).


Feedback welcome!

Cornelia




[Qemu-devel] [PATCH 2/7] s390/kvm: Add support for machine checks.

2012-08-07 Thread Cornelia Huck
Add support for injecting machine checks (only repressible
conditions for now).

This is a bit more involved than I/O interrupts, for these reasons:

- Machine checks come in both floating and cpu varieties.
- We don't have a bit for machine checks enabling, but have to use
  a roundabout approach with trapping PSW changing instructions and
  watching for opened machine checks.

Signed-off-by: Cornelia Huck 
---
 arch/s390/include/asm/kvm_host.h |   8 +++
 arch/s390/kvm/intercept.c|   2 +
 arch/s390/kvm/interrupt.c| 111 
 arch/s390/kvm/kvm-s390.h |   3 +
 arch/s390/kvm/priv.c | 133 +++
 arch/s390/kvm/trace-s390.h   |   6 +-
 include/linux/kvm.h  |   1 +
 7 files changed, 261 insertions(+), 3 deletions(-)

diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index e47f697..556774d 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -77,8 +77,10 @@ struct kvm_s390_sie_block {
__u8reserved40[4];  /* 0x0040 */
 #define LCTL_CR0   0x8000
 #define LCTL_CR6   0x0200
+#define LCTL_CR14  0x0002
__u16   lctl;   /* 0x0044 */
__s16   icpua;  /* 0x0046 */
+#define ICTL_LPSW 0x0200
__u32   ictl;   /* 0x0048 */
__u32   eca;/* 0x004c */
__u8icptcode;   /* 0x0050 */
@@ -189,6 +191,11 @@ struct kvm_s390_emerg_info {
__u16 code;
 };
 
+struct kvm_s390_mchk_info {
+   __u64 cr14;
+   __u64 mcic;
+};
+
 struct kvm_s390_interrupt_info {
struct list_head list;
u64 type;
@@ -199,6 +206,7 @@ struct kvm_s390_interrupt_info {
struct kvm_s390_emerg_info emerg;
struct kvm_s390_extcall_info extcall;
struct kvm_s390_prefix_info prefix;
+   struct kvm_s390_mchk_info mchk;
};
 };
 
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 22798ec..ec1177f 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -106,10 +106,12 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
 
 static intercept_handler_t instruction_handlers[256] = {
[0x01] = kvm_s390_handle_01,
+   [0x82] = kvm_s390_handle_lpsw,
[0x83] = kvm_s390_handle_diag,
[0xae] = kvm_s390_handle_sigp,
[0xb2] = kvm_s390_handle_b2,
[0xb7] = handle_lctl,
+   [0xb9] = kvm_s390_handle_b9,
[0xe5] = kvm_s390_handle_e5,
[0xeb] = handle_lctlg,
 };
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 1dccfe7..edc065f 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -41,6 +41,11 @@ static int psw_ioint_disabled(struct kvm_vcpu *vcpu)
return !(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_IO);
 }
 
+static int psw_mchk_disabled(struct kvm_vcpu *vcpu)
+{
+   return !(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_MCHECK);
+}
+
 static int psw_interrupts_disabled(struct kvm_vcpu *vcpu)
 {
if ((vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PER) ||
@@ -82,6 +87,12 @@ static int __interrupt_is_deliverable(struct kvm_vcpu *vcpu,
case KVM_S390_SIGP_SET_PREFIX:
case KVM_S390_RESTART:
return 1;
+   case KVM_S390_MCHK:
+   if (psw_mchk_disabled(vcpu))
+   return 0;
+   if (vcpu->arch.sie_block->gcr[14] & inti->mchk.cr14)
+   return 1;
+   return 0;
default:
if (is_ioint(inti->type)) {
if (psw_ioint_disabled(vcpu))
@@ -119,6 +130,7 @@ static void __reset_intercept_indicators(struct kvm_vcpu 
*vcpu)
CPUSTAT_IO_INT | CPUSTAT_EXT_INT | CPUSTAT_STOP_INT,
&vcpu->arch.sie_block->cpuflags);
vcpu->arch.sie_block->lctl = 0x;
+   vcpu->arch.sie_block->ictl &= ~ICTL_LPSW;
 }
 
 static void __set_cpuflag(struct kvm_vcpu *vcpu, u32 flag)
@@ -142,6 +154,12 @@ static void __set_intercept_indicator(struct kvm_vcpu 
*vcpu,
case KVM_S390_SIGP_STOP:
__set_cpuflag(vcpu, CPUSTAT_STOP_INT);
break;
+   case KVM_S390_MCHK:
+   if (psw_mchk_disabled(vcpu))
+   vcpu->arch.sie_block->ictl |= ICTL_LPSW;
+   else
+   vcpu->arch.sie_block->lctl |= LCTL_CR14;
+   break;
default:
if (is_ioint(inti->type)) {
if (psw_ioint_disabled(vcpu))
@@ -330,6 +348,32 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
exception = 1;
break;
 
+   case KVM_S390_MCHK:
+   VCPU_EVENT(vcpu, 4, "interrupt: machine check mcic=%llx&quo

[Qemu-devel] [PATCH] virtio-spec: Add virtio-ccw spec.

2012-08-07 Thread Cornelia Huck
Add specifications for the new s390 specific virtio-ccw transport.

Signed-off-by: Cornelia Huck 
---
 virtio-spec.lyx |  433 +++
 1 files changed, 433 insertions(+), 0 deletions(-)

diff --git a/virtio-spec.lyx b/virtio-spec.lyx
index 7a073f4..5223380 100644
--- a/virtio-spec.lyx
+++ b/virtio-spec.lyx
@@ -57,6 +57,7 @@
 \html_css_as_file 0
 \html_be_strict false
 \author -608949062 "Rusty Russell,,," 
+\author -385801441 "Cornelia Huck" cornelia.h...@de.ibm.com
 \author 1531152142 "Paolo Bonzini,,," 
 \end_header
 
@@ -9350,6 +9351,438 @@ tatus register description is asserted.
  After the interrupt is handled, the driver must acknowledge it by writing
  a bit mask corresponding to the serviced interrupt to the InterruptACK
  register.
+\change_inserted -385801441 1343732742
+
+\end_layout
+
+\begin_layout Chapter*
+
+\change_inserted -385801441 1343732726
+Appendix Y: virtio-ccw
+\end_layout
+
+\begin_layout Standard
+
+\change_inserted -385801441 1343732726
+S/390 based virtual machines support neither PCI nor MMIO, so a different
+ transport is needed there.
+\end_layout
+
+\begin_layout Standard
+
+\change_inserted -385801441 1343732726
+The old s390-virtio mechanism used a special page mapped above the guest's
+ memory and several diagnose calls (hypercalls); it does have some drawbacks,
+ however, like a rather limited number of devices and very restricted hotplug
+ support.
+ Moreover, device discovery and operation differ from other environments
+ on the S/390 platform.
+\end_layout
+
+\begin_layout Standard
+
+\change_inserted -385801441 1343732726
+virtio-ccw uses the standard channel I/O based mechanism used for the majority
+ of devices on S/390.
+ A virtual channel device with a special control unit type acts as proxy
+ to the virtio device (similar to the way virtio-pci uses a PCI device)
+ and configuration and operation of the virtio device is accomplished (mostly)
+ via channel commands.
+ This means virtio devices are discoverable via standard operating system
+ algorithms, and adding virtio support is mainly a question of supporting
+ a new control unit type.
+\end_layout
+
+\begin_layout Subsection*
+
+\change_inserted -385801441 1343732726
+Basic Concepts
+\end_layout
+
+\begin_layout Standard
+
+\change_inserted -385801441 1343732817
+As a proxy device, virtio-ccw uses a channel-attached I/O control unit with
+ a special control unit type (0x3832) and a control unit model corresponding
+ to the attached virtio device's subsystem device ID, accessed via a virtual
+ I/O subchannel and a virtual channel path of type 0x32.
+ This proxy device is discoverable via normal channel subsystem device 
discorver
+y (usually a STORE SUBCHANNEL loop) and answers to the basic channel commands,
+ most importantly SENSE ID.
+\end_layout
+
+\begin_layout Standard
+
+\change_inserted -385801441 1343732726
+In addition to the basic channel commands, virtio-ccw defines a set of channel
+ commands related to configuration and operation of virtio:
+\end_layout
+
+\begin_layout LyX-Code
+
+\change_inserted -385801441 1343732726
+\begin_inset listings
+inline false
+status open
+
+\begin_layout LyX-Code
+
+\change_inserted -385801441 1343732726
+
+#define CCW_CMD_SET_VQ 0x13
+\end_layout
+
+\begin_layout LyX-Code
+
+\change_inserted -385801441 1343732726
+
+#define CCW_CMD_VDEV_RESET 0x33
+\end_layout
+
+\begin_layout LyX-Code
+
+\change_inserted -385801441 1343732726
+
+#define CCW_CMD_SET_IND 0x43
+\end_layout
+
+\begin_layout LyX-Code
+
+\change_inserted -385801441 1343732726
+
+#define CCW_CMD_READ_FEAT 0x12
+\end_layout
+
+\begin_layout LyX-Code
+
+\change_inserted -385801441 1343732726
+
+#define CCW_CMD_WRITE_FEAT 0x11
+\end_layout
+
+\begin_layout LyX-Code
+
+\change_inserted -385801441 1343732726
+
+#define CCW_CMD_READ_CONF 0x22 
+\end_layout
+
+\begin_layout LyX-Code
+
+\change_inserted -385801441 1343732726
+
+#define CCW_CMD_WRITE_CONF 0x21
+\end_layout
+
+\begin_layout LyX-Code
+
+\change_inserted -385801441 1343732726
+
+#define CCW_CMD_WRITE_STATUS 0x31
+\end_layout
+
+\begin_layout LyX-Code
+
+\change_inserted -385801441 1343732726
+
+#define CCW_CMD_READ_VQ_CONF 0x32
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsection*
+
+\change_inserted -385801441 1343732726
+Device Initialization
+\end_layout
+
+\begin_layout Standard
+
+\change_inserted -385801441 1343732726
+virtio-ccw uses several channel commands to set up a device.
+\end_layout
+
+\begin_layout Subsubsection*
+
+\change_inserted -385801441 1343732726
+Configuring a Virtqueue
+\end_layout
+
+\begin_layout Standard
+
+\change_inserted -385801441 1343732726
+CCW_CMD_READ_VQ_CONF is issued by the guest to obtain information about
+ a queue.
+ It uses the following structure for communicating:
+\end_layout
+
+\begin_layout LyX-Code
+
+\change_inserted -385801441 1343732726
+\begin_inset listings
+inline fals

[Qemu-devel] [RFC PATCH] Update virtio spec for virtio-ccw.

2012-08-07 Thread Cornelia Huck
Hi,

here's an update to the virtio spec describing the basics of
the virtio-ccw mechanism.

Cornelia Huck (1):
  virtio-spec: Add virtio-ccw spec.

 virtio-spec.lyx |  433 +++
 1 files changed, 433 insertions(+), 0 deletions(-)

-- 
1.7.5.4




[Qemu-devel] [PATCH 5/7] s390: Make some css-related structures usable by non-cio code.

2012-08-07 Thread Cornelia Huck
kvm will need to use some css-related structures (pmcw, schib, orb),
so let's move the definitions from drivers/s390/cio/ to include/asm/.

Signed-off-by: Cornelia Huck 
---
 arch/s390/include/asm/orb.h   | 69 +++
 arch/s390/include/asm/schib.h | 52 
 drivers/s390/cio/cio.h| 46 +
 drivers/s390/cio/io_sch.h |  2 +-
 drivers/s390/cio/ioasm.h  |  2 +-
 drivers/s390/cio/orb.h| 67 -
 6 files changed, 124 insertions(+), 114 deletions(-)
 create mode 100644 arch/s390/include/asm/orb.h
 create mode 100644 arch/s390/include/asm/schib.h
 delete mode 100644 drivers/s390/cio/orb.h

diff --git a/arch/s390/include/asm/orb.h b/arch/s390/include/asm/orb.h
new file mode 100644
index 000..ca5d255
--- /dev/null
+++ b/arch/s390/include/asm/orb.h
@@ -0,0 +1,69 @@
+/*
+ * Orb related data structures.
+ *
+ * Copyright IBM Corp. 2007, 2011
+ *
+ * Author(s): Cornelia Huck 
+ *   Peter Oberparleiter 
+ *   Sebastian Ott 
+ */
+
+#ifndef S390_ORB_H
+#define S390_ORB_H
+
+#include 
+
+/*
+ * Command-mode operation request block
+ */
+struct cmd_orb {
+   u32 intparm;/* interruption parameter */
+   u32 key:4;  /* flags, like key, suspend control, etc. */
+   u32 spnd:1; /* suspend control */
+   u32 res1:1; /* reserved */
+   u32 mod:1;  /* modification control */
+   u32 sync:1; /* synchronize control */
+   u32 fmt:1;  /* format control */
+   u32 pfch:1; /* prefetch control */
+   u32 isic:1; /* initial-status-interruption control */
+   u32 alcc:1; /* address-limit-checking control */
+   u32 ssic:1; /* suppress-suspended-interr. control */
+   u32 res2:1; /* reserved */
+   u32 c64:1;  /* IDAW/QDIO 64 bit control  */
+   u32 i2k:1;  /* IDAW 2/4kB block size control */
+   u32 lpm:8;  /* logical path mask */
+   u32 ils:1;  /* incorrect length */
+   u32 zero:6; /* reserved zeros */
+   u32 orbx:1; /* ORB extension control */
+   u32 cpa;/* channel program address */
+}  __packed __aligned(4);
+
+/*
+ * Transport-mode operation request block
+ */
+struct tm_orb {
+   u32 intparm;
+   u32 key:4;
+   u32:9;
+   u32 b:1;
+   u32:2;
+   u32 lpm:8;
+   u32:7;
+   u32 x:1;
+   u32 tcw;
+   u32 prio:8;
+   u32:8;
+   u32 rsvpgm:8;
+   u32:8;
+   u32:32;
+   u32:32;
+   u32:32;
+   u32:32;
+}  __packed __aligned(4);
+
+union orb {
+   struct cmd_orb cmd;
+   struct tm_orb tm;
+}  __packed __aligned(4);
+
+#endif /* S390_ORB_H */
diff --git a/arch/s390/include/asm/schib.h b/arch/s390/include/asm/schib.h
new file mode 100644
index 000..87d7403
--- /dev/null
+++ b/arch/s390/include/asm/schib.h
@@ -0,0 +1,52 @@
+#ifndef _ASM_S390_SCHIB_H_
+#define _ASM_S390_SCHIB_H_
+
+#include 
+
+#include 
+/*
+ * path management control word
+ */
+struct pmcw {
+   u32 intparm;/* interruption parameter */
+   u32 qf:1;   /* qdio facility */
+   u32 w:1;
+   u32 isc:3;  /* interruption sublass */
+   u32 res5:3; /* reserved zeros */
+   u32 ena:1;  /* enabled */
+   u32 lm:2;   /* limit mode */
+   u32 mme:2;  /* measurement-mode enable */
+   u32 mp:1;   /* multipath mode */
+   u32 tf:1;   /* timing facility */
+   u32 dnv:1;  /* device number valid */
+   u32 dev:16; /* device number */
+   u8  lpm;/* logical path mask */
+   u8  pnom;   /* path not operational mask */
+   u8  lpum;   /* last path used mask */
+   u8  pim;/* path installed mask */
+   u16 mbi;/* measurement-block index */
+   u8  pom;/* path operational mask */
+   u8  pam;/* path available mask */
+   u8  chpid[8];   /* CHPID 0-7 (if available) */
+   u32 unused1:8;  /* reserved zeros */
+   u32 st:3;   /* subchannel type */
+   u32 unused2:18; /* reserved zeros */
+   u32 mbfc:1; /* measurement block format control */
+   u32 xmwme:1;/* extended measurement word mode enable */
+   u32 csense:1;   /* concurrent sense; can be enabled ...*/
+   /*  ... per MSCH, however, if facility */
+   /*  ... is not installed, this results */
+   /*  ... in an operand exception.   */
+} __packed;
+
+/*
+ * subchannel information block
+ */
+struct schib {
+   struct pmcw pmcw;/* path management control word */
+   union scsw scsw; /* subchannel status word */
+   

[Qemu-devel] [PATCH 4/4] s390/kvm: Split out early console code.

2012-08-07 Thread Cornelia Huck
This code is transport agnostic and can be used by both the legacy
virtio code and virtio_ccw.

Signed-off-by: Cornelia Huck 
---
 drivers/s390/kvm/Makefile   |  2 +-
 drivers/s390/kvm/early_printk.c | 42 +
 drivers/s390/kvm/kvm_virtio.c   | 29 ++--
 drivers/s390/kvm/virtio_ccw.c   |  1 -
 4 files changed, 45 insertions(+), 29 deletions(-)
 create mode 100644 drivers/s390/kvm/early_printk.c

diff --git a/drivers/s390/kvm/Makefile b/drivers/s390/kvm/Makefile
index 241891a..a3c8fc4 100644
--- a/drivers/s390/kvm/Makefile
+++ b/drivers/s390/kvm/Makefile
@@ -6,4 +6,4 @@
 # it under the terms of the GNU General Public License (version 2 only)
 # as published by the Free Software Foundation.
 
-obj-$(CONFIG_S390_GUEST) += kvm_virtio.o virtio_ccw.o
+obj-$(CONFIG_S390_GUEST) += kvm_virtio.o early_printk.o virtio_ccw.o
diff --git a/drivers/s390/kvm/early_printk.c b/drivers/s390/kvm/early_printk.c
new file mode 100644
index 000..7831530
--- /dev/null
+++ b/drivers/s390/kvm/early_printk.c
@@ -0,0 +1,42 @@
+/*
+ * early_printk.c - code for early console output with virtio_console
+ * split off from kvm_virtio.c
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * 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): Christian Borntraeger 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static __init int early_put_chars(u32 vtermno, const char *buf, int count)
+{
+   char scratch[17];
+   unsigned int len = count;
+
+   if (len > sizeof(scratch) - 1)
+   len = sizeof(scratch) - 1;
+   scratch[len] = '\0';
+   memcpy(scratch, buf, len);
+   kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, __pa(scratch));
+   return len;
+}
+
+static int __init s390_virtio_console_init(void)
+{
+   if (sclp_has_vt220() || sclp_has_linemode())
+   return -ENODEV;
+   return virtio_cons_early_init(early_put_chars);
+}
+console_initcall(s390_virtio_console_init);
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 408447c..c693548 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -25,9 +24,9 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
+#include 
 
 #define VIRTIO_SUBCODE_64 0x0D00
 
@@ -461,8 +460,7 @@ static int __init kvm_devices_init(void)
if (test_devices_support() < 0) {
vmem_remove_mapping(real_memory_size, PAGE_SIZE);
root_device_unregister(kvm_root);
-   /* No error. */
-   return 0;
+   return -ENODEV;
}
 
INIT_WORK(&hotplug_work, hotplug_devices);
@@ -474,29 +472,6 @@ static int __init kvm_devices_init(void)
return 0;
 }
 
-/* code for early console output with virtio_console */
-static __init int early_put_chars(u32 vtermno, const char *buf, int count)
-{
-   char scratch[17];
-   unsigned int len = count;
-
-   if (len > sizeof(scratch) - 1)
-   len = sizeof(scratch) - 1;
-   scratch[len] = '\0';
-   memcpy(scratch, buf, len);
-   kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, __pa(scratch));
-   return len;
-}
-
-static int __init s390_virtio_console_init(void)
-{
-   if (sclp_has_vt220() || sclp_has_linemode())
-   return -ENODEV;
-   return virtio_cons_early_init(early_put_chars);
-}
-console_initcall(s390_virtio_console_init);
-
-
 /*
  * We do this after core stuff, but before the drivers.
  */
diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c
index df0f994..c3d07db 100644
--- a/drivers/s390/kvm/virtio_ccw.c
+++ b/drivers/s390/kvm/virtio_ccw.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
-- 
1.7.11.4




[Qemu-devel] [PATCH 1/5] Update headers for upcoming s390 changes.

2012-08-07 Thread Cornelia Huck
Signed-off-by: Cornelia Huck 
---
 linux-headers/asm-s390/kvm.h  |  2 +-
 linux-headers/asm-s390/kvm_para.h |  2 +-
 linux-headers/linux/kvm.h | 63 +++
 3 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index bdcbe0f..d25da59 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -1,7 +1,7 @@
 #ifndef __LINUX_KVM_S390_H
 #define __LINUX_KVM_S390_H
 /*
- * asm-s390/kvm.h - KVM s390 specific structures and definitions
+ * KVM s390 specific structures and definitions
  *
  * Copyright IBM Corp. 2008
  *
diff --git a/linux-headers/asm-s390/kvm_para.h 
b/linux-headers/asm-s390/kvm_para.h
index 8e2dd67..870051f 100644
--- a/linux-headers/asm-s390/kvm_para.h
+++ b/linux-headers/asm-s390/kvm_para.h
@@ -1,5 +1,5 @@
 /*
- * asm-s390/kvm_para.h - definition for paravirtual devices on s390
+ * definition for paravirtual devices on s390
  *
  * Copyright IBM Corp. 2008
  *
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 5a9d4e3..a813a1c 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -163,6 +163,7 @@ struct kvm_pit_config {
 #define KVM_EXIT_OSI  18
 #define KVM_EXIT_PAPR_HCALL  19
 #define KVM_EXIT_S390_UCONTROL   20
+#define KVM_EXIT_S390_SCH_IO  21
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 #define KVM_INTERNAL_ERROR_EMULATION 1
@@ -276,6 +277,20 @@ struct kvm_run {
__u64 ret;
__u64 args[9];
} papr_hcall;
+   /* KVM_EXIT_S390_SCH_IO */
+   struct {
+   __u32 sch_id;
+#define SCH_DO_CSCH 0
+#define SCH_DO_HSCH 1
+#define SCH_DO_SSCH 2
+#define SCH_DO_RSCH 3
+#define SCH_DO_XSCH 4
+   __u8 func;
+   __u8 pad;
+   __u64 orb;
+   __u32 scsw[3];
+   __u32 pmcw[7];
+   } s390_sch_io;
/* Fix the size of the union. */
char padding[256];
};
@@ -388,10 +403,17 @@ struct kvm_s390_psw {
 #define KVM_S390_PROGRAM_INT   0xfffe0001u
 #define KVM_S390_SIGP_SET_PREFIX   0xfffe0002u
 #define KVM_S390_RESTART   0xfffe0003u
+#define KVM_S390_MCHK  0xfffe1000u
 #define KVM_S390_INT_VIRTIO0x2603u
 #define KVM_S390_INT_SERVICE   0x2401u
 #define KVM_S390_INT_EMERGENCY 0x1201u
 #define KVM_S390_INT_EXTERNAL_CALL 0x1202u
+#define KVM_S390_INT_IO(ai,cssid,ssid,schid)   \
+   (((schid)) |   \
+((ssid) << 16) |  \
+((cssid) << 18) | \
+((ai) << 26))
+
 
 struct kvm_s390_interrupt {
__u32 type;
@@ -473,6 +495,39 @@ struct kvm_ppc_smmu_info {
struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ];
 };
 
+/* for KVM_S390_CSS_NOTIFY */
+struct kvm_css_notify {
+   __u8 cssid;
+   __u8 ssid;
+   __u16 schid;
+   __u32 scsw[3];
+   __u32 pmcw[7];
+   __u8 sense_data[32];
+   __u8 unsolicited;
+   __u8 func;
+};
+
+/* for KVM_S390_CCW_HOTPLUG */
+struct kvm_s390_sch_info {
+   __u8 cssid;
+   __u8 ssid;
+   __u16 schid;
+   __u16 devno;
+   __u32 schib[12];
+   int hotplugged;
+   int add;
+   int virtual;
+};
+
+/* for KVM_S390_CHP_HOTPLUG */
+struct kvm_s390_chp_info {
+   __u8 cssid;
+   __u8 chpid;
+   __u8 type;
+   int add;
+   int virtual;
+};
+
 #define KVMIO 0xAE
 
 /* machine type bits, to be used as argument to KVM_CREATE_VM */
@@ -617,6 +672,8 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_SIGNAL_MSI 77
 #define KVM_CAP_PPC_GET_SMMU_INFO 78
 #define KVM_CAP_S390_COW 79
+#define KVM_CAP_PPC_ALLOC_HTAB 80
+#define KVM_CAP_S390_CSS_SUPPORT 81
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -828,6 +885,12 @@ struct kvm_s390_ucas_mapping {
 #define KVM_SIGNAL_MSI_IOW(KVMIO,  0xa5, struct kvm_msi)
 /* Available with KVM_CAP_PPC_GET_SMMU_INFO */
 #define KVM_PPC_GET_SMMU_INFO_IOR(KVMIO,  0xa6, struct kvm_ppc_smmu_info)
+/* Available with KVM_CAP_PPC_ALLOC_HTAB */
+#define KVM_PPC_ALLOCATE_HTAB_IOWR(KVMIO, 0xa7, __u32)
+/* Available with KVM_CAP_S390_CSS_SUPPORT */
+#define KVM_S390_CSS_NOTIFY   _IOW(KVMIO, 0xae, struct kvm_css_notify)
+#define KVM_S390_CCW_HOTPLUG  _IOW(KVMIO, 0xab, struct kvm_s390_sch_info)
+#define KVM_S390_CHP_HOTPLUG  _IOW(KVMIO, 0xac, struct kvm_s390_chp_info)
 
 /*
  * ioctls for vcpu fds
-- 
1.7.11.4




[Qemu-devel] [PATCH 4/7] s390: Move css limits from drivers/s390/cio/ to include/asm/.

2012-08-07 Thread Cornelia Huck
There's no need to keep __MAX_SUBCHANNEL and __MAX_SSID private to the
common I/O layer when __MAX_CSSID is usable by everybody.

Signed-off-by: Cornelia Huck 
---
 arch/s390/include/asm/cio.h | 2 ++
 drivers/s390/cio/css.h  | 3 ---
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h
index 77043aa..9b6cc82 100644
--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -9,6 +9,8 @@
 
 #define LPM_ANYPATH 0xff
 #define __MAX_CSSID 0
+#define __MAX_SUBCHANNEL 65535
+#define __MAX_SSID 3
 
 #include 
 
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 33bb4d8..4af3dfe 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -112,9 +112,6 @@ extern int for_each_subchannel(int(*fn)(struct 
subchannel_id, void *), void *);
 extern void css_reiterate_subchannels(void);
 void css_update_ssd_info(struct subchannel *sch);
 
-#define __MAX_SUBCHANNEL 65535
-#define __MAX_SSID 3
-
 struct channel_subsystem {
u8 cssid;
int valid;
-- 
1.7.11.4




[Qemu-devel] [RFC PATCH 0/7] s390: virtual css host support.

2012-08-07 Thread Cornelia Huck
Hi,

the following patches implement support for a virtual channel
subsystem in the host (virtio-ccw on the host is handled by
user space).

Patches 1 and 2 add support for injecting I/O interrupts and
(some) machine checks via the already existing mechanisms.
The most important parts are those handling interrupt delivery.

Patch 3 prepares for in-kernel handling of I/O instructions.

Patches 4 and 5 make it possible for kvm to re-use some css-related
definitions already used by the s390 common I/O layer.

Patch 6 introduces the interface to dynamically enable capabilities
already in use on ppc to s390.

Patch 7 (the big one) adds in-kernel implementations of most I/O
instructions (leaving out some facilities that were too complex and
are not currently needed; these can convieniently be marked as
not supported). Some operations (which are executed asynchronically
on real hardware) are outsourced to user space. This in-kernel
channel subsystem support can be enabled by user space via a new
capability.

Cornelia Huck (7):
  s390/kvm: Support for I/O interrupts.
  s390/kvm: Add support for machine checks.
  s390/kvm: In-kernel handling of I/O instructions.
  s390: Move css limits from drivers/s390/cio/ to include/asm/.
  s390: Make some css-related structures usable by non-cio code.
  s390/kvm: Base infrastructure for enabling capabilities.
  s390/kvm: In-kernel channel subsystem support.

 Documentation/virtual/kvm/api.txt | 129 +-
 arch/s390/include/asm/cio.h   |   2 +
 arch/s390/include/asm/kvm_host.h  |  58 +++
 arch/s390/include/asm/orb.h   |  69 +++
 arch/s390/include/asm/schib.h |  52 +++
 arch/s390/kvm/Makefile|   2 +-
 arch/s390/kvm/css.c   | 945 ++
 arch/s390/kvm/intercept.c |  22 +-
 arch/s390/kvm/interrupt.c | 337 --
 arch/s390/kvm/ioinst.c| 797 
 arch/s390/kvm/kvm-s390.c  |  61 +++
 arch/s390/kvm/kvm-s390.h  |  42 ++
 arch/s390/kvm/priv.c  | 194 +++-
 arch/s390/kvm/trace-s390.h|  73 ++-
 arch/s390/kvm/trace.h |  22 +
 drivers/s390/cio/cio.h|  46 +-
 drivers/s390/cio/css.h|   3 -
 drivers/s390/cio/io_sch.h |   2 +-
 drivers/s390/cio/ioasm.h  |   2 +-
 drivers/s390/cio/orb.h|  67 ---
 include/linux/kvm.h   |  60 +++
 include/trace/events/kvm.h|   2 +-
 virt/kvm/kvm_main.c   |   3 +-
 23 files changed, 2816 insertions(+), 174 deletions(-)
 create mode 100644 arch/s390/include/asm/orb.h
 create mode 100644 arch/s390/include/asm/schib.h
 create mode 100644 arch/s390/kvm/css.c
 create mode 100644 arch/s390/kvm/ioinst.c
 delete mode 100644 drivers/s390/cio/orb.h

-- 
1.7.11.4




[Qemu-devel] [PATCH 6/7] s390/kvm: Base infrastructure for enabling capabilities.

2012-08-07 Thread Cornelia Huck
Signed-off-by: Cornelia Huck 
---
 Documentation/virtual/kvm/api.txt |  2 +-
 arch/s390/kvm/kvm-s390.c  | 26 ++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index bf33aaa..140e7e2 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -909,7 +909,7 @@ documentation when it pops into existence).
 4.37 KVM_ENABLE_CAP
 
 Capability: KVM_CAP_ENABLE_CAP
-Architectures: ppc
+Architectures: ppc, s390
 Type: vcpu ioctl
 Parameters: struct kvm_enable_cap (in)
 Returns: 0 on success; -1 on error
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index e83df7f..4b0681c 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -140,6 +140,7 @@ int kvm_dev_ioctl_check_extension(long ext)
 #endif
case KVM_CAP_SYNC_REGS:
case KVM_CAP_ONE_REG:
+   case KVM_CAP_ENABLE_CAP:
r = 1;
break;
case KVM_CAP_NR_VCPUS:
@@ -807,6 +808,22 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, 
unsigned long addr)
return 0;
 }
 
+static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
+struct kvm_enable_cap *cap)
+{
+   int r;
+
+   if (cap->flags)
+   return -EINVAL;
+
+   switch (cap->cap) {
+   default:
+   r = -EINVAL;
+   break;
+   }
+   return r;
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp,
 unsigned int ioctl, unsigned long arg)
 {
@@ -893,6 +910,15 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
r = 0;
break;
}
+   case KVM_ENABLE_CAP:
+   {
+   struct kvm_enable_cap cap;
+   r = -EFAULT;
+   if (copy_from_user(&cap, argp, sizeof(cap)))
+   break;
+   r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap);
+   break;
+   }
default:
r = -ENOTTY;
}
-- 
1.7.11.4




[Qemu-devel] [PATCH 2/5] s390: Virtual channel subsystem support.

2012-08-07 Thread Cornelia Huck
Provide a mechanism for qemu to provide fully virtual subchannels to
the guest. In the KVM case, this relies on the kernel's css support.
The !KVM case is not yet supported.

Signed-off-by: Cornelia Huck 
---
 hw/s390x/Makefile.objs |   1 +
 hw/s390x/css.c | 440 +
 hw/s390x/css.h |  62 +++
 target-s390x/Makefile.objs |   2 +-
 target-s390x/cpu.h | 108 +++
 target-s390x/ioinst.c  |  38 
 target-s390x/ioinst.h  | 173 ++
 target-s390x/kvm.c | 101 +++
 8 files changed, 924 insertions(+), 1 deletion(-)
 create mode 100644 hw/s390x/css.c
 create mode 100644 hw/s390x/css.h
 create mode 100644 target-s390x/ioinst.c
 create mode 100644 target-s390x/ioinst.h

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index dcdcac8..93b41fb 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -1,3 +1,4 @@
 obj-y = s390-virtio-bus.o s390-virtio.o
 
 obj-y := $(addprefix ../,$(obj-y))
+obj-y += css.o
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
new file mode 100644
index 000..7941c44
--- /dev/null
+++ b/hw/s390x/css.c
@@ -0,0 +1,440 @@
+/*
+ * Channel subsystem base support.
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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-thread.h"
+#include "qemu-queue.h"
+#include 
+#include "kvm.h"
+#include "cpu.h"
+#include "ioinst.h"
+#include "css.h"
+
+struct chp_info {
+uint8_t in_use;
+uint8_t type;
+};
+
+static struct chp_info chpids[MAX_CSSID + 1][MAX_CHPID + 1];
+
+static css_subch_cb_func css_subch_cb;
+
+int css_set_subch_cb(css_subch_cb_func func)
+{
+if (func && css_subch_cb) {
+return -EBUSY;
+}
+css_subch_cb = func;
+return 0;
+}
+
+static void css_inject_io_interrupt(SubchDev *sch, uint8_t func)
+{
+s390_io_interrupt(sch->cssid, sch->ssid, sch->schid, 
&sch->curr_status.scsw,
+  &sch->curr_status.pmcw, &sch->sense_data, 0,
+  sch->curr_status.pmcw.isc, sch->curr_status.pmcw.intparm,
+  func);
+}
+
+void css_conditional_io_interrupt(SubchDev *sch)
+{
+s390_io_interrupt(sch->cssid, sch->ssid, sch->schid, 
&sch->curr_status.scsw,
+  &sch->curr_status.pmcw, &sch->sense_data, 1,
+  sch->curr_status.pmcw.isc, 
sch->curr_status.pmcw.intparm, 0);
+}
+
+static void sch_handle_clear_func(SubchDev *sch)
+{
+struct pmcw *p = &sch->curr_status.pmcw;
+struct scsw *s = &sch->curr_status.scsw;
+int path;
+
+/* Path management: In our simple css, we always choose the only path. */
+path = 0x80;
+
+/* Reset values prior to 'issueing the clear signal'. */
+p->lpum = 0;
+p->pom = 0xff;
+s->pno = 0;
+
+/* We always 'attempt to issue the clear signal', and we always succeed. */
+sch->orb = NULL;
+sch->channel_prog = NULL;
+sch->last_cmd = NULL;
+s->actl &= ~SCSW_ACTL_CLEAR_PEND;
+s->stctl |= SCSW_STCTL_STATUS_PEND;
+
+s->dstat = 0;
+s->cstat = 0;
+p->lpum = path;
+
+}
+
+static void sch_handle_halt_func(SubchDev *sch)
+{
+
+struct pmcw *p = &sch->curr_status.pmcw;
+struct scsw *s = &sch->curr_status.scsw;
+int path;
+
+/* Path management: In our simple css, we always choose the only path. */
+path = 0x80;
+
+/* We always 'attempt to issue the halt signal', and we always succeed. */
+sch->orb = NULL;
+sch->channel_prog = NULL;
+sch->last_cmd = NULL;
+s->actl &= ~SCSW_ACTL_HALT_PEND;
+s->stctl |= SCSW_STCTL_STATUS_PEND;
+
+if ((s->actl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) ||
+!((s->actl & SCSW_ACTL_START_PEND) ||
+  (s->actl & SCSW_ACTL_SUSP))) {
+s->dstat = SCSW_DSTAT_DEVICE_END;
+}
+s->cstat = 0;
+p->lpum = path;
+
+}
+
+static int css_interpret_ccw(SubchDev *sch, struct ccw1 *ccw)
+{
+int ret;
+bool check_len;
+int len;
+int i;
+
+if (!ccw) {
+return -EIO;
+}
+
+/* Check for invalid command codes. */
+if ((ccw->cmd_code & 0x0f) == 0) {
+return -EINVAL;
+}
+if (((ccw->cmd_code & 0x0f) == CCW_CMD_TIC) &&
+((ccw->cmd_code & 0xf0) != 0)) {
+return -EINVAL;
+}
+
+if (ccw->flags & CCW_FLAG_SUSPEND) {
+return -ERESTART;
+}
+
+check_len = !((ccw->flags & CCW_FLAG_SLI) && !(ccw->flags & CCW_FLAG_DC));
+
+/* Look at the command. */
+swit

[Qemu-devel] [PATCH 5/5] [HACK] Handle multiple virtio aliases.

2012-08-07 Thread Cornelia Huck
This patch enables using both virtio-xxx-s390 and virtio-xxx-ccw
by making the alias lookup code verify that a driver is actually
registered.

(Only included in order to allow testing of virtio-ccw; should be
replaced by cleaning up the virtio bus model.)

Not-signed-off-by: Cornelia Huck 
---
 blockdev.c|  6 +---
 hw/qdev-monitor.c | 85 +--
 vl.c  |  6 +---
 3 files changed, 53 insertions(+), 44 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 8669142..7a8eb27 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -559,11 +559,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
 case IF_VIRTIO:
 /* add virtio block device */
 opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0, NULL);
-if (arch_type == QEMU_ARCH_S390X) {
-qemu_opt_set(opts, "driver", "virtio-blk-s390");
-} else {
-qemu_opt_set(opts, "driver", "virtio-blk-pci");
-}
+qemu_opt_set(opts, "driver", "virtio-blk");
 qemu_opt_set(opts, "drive", dinfo->id);
 if (devaddr)
 qemu_opt_set(opts, "addr", devaddr);
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 79f7e6b..6178b83 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -118,9 +118,53 @@ static int set_property(const char *name, const char 
*value, void *opaque)
 return 0;
 }
 
-static const char *find_typename_by_alias(const char *alias)
+static BusState *qbus_find_recursive(BusState *bus, const char *name,
+ const char *bus_typename)
+{
+BusChild *kid;
+BusState *child, *ret;
+int match = 1;
+
+if (name && (strcmp(bus->name, name) != 0)) {
+match = 0;
+}
+if (bus_typename &&
+(strcmp(object_get_typename(OBJECT(bus)), bus_typename) != 0)) {
+match = 0;
+}
+if (match) {
+return bus;
+}
+
+QTAILQ_FOREACH(kid, &bus->children, sibling) {
+DeviceState *dev = kid->child;
+QLIST_FOREACH(child, &dev->child_bus, sibling) {
+ret = qbus_find_recursive(child, name, bus_typename);
+if (ret) {
+return ret;
+}
+}
+}
+return NULL;
+}
+
+static bool qdev_verify_bus(DeviceClass *dc)
+{
+BusState *bus;
+
+if (dc) {
+bus = qbus_find_recursive(sysbus_get_default(), NULL, dc->bus_type);
+if (bus) {
+return true;
+}
+}
+return false;
+}
+
+static const char *find_typename_by_alias(const char *alias, bool check_bus)
 {
 int i;
+ObjectClass *oc;
 
 for (i = 0; qdev_alias_table[i].alias; i++) {
 if (qdev_alias_table[i].arch_mask &&
@@ -129,7 +173,10 @@ static const char *find_typename_by_alias(const char 
*alias)
 }
 
 if (strcmp(qdev_alias_table[i].alias, alias) == 0) {
-return qdev_alias_table[i].typename;
+oc = object_class_by_name(qdev_alias_table[i].typename);
+if (oc && (!check_bus || qdev_verify_bus(DEVICE_CLASS(oc {
+return qdev_alias_table[i].typename;
+}
 }
 }
 
@@ -155,7 +202,7 @@ int qdev_device_help(QemuOpts *opts)
 
 klass = object_class_by_name(driver);
 if (!klass) {
-const char *typename = find_typename_by_alias(driver);
+const char *typename = find_typename_by_alias(driver, false);
 
 if (typename) {
 driver = typename;
@@ -283,36 +330,6 @@ static DeviceState *qbus_find_dev(BusState *bus, char 
*elem)
 return NULL;
 }
 
-static BusState *qbus_find_recursive(BusState *bus, const char *name,
- const char *bus_typename)
-{
-BusChild *kid;
-BusState *child, *ret;
-int match = 1;
-
-if (name && (strcmp(bus->name, name) != 0)) {
-match = 0;
-}
-if (bus_typename &&
-(strcmp(object_get_typename(OBJECT(bus)), bus_typename) != 0)) {
-match = 0;
-}
-if (match) {
-return bus;
-}
-
-QTAILQ_FOREACH(kid, &bus->children, sibling) {
-DeviceState *dev = kid->child;
-QLIST_FOREACH(child, &dev->child_bus, sibling) {
-ret = qbus_find_recursive(child, name, bus_typename);
-if (ret) {
-return ret;
-}
-}
-}
-return NULL;
-}
-
 static BusState *qbus_find(const char *path)
 {
 DeviceState *dev;
@@ -417,7 +434,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
 /* find driver */
 obj = object_class_by_name(driver);
 if (!obj) {
-const char *typename = find_typename_by_alias(driver);
+const char *typename = find_typename_by_alias(driver, true);
 
 if (typename) {
 driver = typename;
diff --git a/vl.c b

[Qemu-devel] [PATCH 3/4] s390/kvm: Add a channel I/O based virtio transport driver.

2012-08-07 Thread Cornelia Huck
Add a driver for kvm guests that matches virtual ccw devices provided
by the host as virtio bridge devices.

These virtio-ccw devices use a special set of channel commands in order
to perform virtio functions.

Signed-off-by: Cornelia Huck 
---
 arch/s390/include/asm/irq.h   |   1 +
 arch/s390/kernel/irq.c|   1 +
 drivers/s390/kvm/Makefile |   2 +-
 drivers/s390/kvm/virtio_ccw.c | 761 ++
 4 files changed, 764 insertions(+), 1 deletion(-)
 create mode 100644 drivers/s390/kvm/virtio_ccw.c

diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h
index 2b9d418..b4bea53 100644
--- a/arch/s390/include/asm/irq.h
+++ b/arch/s390/include/asm/irq.h
@@ -31,6 +31,7 @@ enum interruption_class {
IOINT_CTC,
IOINT_APB,
IOINT_CSC,
+   IOINT_VIR,
NMI_NMI,
NR_IRQS,
 };
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index dd7630d..2cc7eed 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -56,6 +56,7 @@ static const struct irq_class intrclass_names[] = {
{.name = "CTC", .desc = "[I/O] CTC" },
{.name = "APB", .desc = "[I/O] AP Bus" },
{.name = "CSC", .desc = "[I/O] CHSC Subchannel" },
+   {.name = "VIR", .desc = "[I/O] Virtual I/O Devices" },
{.name = "NMI", .desc = "[NMI] Machine Check" },
 };
 
diff --git a/drivers/s390/kvm/Makefile b/drivers/s390/kvm/Makefile
index 0815690..241891a 100644
--- a/drivers/s390/kvm/Makefile
+++ b/drivers/s390/kvm/Makefile
@@ -6,4 +6,4 @@
 # it under the terms of the GNU General Public License (version 2 only)
 # as published by the Free Software Foundation.
 
-obj-$(CONFIG_S390_GUEST) += kvm_virtio.o
+obj-$(CONFIG_S390_GUEST) += kvm_virtio.o virtio_ccw.o
diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c
new file mode 100644
index 000..df0f994
--- /dev/null
+++ b/drivers/s390/kvm/virtio_ccw.c
@@ -0,0 +1,761 @@
+/*
+ * ccw based virtio transport
+ *
+ * Copyright IBM Corp. 2012
+ *
+ * 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): Cornelia Huck 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * virtio related functions
+ */
+
+struct vq_config_block {
+   __u16 index;
+   __u16 num;
+} __attribute__ ((packed));
+
+#define VIRTIO_CCW_CONFIG_SIZE 0x100
+/* same as PCI config space size, should be enough for all drivers */
+
+struct virtio_ccw_device {
+   struct virtio_device vdev;
+   __u8 status;
+   __u8 config[VIRTIO_CCW_CONFIG_SIZE];
+   struct ccw_device *cdev;
+   struct ccw1 ccw;
+   __u32 area;
+   __u32 curr_io;
+   int err;
+   wait_queue_head_t wait_q;
+   spinlock_t lock;
+   struct list_head virtqueues;
+   unsigned long indicators; /* XXX - works because we're under 64 bit */
+   struct vq_config_block *config_block;
+};
+
+struct vq_info_block {
+   __u64 queue;
+   __u16 num;
+} __attribute__ ((packed));
+
+struct virtio_ccw_vq_info {
+   struct virtqueue *vq;
+   int num;
+   int queue_index;
+   void *queue;
+   struct vq_info_block *info_block;
+   struct list_head node;
+};
+
+#define KVM_VIRTIO_CCW_RING_ALIGN 4096
+
+#define CCW_CMD_SET_VQ 0x13
+#define CCW_CMD_VDEV_RESET 0x33
+#define CCW_CMD_SET_IND 0x43
+#define CCW_CMD_READ_FEAT 0x12
+#define CCW_CMD_WRITE_FEAT 0x11
+#define CCW_CMD_READ_CONF 0x22
+#define CCW_CMD_WRITE_CONF 0x21
+#define CCW_CMD_WRITE_STATUS 0x31
+#define CCW_CMD_READ_VQ_CONF 0x32
+
+#define VIRTIO_CCW_DOING_SET_VQ 0x0001
+#define VIRTIO_CCW_DOING_RESET 0x0004
+#define VIRTIO_CCW_DOING_READ_FEAT 0x0008
+#define VIRTIO_CCW_DOING_WRITE_FEAT 0x0010
+#define VIRTIO_CCW_DOING_READ_CONFIG 0x0020
+#define VIRTIO_CCW_DOING_WRITE_CONFIG 0x0040
+#define VIRTIO_CCW_DOING_WRITE_STATUS 0x0080
+#define VIRTIO_CCW_DOING_SET_IND 0x0100
+#define VIRTIO_CCW_DOING_READ_VQ_CONF 0x0200
+#define VIRTIO_CCW_INTPARM_MASK 0x
+
+static struct virtio_ccw_device *to_vc_device(struct virtio_device *vdev)
+{
+   return container_of(vdev, struct virtio_ccw_device, vdev);
+}
+
+static int doing_io(struct virtio_ccw_device *vcdev, __u32 flag)
+{
+   unsigned long flags;
+   __u32 ret;
+
+   spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags);
+   if (vcdev->err)
+   ret = vcdev->err;
+   else
+   ret = vcdev->curr_io & flag;
+   spin_unlock_irqrestore(get_ccwdev_lock(vcdev->cdev), flags);
+   ret

[Qemu-devel] [PATCH 3/7] s390/kvm: In-kernel handling of I/O instructions.

2012-08-07 Thread Cornelia Huck
Explicitely catch all channel I/O related instructions intercepts
in the kernel and set condition code 3 for them.

This paws the way for properly handling these instructions later
on.

Note: This is not architecture compliant (the previous code wasn't
either) since setting cc 3 is not the correct thing to do for some
of these instructions. For Linux guests, however, it still has the
intended effect of stopping css probing.

Signed-off-by: Cornelia Huck 
---
 arch/s390/kvm/intercept.c | 19 +---
 arch/s390/kvm/kvm-s390.h  |  1 +
 arch/s390/kvm/priv.c  | 56 +--
 3 files changed, 56 insertions(+), 20 deletions(-)

diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index ec1177f..754dc9e 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -33,8 +33,6 @@ static int handle_lctlg(struct kvm_vcpu *vcpu)
int reg, rc;
 
vcpu->stat.instruction_lctlg++;
-   if ((vcpu->arch.sie_block->ipb & 0xff) != 0x2f)
-   return -EOPNOTSUPP;
 
useraddr = disp2;
if (base2)
@@ -104,6 +102,21 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
return 0;
 }
 
+static intercept_handler_t eb_handlers[256] = {
+   [0x2f] = handle_lctlg,
+   [0x8a] = kvm_s390_handle_priv_eb,
+};
+
+static int handle_eb(struct kvm_vcpu *vcpu)
+{
+   intercept_handler_t handler;
+
+   handler = eb_handlers[vcpu->arch.sie_block->ipb & 0xff];
+   if (handler)
+   return handler(vcpu);
+   return -EOPNOTSUPP;
+}
+
 static intercept_handler_t instruction_handlers[256] = {
[0x01] = kvm_s390_handle_01,
[0x82] = kvm_s390_handle_lpsw,
@@ -113,7 +126,7 @@ static intercept_handler_t instruction_handlers[256] = {
[0xb7] = handle_lctl,
[0xb9] = kvm_s390_handle_b9,
[0xe5] = kvm_s390_handle_e5,
-   [0xeb] = handle_lctlg,
+   [0xeb] = handle_eb,
 };
 
 static int handle_noop(struct kvm_vcpu *vcpu)
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index b1e1cb6..7f50229 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -83,6 +83,7 @@ int kvm_s390_handle_e5(struct kvm_vcpu *vcpu);
 int kvm_s390_handle_01(struct kvm_vcpu *vcpu);
 int kvm_s390_handle_b9(struct kvm_vcpu *vcpu);
 int kvm_s390_handle_lpsw(struct kvm_vcpu *vcpu);
+int kvm_s390_handle_priv_eb(struct kvm_vcpu *vcpu);
 
 /* implemented in sigp.c */
 int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 7e7263c..8b79a94 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -135,20 +135,9 @@ static int handle_skey(struct kvm_vcpu *vcpu)
return 0;
 }
 
-static int handle_stsch(struct kvm_vcpu *vcpu)
+static int handle_io_inst(struct kvm_vcpu *vcpu)
 {
-   vcpu->stat.instruction_stsch++;
-   VCPU_EVENT(vcpu, 4, "%s", "store subchannel - CC3");
-   /* condition code 3 */
-   vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
-   vcpu->arch.sie_block->gpsw.mask |= (3 & 3ul) << 44;
-   return 0;
-}
-
-static int handle_chsc(struct kvm_vcpu *vcpu)
-{
-   vcpu->stat.instruction_chsc++;
-   VCPU_EVENT(vcpu, 4, "%s", "channel subsystem call - CC3");
+   VCPU_EVENT(vcpu, 4, "%s", "I/O instruction");
/* condition code 3 */
vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
vcpu->arch.sie_block->gpsw.mask |= (3 & 3ul) << 44;
@@ -392,7 +381,7 @@ out_fail:
return 0;
 }
 
-static intercept_handler_t priv_handlers[256] = {
+static intercept_handler_t b2_handlers[256] = {
[0x02] = handle_stidp,
[0x10] = handle_set_prefix,
[0x11] = handle_store_prefix,
@@ -400,8 +389,22 @@ static intercept_handler_t priv_handlers[256] = {
[0x29] = handle_skey,
[0x2a] = handle_skey,
[0x2b] = handle_skey,
-   [0x34] = handle_stsch,
-   [0x5f] = handle_chsc,
+   [0x30] = handle_io_inst,
+   [0x31] = handle_io_inst,
+   [0x32] = handle_io_inst,
+   [0x33] = handle_io_inst,
+   [0x34] = handle_io_inst,
+   [0x35] = handle_io_inst,
+   [0x36] = handle_io_inst,
+   [0x37] = handle_io_inst,
+   [0x38] = handle_io_inst,
+   [0x39] = handle_io_inst,
+   [0x3a] = handle_io_inst,
+   [0x3b] = handle_io_inst,
+   [0x3c] = handle_io_inst,
+   [0x5f] = handle_io_inst,
+   [0x74] = handle_io_inst,
+   [0x76] = handle_io_inst,
[0x7d] = handle_stsi,
[0xb1] = handle_stfl,
[0xb2] = handle_lpswe,
@@ -418,7 +421,7 @@ int kvm_s390_handle_b2(struct kvm_vcpu *vcpu)
 * state bit and (a) handle the instruction or (b) send a code 2
 * program check.
 * Anything else goes to userspace.*/
-   handler = priv_handlers[vcpu->arch.sie_block->ipa & 

[Qemu-devel] [RFC PATCH 0/5] qemu: s390: virtual css and virtio-ccw

2012-08-07 Thread Cornelia Huck
Hi,

following are the qemu parts for supporting virtual channel I/O
and the new virtio-ccw transport.

Patch 1 pulls in the new interface definitions.

Patch 2 contains the ground work for supporting virtual subchannels
(kvm only).

Patch 3 implements the new virtio-ccw transport.

Patch 4 makes virtual subchannels available for !kvm as well. Note
that this patch is completely untested; it basically contains my
initial channel subsystem code before I moved most of it into the
kernel.

Patch 5 is a hack needed to make virtio-ccw work with the alias stuff
for now. The correct solution is to rework the virtio layering as
has been proposed for virtio-mmio (see
http://comments.gmane.org/gmane.comp.emulators.qemu/148224).

The patches still have some TODOs in them (but nothing major), and
likely some things need to be done differently. I hope, however,
that the architectural part is fine.

Cornelia Huck (5):
  Update headers for upcoming s390 changes.
  s390: Virtual channel subsystem support.
  s390: Add new channel I/O based virtio transport.
  s390: Virtual channel subsystem support for !KVM.
  [HACK] Handle multiple virtio aliases.

 blockdev.c|6 +-
 hw/qdev-monitor.c |   90 +--
 hw/s390-virtio.c  |  268 ++---
 hw/s390x/Makefile.objs|2 +
 hw/s390x/css.c| 1202 +
 hw/s390x/css.h|   89 +++
 hw/s390x/virtio-ccw.c |  962 +
 hw/s390x/virtio-ccw.h |   77 +++
 linux-headers/asm-s390/kvm.h  |2 +-
 linux-headers/asm-s390/kvm_para.h |2 +-
 linux-headers/linux/kvm.h |   63 ++
 target-s390x/Makefile.objs|2 +-
 target-s390x/cpu.h|  261 
 target-s390x/helper.c |  140 +
 target-s390x/ioinst.c |  734 ++
 target-s390x/ioinst.h |  206 +++
 target-s390x/kvm.c|  265 +++-
 target-s390x/op_helper.c  |   22 +-
 vl.c  |7 +-
 19 files changed, 4260 insertions(+), 140 deletions(-)
 create mode 100644 hw/s390x/css.c
 create mode 100644 hw/s390x/css.h
 create mode 100644 hw/s390x/virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.h
 create mode 100644 target-s390x/ioinst.c
 create mode 100644 target-s390x/ioinst.h

-- 
1.7.11.4




[Qemu-devel] [RFC PATCH 0/4] s390: virtio-ccw guest kernel support.

2012-08-07 Thread Cornelia Huck
Hi,

the following patches are for Linux running as a guest under a
host with virtio-ccw support.

Patch 1 makes the kvm_virtio driver exit gracefully if the page
containing s390-virtio information it expects is not present; it
could probably go in seperately from the other patches.

Patch 2 exports a needed interface.

Patch 3 adds a driver handling virtio-ccw devices. The virtual
subchannels have ccw devices with a special CU id this driver
matches for. The virtio_ccw driver handles configuration and
operation via the special new channel commands.

Patch 4 is a split out of common code.

Cornelia Huck (4):
  s390/kvm: Handle hosts not supporting s390-virtio.
  s390: Add a mechanism to get the subchannel id.
  s390/kvm: Add a channel I/O based virtio transport driver.
  s390/kvm: Split out early console code.

 arch/s390/include/asm/ccwdev.h  |   5 +
 arch/s390/include/asm/irq.h |   1 +
 arch/s390/kernel/irq.c  |   1 +
 drivers/s390/cio/device_ops.c   |  10 +
 drivers/s390/kvm/Makefile   |   2 +-
 drivers/s390/kvm/early_printk.c |  42 +++
 drivers/s390/kvm/kvm_virtio.c   |  46 ++-
 drivers/s390/kvm/virtio_ccw.c   | 760 
 8 files changed, 841 insertions(+), 26 deletions(-)
 create mode 100644 drivers/s390/kvm/early_printk.c
 create mode 100644 drivers/s390/kvm/virtio_ccw.c

-- 
1.7.11.4




[Qemu-devel] [PATCH 2/4] s390: Add a mechanism to get the subchannel id.

2012-08-07 Thread Cornelia Huck
This will be needed by the new virtio-ccw transport.

Signed-off-by: Cornelia Huck 
---
 arch/s390/include/asm/ccwdev.h |  5 +
 drivers/s390/cio/device_ops.c  | 10 ++
 2 files changed, 15 insertions(+)

diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h
index 1cb4bb3..9ad79f7 100644
--- a/arch/s390/include/asm/ccwdev.h
+++ b/arch/s390/include/asm/ccwdev.h
@@ -18,6 +18,9 @@ struct irb;
 struct ccw1;
 struct ccw_dev_id;
 
+/* from asm/schid.h */
+struct subchannel_id;
+
 /* simplified initializers for struct ccw_device:
  * CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one
  * entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */
@@ -226,5 +229,7 @@ int ccw_device_siosl(struct ccw_device *);
 // FIXME: these have to go
 extern int _ccw_device_get_subchannel_number(struct ccw_device *);
 
+extern void ccw_device_get_schid(struct ccw_device *, struct subchannel_id *);
+
 extern void *ccw_device_get_chp_desc(struct ccw_device *, int);
 #endif /* _S390_CCWDEV_H_ */
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index ec7fb6d..a93f4a0 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -763,6 +763,16 @@ _ccw_device_get_subchannel_number(struct ccw_device *cdev)
return cdev->private->schid.sch_no;
 }
 
+/**
+ * ccw_device_get_schid - obtain a subchannel id
+ * @cdev: device to obtain the id for
+ * @schid: where to fill in the values
+ */
+void ccw_device_get_schid(struct ccw_device *cdev, struct subchannel_id *schid)
+{
+   *schid = cdev->private->schid;
+}
+EXPORT_SYMBOL(ccw_device_get_schid);
 
 MODULE_LICENSE("GPL");
 EXPORT_SYMBOL(ccw_device_set_options_mask);
-- 
1.7.11.4




[Qemu-devel] [PATCH 3/5] s390: Add new channel I/O based virtio transport.

2012-08-07 Thread Cornelia Huck
Add a new virtio transport that uses channel commands to perform
virtio operations.

Add a new machine type s390-ccw that uses this virtio-ccw transport
and make it the default machine for s390.

Signed-off-by: Cornelia Huck 
---
 hw/qdev-monitor.c  |   5 +
 hw/s390-virtio.c   | 268 ++
 hw/s390x/Makefile.objs |   1 +
 hw/s390x/virtio-ccw.c  | 962 +
 hw/s390x/virtio-ccw.h  |  77 
 vl.c   |   1 +
 6 files changed, 1243 insertions(+), 71 deletions(-)
 create mode 100644 hw/s390x/virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.h

diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index b22a37a..79f7e6b 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -42,6 +42,11 @@ static const QDevAlias qdev_alias_table[] = {
 { "virtio-blk-s390", "virtio-blk", QEMU_ARCH_S390X },
 { "virtio-net-s390", "virtio-net", QEMU_ARCH_S390X },
 { "virtio-serial-s390", "virtio-serial", QEMU_ARCH_S390X },
+{ "virtio-blk-ccw", "virtio-blk", QEMU_ARCH_S390X },
+{ "virtio-net-ccw", "virtio-net", QEMU_ARCH_S390X },
+{ "virtio-serial-ccw", "virtio-serial", QEMU_ARCH_S390X },
+{ "virtio-balloon-ccw", "virtio-balloon", QEMU_ARCH_S390X },
+{ "virtio-scsi-ccw", "virtio-scsi", QEMU_ARCH_S390X },
 { "lsi53c895a", "lsi" },
 { "ich9-ahci", "ahci" },
 { }
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 47eed35..b8bdf80 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -30,8 +30,11 @@
 #include "hw/sysbus.h"
 #include "kvm.h"
 #include "exec-memory.h"
+#include "qemu-thread.h"
 
 #include "hw/s390-virtio-bus.h"
+#include "hw/s390x/css.h"
+#include "hw/s390x/virtio-ccw.h"
 
 //#define DEBUG_S390
 
@@ -46,6 +49,7 @@
 #define KVM_S390_VIRTIO_NOTIFY  0
 #define KVM_S390_VIRTIO_RESET   1
 #define KVM_S390_VIRTIO_SET_STATUS  2
+#define KVM_S390_VIRTIO_CCW_NOTIFY  3
 
 #define KERN_IMAGE_START0x01UL
 #define KERN_PARM_AREA  0x010480UL
@@ -62,6 +66,7 @@
 
 static VirtIOS390Bus *s390_bus;
 static S390CPU **ipi_states;
+VirtioCcwBus *ccw_bus;
 
 S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
 {
@@ -75,15 +80,21 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
 int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall)
 {
 int r = 0, i;
+int cssid, ssid, schid, m;
+SubchDev *sch;
 
 dprintf("KVM hypercall: %ld\n", hypercall);
 switch (hypercall) {
 case KVM_S390_VIRTIO_NOTIFY:
 if (mem > ram_size) {
-VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
-   mem, &i);
-if (dev) {
-virtio_queue_notify(dev->vdev, i);
+if (s390_bus) {
+VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
+   mem, &i);
+if (dev) {
+virtio_queue_notify(dev->vdev, i);
+} else {
+r = -EINVAL;
+}
 } else {
 r = -EINVAL;
 }
@@ -92,28 +103,49 @@ int s390_virtio_hypercall(CPUS390XState *env, uint64_t 
mem, uint64_t hypercall)
 }
 break;
 case KVM_S390_VIRTIO_RESET:
-{
-VirtIOS390Device *dev;
-
-dev = s390_virtio_bus_find_mem(s390_bus, mem);
-virtio_reset(dev->vdev);
-stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0);
-s390_virtio_device_sync(dev);
-s390_virtio_reset_idx(dev);
+if (s390_bus) {
+VirtIOS390Device *dev;
+
+dev = s390_virtio_bus_find_mem(s390_bus, mem);
+virtio_reset(dev->vdev);
+stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0);
+s390_virtio_device_sync(dev);
+s390_virtio_reset_idx(dev);
+} else {
+r = -EINVAL;
+}
 break;
-}
 case KVM_S390_VIRTIO_SET_STATUS:
-{
-VirtIOS390Device *dev;
+if (s390_bus) {
+VirtIOS390Device *dev;
 
-dev = s390_virtio_bus_find_mem(s390_bus, mem);
-if (dev) {
-s390_virtio_device_update_status(dev);
+dev = s390_virtio_bus_find_mem(s390_bus, mem);
+if (dev) {
+s390_virtio_device_update_status(dev);
+} else {
+r = -EINVAL;
+}
 } else {
 r = -EINVAL;
 }
 break;
-}
+case KVM_S390_VIRTIO_CCW_NOTIFY:
+if (ccw_bus) {
+if (ioinst_disassemble_sch_ident(en

[Qemu-devel] [PATCH 1/7] s390/kvm: Support for I/O interrupts.

2012-08-07 Thread Cornelia Huck
Add support for handling I/O interrupts (standard, subchannel-related
ones and rudimentary adapter interrupts).

The subchannel-identifying parameters are encoded into the interrupt
type.

I/O interrupts are floating, so they can't be injected on a specific
vcpu.

Signed-off-by: Cornelia Huck 
---
 arch/s390/include/asm/kvm_host.h |   2 +
 arch/s390/kvm/interrupt.c| 115 +--
 include/linux/kvm.h  |   6 ++
 3 files changed, 118 insertions(+), 5 deletions(-)

diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index b784154..e47f697 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -76,6 +76,7 @@ struct kvm_s390_sie_block {
__u64   epoch;  /* 0x0038 */
__u8reserved40[4];  /* 0x0040 */
 #define LCTL_CR0   0x8000
+#define LCTL_CR6   0x0200
__u16   lctl;   /* 0x0044 */
__s16   icpua;  /* 0x0046 */
__u32   ictl;   /* 0x0048 */
@@ -127,6 +128,7 @@ struct kvm_vcpu_stat {
u32 deliver_prefix_signal;
u32 deliver_restart_signal;
u32 deliver_program_int;
+   u32 deliver_io_int;
u32 exit_wait_state;
u32 instruction_stidp;
u32 instruction_spx;
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 7556231..1dccfe7 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -21,11 +21,26 @@
 #include "gaccess.h"
 #include "trace-s390.h"
 
+#define IOINT_SCHID_MASK 0x
+#define IOINT_SSID_MASK 0x0003
+#define IOINT_CSSID_MASK 0x03fc
+#define IOINT_AI_MASK 0x0400
+
+static int is_ioint(u64 type)
+{
+   return ((type & 0xfffeu) != 0xfffeu);
+}
+
 static int psw_extint_disabled(struct kvm_vcpu *vcpu)
 {
return !(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_EXT);
 }
 
+static int psw_ioint_disabled(struct kvm_vcpu *vcpu)
+{
+   return !(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_IO);
+}
+
 static int psw_interrupts_disabled(struct kvm_vcpu *vcpu)
 {
if ((vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PER) ||
@@ -68,7 +83,18 @@ static int __interrupt_is_deliverable(struct kvm_vcpu *vcpu,
case KVM_S390_RESTART:
return 1;
default:
-   BUG();
+   if (is_ioint(inti->type)) {
+   if (psw_ioint_disabled(vcpu))
+   return 0;
+   if (vcpu->arch.sie_block->gcr[6] &
+   inti->io.io_int_word)
+   return 1;
+   return 0;
+   } else {
+   printk(KERN_WARNING "illegal interrupt type %llx\n",
+  inti->type);
+   BUG();
+   }
}
return 0;
 }
@@ -117,6 +143,13 @@ static void __set_intercept_indicator(struct kvm_vcpu 
*vcpu,
__set_cpuflag(vcpu, CPUSTAT_STOP_INT);
break;
default:
+   if (is_ioint(inti->type)) {
+   if (psw_ioint_disabled(vcpu))
+   __set_cpuflag(vcpu, CPUSTAT_IO_INT);
+   else
+   vcpu->arch.sie_block->lctl |= LCTL_CR6;
+   break;
+   }
BUG();
}
 }
@@ -298,7 +331,49 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
break;
 
default:
-   BUG();
+   if (is_ioint(inti->type)) {
+   __u32 param0 = ((__u32)inti->io.subchannel_id << 16) |
+   inti->io.subchannel_nr;
+   __u64 param1 = ((__u64)inti->io.io_int_parm << 32) |
+   inti->io.io_int_word;
+   VCPU_EVENT(vcpu, 4,
+  "interrupt: I/O %llx", inti->type);
+   vcpu->stat.deliver_io_int++;
+   trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, 
inti->type,
+param0, param1);
+   rc = put_guest_u16(vcpu, __LC_SUBCHANNEL_ID,
+  inti->io.subchannel_id);
+   if (rc == -EFAULT)
+   exception = 1;
+
+   rc = put_guest_u16(vcpu, __LC_SUBCHANNEL_NR,
+  inti->io.subchannel_nr);
+   if (rc == -EFAULT)
+   exception = 1;
+
+   rc = put_guest_u32(vcpu, __LC_IO_INT_PARM,
+  inti->io.io_int_parm);
+ 

[Qemu-devel] [PATCH 1/4] s390/kvm: Handle hosts not supporting s390-virtio.

2012-08-07 Thread Cornelia Huck
Running under a kvm host does not necessarily imply the presence of
a page mapped above the main memory with the virtio information;
however, the code includes a hard coded access to that page.

Instead, check for the presence of the page and exit gracefully
before we hit an addressing exception if it does not exist.

Signed-off-by: Cornelia Huck 
---
 drivers/s390/kvm/kvm_virtio.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 47cccd5..408447c 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -418,6 +418,21 @@ static void kvm_extint_handler(struct ext_code ext_code,
}
 }
 
+static int __init test_devices_support(void)
+{
+   int ccode = -EIO;
+
+   asm volatile(
+   "0: cli 0(%1),0\n"
+   "   ipm %0\n"
+   "   srl %0,28\n"
+   "1:\n"
+   EX_TABLE(0b,1b)
+   : "+d" (ccode)
+   : "a" (kvm_devices)
+   : "cc");
+   return ccode;
+}
 /*
  * Init function for virtio
  * devices are in a single page above top of "normal" mem
@@ -443,6 +458,12 @@ static int __init kvm_devices_init(void)
}
 
kvm_devices = (void *) real_memory_size;
+   if (test_devices_support() < 0) {
+   vmem_remove_mapping(real_memory_size, PAGE_SIZE);
+   root_device_unregister(kvm_root);
+   /* No error. */
+   return 0;
+   }
 
INIT_WORK(&hotplug_work, hotplug_devices);
 
-- 
1.7.11.4




Re: [Qemu-devel] [PATCH 2/5] s390: Virtual channel subsystem support.

2012-08-08 Thread Cornelia Huck
On Tue, 7 Aug 2012 21:00:59 +
Blue Swirl  wrote:


> > diff --git a/hw/s390x/css.c b/hw/s390x/css.c
> > new file mode 100644
> > index 000..7941c44
> > --- /dev/null
> > +++ b/hw/s390x/css.c
> > @@ -0,0 +1,440 @@
> > +/*
> > + * Channel subsystem base support.
> > + *
> > + * Copyright 2012 IBM Corp.
> > + * Author(s): Cornelia Huck 
> > + *
> > + * 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-thread.h"
> > +#include "qemu-queue.h"
> > +#include 
> > +#include "kvm.h"
> > +#include "cpu.h"
> > +#include "ioinst.h"
> > +#include "css.h"
> > +
> > +struct chp_info {
> 
> CamelCase, please.

OK.
> 
> > +uint8_t in_use;
> > +uint8_t type;
> > +};
> > +
> > +static struct chp_info chpids[MAX_CSSID + 1][MAX_CHPID + 1];
> > +
> > +static css_subch_cb_func css_subch_cb;
> 
> Probably these can be put to a container structure which can be passed around.

Still trying to come up with a good model for that.

> 

> > +case CCW_CMD_SENSE_ID:
> > +{
> > +uint8_t sense_bytes[256];
> > +
> > +/* Sense ID information is device specific. */
> > +memcpy(sense_bytes, &sch->id, sizeof(sense_bytes));
> > +if (check_len) {
> > +if (ccw->count != sizeof(sense_bytes)) {
> > +ret = -EINVAL;
> > +break;
> > +}
> > +}
> > +len = MIN(ccw->count, sizeof(sense_bytes));
> > +/*
> > + * Only indicate 0xff in the first sense byte if we actually
> > + * have enough place to store at least bytes 0-3.
> > + */
> > +if (len >= 4) {
> > +stb_phys(ccw->cda, 0xff);
> > +} else {
> > +stb_phys(ccw->cda, 0);
> > +}
> > +i = 1;
> > +for (i = 1; i < len - 1; i++) {
> > +stb_phys(ccw->cda + i, sense_bytes[i]);
> > +}
> 
> cpu_physical_memory_write()

Hm, what's wrong with storing byte-by-byte?

> 
> > +sch->curr_status.scsw.count = ccw->count - len;
> > +ret = 0;
> > +break;
> > +}
> > +case CCW_CMD_TIC:
> > +if (sch->last_cmd->cmd_code == CCW_CMD_TIC) {
> > +ret = -EINVAL;
> > +break;
> > +}
> > +if (ccw->flags & (CCW_FLAG_CC | CCW_FLAG_DC)) {
> > +ret = -EINVAL;
> > +break;
> > +}
> > +sch->channel_prog = qemu_get_ram_ptr(ccw->cda);
> > +ret = sch->channel_prog ? -EAGAIN : -EFAULT;
> > +break;
> > +default:
> > +if (sch->ccw_cb) {
> > +/* Handle device specific commands. */
> > +ret = sch->ccw_cb(sch, ccw);
> > +} else {
> > +ret = -EOPNOTSUPP;
> > +}
> > +break;
> > +}
> > +sch->last_cmd = ccw;
> > +if (ret == 0) {
> > +if (ccw->flags & CCW_FLAG_CC) {
> > +sch->channel_prog += 8;
> > +ret = -EAGAIN;
> > +}
> > +}
> > +
> > +return ret;

> > diff --git a/hw/s390x/css.h b/hw/s390x/css.h
> > new file mode 100644
> > index 000..b8a95cc
> > --- /dev/null
> > +++ b/hw/s390x/css.h
> > @@ -0,0 +1,62 @@
> > +/*
> > + * Channel subsystem structures and definitions.
> > + *
> > + * Copyright 2012 IBM Corp.
> > + * Author(s): Cornelia Huck 
> > + *
> > + * 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 CSS_H
> > +#define CSS_H
> > +
> > +#include "ioinst.h"
> > +
> > +/* Channel subsystem constants. */
> > +#define MAX_SCHID 65535
> > +#define MAX_SSID 3
> > +#define MAX_CSSID 254 /* 255 is reserved */
> > +#define MAX_CHPID 255
> > +
> > +#define MAX_CIWS 8
> > +
> > +struct senseid {
> 
> SenseID

OK.
> 
> > +/* common part */
> > +uint32_t  reserved:8;/* always 0x'FF' */
> 
> The standard syntax 

Re: [Qemu-devel] [PATCH 3/5] s390: Add new channel I/O based virtio transport.

2012-08-08 Thread Cornelia Huck
On Tue, 7 Aug 2012 20:47:22 +
Blue Swirl  wrote:


> > diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> > new file mode 100644
> > index 000..8a90c3a
> > --- /dev/null
> > +++ b/hw/s390x/virtio-ccw.c
> > @@ -0,0 +1,962 @@
> > +/*
> > + * virtio ccw target implementation
> > + *
> > + * Copyright 2012 IBM Corp.
> > + * Author(s): Cornelia Huck 
> > + *
> > + * 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 
> > +#include "block.h"
> > +#include "blockdev.h"
> > +#include "sysemu.h"
> > +#include "net.h"
> > +#include "monitor.h"
> > +#include "qemu-thread.h"
> > +#include "../virtio.h"
> > +#include "../virtio-serial.h"
> > +#include "../virtio-net.h"
> > +#include "../sysbus.h"
> 
> "hw/virtio..." for the above

OK.
> 
> > +#include "bitops.h"
> > +
> > +#include "ioinst.h"
> > +#include "css.h"
> > +#include "virtio-ccw.h"
> > +
> > +static const TypeInfo virtio_ccw_bus_info = {
> > +.name = TYPE_VIRTIO_CCW_BUS,
> > +.parent = TYPE_BUS,
> > +.instance_size = sizeof(VirtioCcwBus),
> > +};
> > +
> > +static const VirtIOBindings virtio_ccw_bindings;
> > +
> > +typedef struct sch_entry {
> > +SubchDev *sch;
> > +QLIST_ENTRY(sch_entry) entry;
> > +} sch_entry;
> 
> SubchEntry, see CODING_STYLE. Also other struct and typedef names below.
> 
> > +
> > +QLIST_HEAD(subch_list, sch_entry);
> 
> static, but please put this to a structure that is passed around instead.
> 
> > +
> > +typedef struct devno_entry {
> > +uint16_t devno;
> > +QLIST_ENTRY(devno_entry) entry;
> > +} devno_entry;
> > +
> > +QLIST_HEAD(devno_list, devno_entry);
> 
> Ditto
> 
> > +
> > +struct subch_set {
> > +struct subch_list *s_list[256];
> > +struct devno_list *d_list[256];
> > +};
> > +
> > +struct css_set {
> > +struct subch_set *set[MAX_SSID + 1];
> > +};
> > +
> > +static struct css_set *channel_subsys[MAX_CSSID + 1];

OK, will try to come up with some kind of structure for this and
CamelCasify it.

> > +
> > +VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
> > +{
> > +VirtIODevice *vdev = NULL;
> > +
> > +if (sch->driver_data) {
> > +vdev = ((VirtioCcwData *)sch->driver_data)->vdev;
> > +}
> > +return vdev;
> > +}
> > +

> > +VirtioCcwBus *virtio_ccw_bus_init(void)
> > +{
> > +VirtioCcwBus *bus;
> > +BusState *_bus;
> 
> Please avoid identifiers with leading underscores.

OK.

> 
> > +DeviceState *dev;
> > +
> > +css_set_subch_cb(virtio_ccw_find_subch);
> > +
> > +/* Create bridge device */
> > +dev = qdev_create(NULL, "virtio-ccw-bridge");
> > +qdev_init_nofail(dev);
> > +
> > +/* Create bus on bridge device */
> > +_bus = qbus_create(TYPE_VIRTIO_CCW_BUS, dev, "virtio-ccw");
> > +bus = DO_UPCAST(VirtioCcwBus, bus, _bus);
> > +
> > +/* Enable hotplugging */
> > +_bus->allow_hotplug = 1;
> > +
> > +return bus;
> > +}
> > +
> > +struct vq_info_block {
> > +uint64_t queue;
> > +uint16_t num;
> > +} QEMU_PACKED;
> > +
> > +struct vq_config_block {
> > +uint16_t index;
> > +uint16_t num;
> > +} QEMU_PACKED;
> 
> Aren't these KVM structures? They should be defined in a KVM header
> file file in linux-headers.

Not really, virtio-ccw isn't tied to kvm.

I see this more as command blocks that are specific to the "control
unit" - like something that would be defined in an attachment
specification for a classic s390 device (and in the virtio spec in this
case) and modeled as C structures here.

> 

> > +case CCW_CMD_WRITE_CONF:
> > +if (check_len) {
> > +if (ccw->count > data->vdev->config_len) {
> > +ret = -EINVAL;
> > +break;
> > +}
> > +}
> > +len = MIN(ccw->count, data->vdev->config_len);
> > +config = qemu_get_ram_ptr(ccw->cda);
> 
> Please use cpu_physical_memory_read() (or DMA v

Re: [Qemu-devel] [PATCH 2/5] s390: Virtual channel subsystem support.

2012-08-08 Thread Cornelia Huck
On Wed, 8 Aug 2012 09:27:32 +0100
Peter Maydell  wrote:

> On 7 August 2012 15:52, Cornelia Huck  wrote:
> > +static void sch_handle_clear_func(SubchDev *sch)
> > +{
> > +struct pmcw *p = &sch->curr_status.pmcw;
> > +struct scsw *s = &sch->curr_status.scsw;
> > +int path;
> > +
> > +/* Path management: In our simple css, we always choose the only path. 
> > */
> > +path = 0x80;
> > +
> > +/* Reset values prior to 'issueing the clear signal'. */
> > +p->lpum = 0;
> 
> This is unnecessary since we're going to set p->lpum to something else about
> ten lines later, right?

My intention here was following the description in the architecture
closely. In our case, 'attempting to issue the clear signal' will
always succeed, and so we will always set the lpum later on - on real
hardware, this may be different.

> 
> > +p->pom = 0xff;
> > +s->pno = 0;
> > +
> > +/* We always 'attempt to issue the clear signal', and we always 
> > succeed. */
> > +sch->orb = NULL;
> > +sch->channel_prog = NULL;
> > +sch->last_cmd = NULL;
> > +s->actl &= ~SCSW_ACTL_CLEAR_PEND;
> > +s->stctl |= SCSW_STCTL_STATUS_PEND;
> > +
> > +s->dstat = 0;
> > +s->cstat = 0;
> > +p->lpum = path;
> > +
> > +}
> 
> -- PMM
> 




Re: [Qemu-devel] [PATCH 2/5] s390: Virtual channel subsystem support.

2012-08-09 Thread Cornelia Huck
On Wed, 8 Aug 2012 19:39:33 +
Blue Swirl  wrote:

> On Wed, Aug 8, 2012 at 7:34 PM, Peter Maydell  
> wrote:
> > On 8 August 2012 20:16, Blue Swirl  wrote:
> >> On Wed, Aug 8, 2012 at 8:17 AM, Cornelia Huck  
> >> wrote:
> >>> On Tue, 7 Aug 2012 21:00:59 +
> >>> Blue Swirl  wrote:
> >>>> Please use more descriptive names instead of acronyms, for example 
> >>>> SubChStatus.
> >>>
> >>> I'd rather leave these at the well-known scsw, pmcw, etc. names. These
> >>> have been around for decades, and somebody familiar with channel I/O
> >>> will instantly know what a struct scsw is, but will need to look hard
> >>> at the code to figure out the meaning of SubChStatus.
> >>
> >> If they are well-known and have been around for so long time, are
> >> there any suitable header files (with compatible licenses) where they
> >> are defined which could be reused?

There's the Linux headers, but they are not exported as this is not a
user space interface (on the guest side).

Otherwise, most code dealing with channel I/O is probably not written
in C ;)

> >>
> >> Otherwise, please follow CODING_STYLE.
> >
> > I think we should follow CODING_STYLE for capitalisation issues
> > but generally if the device's documentation has standard abbreviations
> > for register names, structures, etc, etc we should use them. Often
> > this code has to be maintained later by somebody else who might not
> > be familiar with the general operation of the hardware and who is trying
> > to match up the code with whatever the data sheet says. Following the
> > naming used in the h/w docs makes that job easier.
> 
> Yes. typedef struct SCSW {} SCSW; should be OK too.

Then I'll use something like that.




Re: [Qemu-devel] [PATCH 3/5] s390: Add new channel I/O based virtio transport.

2012-08-09 Thread Cornelia Huck
On Wed, 8 Aug 2012 19:03:14 +
Blue Swirl  wrote:


> >> > +struct vq_info_block {
> >> > +uint64_t queue;
> >> > +uint16_t num;
> >> > +} QEMU_PACKED;
> >> > +
> >> > +struct vq_config_block {
> >> > +uint16_t index;
> >> > +uint16_t num;
> >> > +} QEMU_PACKED;
> >>
> >> Aren't these KVM structures? They should be defined in a KVM header
> >> file file in linux-headers.
> >
> > Not really, virtio-ccw isn't tied to kvm.
> >
> > I see this more as command blocks that are specific to the "control
> > unit" - like something that would be defined in an attachment
> > specification for a classic s390 device (and in the virtio spec in this
> > case) and modeled as C structures here.
> 
> OK. Then please use CamelCase for these too.
> 

OK.




Re: [Qemu-devel] [PATCH 1/4] s390/kvm: Handle hosts not supporting s390-virtio.

2012-08-09 Thread Cornelia Huck
On Thu, 09 Aug 2012 13:03:57 +0300
Avi Kivity  wrote:

> On 08/07/2012 05:52 PM, Cornelia Huck wrote:
> > Running under a kvm host does not necessarily imply the presence of
> > a page mapped above the main memory with the virtio information;
> > however, the code includes a hard coded access to that page.
> > 
> > Instead, check for the presence of the page and exit gracefully
> > before we hit an addressing exception if it does not exist.
> > 
> >  /*
> >   * Init function for virtio
> >   * devices are in a single page above top of "normal" mem
> > @@ -443,6 +458,12 @@ static int __init kvm_devices_init(void)
> > }
> >  
> > kvm_devices = (void *) real_memory_size;
> > +   if (test_devices_support() < 0) {
> > +   vmem_remove_mapping(real_memory_size, PAGE_SIZE);
> > +   root_device_unregister(kvm_root);
> > +   /* No error. */
> > +   return 0;
> > +   }
> >  
> 
> Cleaner to defer root_device_register() until after the mapping has been
> verified.

OK, will reorder.




Re: [Qemu-devel] [PATCH 3/5] s390: Add new channel I/O based virtio transport.

2012-08-09 Thread Cornelia Huck
On Thu, 9 Aug 2012 12:34:04 +0100
Stefan Hajnoczi  wrote:

> On Tue, Aug 7, 2012 at 3:52 PM, Cornelia Huck  
> wrote:
> > Add a new virtio transport that uses channel commands to perform
> > virtio operations.
> >
> > Add a new machine type s390-ccw that uses this virtio-ccw transport
> > and make it the default machine for s390.
> >
> > Signed-off-by: Cornelia Huck 
> > ---
> >  hw/qdev-monitor.c  |   5 +
> >  hw/s390-virtio.c   | 268 ++
> >  hw/s390x/Makefile.objs |   1 +
> >  hw/s390x/virtio-ccw.c  | 962 
> > +
> >  hw/s390x/virtio-ccw.h  |  77 
> >  vl.c   |   1 +
> >  6 files changed, 1243 insertions(+), 71 deletions(-)
> >  create mode 100644 hw/s390x/virtio-ccw.c
> >  create mode 100644 hw/s390x/virtio-ccw.h
> 
> Is the virtqueue still using vring and assuming the hypervisor reaches
> into guest memory?

The virtqueues are guest-allocated and their location is transmitted
via a control-type ccw to the host, which can then use it until
notified otherwise.

> 
> Can existing ccw device types access memory directly (for some reason
> I assumed ccw always copies or send messages)?

Not sure if I understand your question correctly, but read or write
type ccws specify a memory area where the hardware/hypervisor may write
to or read from. These accesses happen while the channel program is
running (any time between the ssch/rsch and ending status present at
the subchannel). The "specify an area that can be used by hardware and
os" approach exists as well; the closed thing to the virtio-ccw
approach is probably qdio.




Re: [Qemu-devel] [PATCH 1/4] s390/kvm: Handle hosts not supporting s390-virtio.

2012-08-10 Thread Cornelia Huck
On Fri, 10 Aug 2012 01:09:15 +0200
Alexander Graf  wrote:

> 
> On 07.08.2012, at 16:52, Cornelia Huck wrote:
> 
> > Running under a kvm host does not necessarily imply the presence of
> > a page mapped above the main memory with the virtio information;
> > however, the code includes a hard coded access to that page.
> > 
> > Instead, check for the presence of the page and exit gracefully
> > before we hit an addressing exception if it does not exist.
> > 
> > Signed-off-by: Cornelia Huck 
> > ---
> > drivers/s390/kvm/kvm_virtio.c | 21 +
> > 1 file changed, 21 insertions(+)
> > 
> > diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
> > index 47cccd5..408447c 100644
> > --- a/drivers/s390/kvm/kvm_virtio.c
> > +++ b/drivers/s390/kvm/kvm_virtio.c
> > @@ -418,6 +418,21 @@ static void kvm_extint_handler(struct ext_code 
> > ext_code,
> > }
> > }
> > 
> > +static int __init test_devices_support(void)
> 
> Today we know what this function does, but the next person running into it 
> has no clue. Maybe add a nice description here that you're trying to access 
> memory above ram? (is this even what you're doing here? my s390 asm is 
> slightly rusty) :)

Good point, will add a comment.




Re: [Qemu-devel] [PATCH 1/4] s390/kvm: Handle hosts not supporting s390-virtio.

2012-08-10 Thread Cornelia Huck
On Fri, 10 Aug 2012 10:42:48 +0200
Heiko Carstens  wrote:

> On Thu, Aug 09, 2012 at 12:41:57PM +0200, Cornelia Huck wrote:
> > On Thu, 09 Aug 2012 13:03:57 +0300
> > Avi Kivity  wrote:
> > 
> > > On 08/07/2012 05:52 PM, Cornelia Huck wrote:
> > > > Running under a kvm host does not necessarily imply the presence of
> > > > a page mapped above the main memory with the virtio information;
> > > > however, the code includes a hard coded access to that page.
> > > > 
> > > > Instead, check for the presence of the page and exit gracefully
> > > > before we hit an addressing exception if it does not exist.
> > > > 
> > > >  /*
> > > >   * Init function for virtio
> > > >   * devices are in a single page above top of "normal" mem
> > > > @@ -443,6 +458,12 @@ static int __init kvm_devices_init(void)
> > > > }
> > > >  
> > > > kvm_devices = (void *) real_memory_size;
> > > > +   if (test_devices_support() < 0) {
> > > > +   vmem_remove_mapping(real_memory_size, PAGE_SIZE);
> > > > +   root_device_unregister(kvm_root);
> > > > +   /* No error. */
> > > > +   return 0;
> > > > +   }
> > > >  
> > > 
> > > Cleaner to defer root_device_register() until after the mapping has been
> > > verified.
> > 
> > OK, will reorder.
> 
> Please use the "lura" instruction to figure out if the guest real page
> even exists _before_ creating the mapping.
> That way you don't need all the code afterwards.

New instruction of the day ;)

Indeed, this makes the code look nicer.




Re: [Qemu-devel] [PATCH 3/4] s390/kvm: Add a channel I/O based virtio transport driver.

2012-08-13 Thread Cornelia Huck
On Wed, 08 Aug 2012 13:52:57 +0930
Rusty Russell  wrote:

> On Tue,  7 Aug 2012 16:52:47 +0200, Cornelia Huck  
> wrote:
> > Add a driver for kvm guests that matches virtual ccw devices provided
> > by the host as virtio bridge devices.
> 
> Hi Cornelia,
> 
> OK, this is a good opportunity to fix some limitations, just as
> we did for virtio_mmio (drivers/virtio/virtio_mmio.c).
> 
> 1) Please don't limit yourself to 32 feature bits!  If you look at how
>virtio_mmio does it, they use a selector to index into a
>theoretically-infinite array of feature bits:
> 
>  * 0x010  R  HostFeatures Features supported by the host
>  * 0x014  W  HostFeaturesSel  Set of host features to access via HostFeatures
>  *
>  * 0x020  W  GuestFeaturesFeatures activated by the guest
>  * 0x024  W  GuestFeaturesSel Set of activated features to set via 
> GuestFeatures

It should be easy to extend the data processed by the feature ccws to a
feature/index combination. Would it be practical to limit the index to
an 8 bit value?

> 
> 2) Please also allow the guest to set the alignment for virtio ring
>layout (it controls the spacing between the rings), eg:
> 
>  * 0x03c  W  QueueAlign   Used Ring alignment for the current queue

I think the set_vq ccw could be extended with that info.

> 
> 3) Finally, make sure the guest can set the size of the queue, in case
>it can't allocate the size the host suggests, eg:
> 
>  * 0x034  R  QueueNumMax  Maximum size of the currently selected queue
>  * 0x038  W  QueueNum Queue size for the currently selected queue
> 
>This means the host can suggest huge queues, knowing the guest won't
>simply fail if it does so.

Makes sense, I didn't like just failing to allocate either. The actual
size could probably go into the set_vq ccw as well.

> 
> Note that we're also speculating a move to a new vring format, which
> will probably be little-endian.  But you probably want a completely new
> ccw code for that anyway.

Do you have a pointer to that discussion handy?

If the host may support different vring formats, I'll probably want to
add some kind of discovery mechanism for that as well (what discovery
mechanism depends on whether this would be per-device or per-machine).




Re: [Qemu-devel] [PATCH 2/4] s390: Add a mechanism to get the subchannel id.

2012-08-14 Thread Cornelia Huck
On Tue, 14 Aug 2012 10:52:09 +0200 (CEST)
Sebastian Ott  wrote:

> 
> On Tue, 7 Aug 2012, Cornelia Huck wrote:
> > +/**
> > + * ccw_device_get_schid - obtain a subchannel id
> > + * @cdev: device to obtain the id for
> > + * @schid: where to fill in the values
> > + */
> > +void ccw_device_get_schid(struct ccw_device *cdev, struct subchannel_id 
> > *schid)
> > +{
> > +   *schid = cdev->private->schid;
> > +}
> > +EXPORT_SYMBOL(ccw_device_get_schid);
> 
> After I gave this some thought I like your version of this function
> better. But please use the id of the parent subchannel instead of the
> copy in cdev->private (since this will be removed soon). I'll do a
> cleanup patch to convert the internal users of the old function to use
> the one above.

Good, will change that (I think we can rely on a ccw device always
having either a real subchannel or the orphanage pseudo subchannel as
parent).

Small taste question: EXPORT_SYMBOL vs EXPORT_SYMBOL_GPL?




Re: [Qemu-devel] [PATCH 3/4] s390/kvm: Add a channel I/O based virtio transport driver.

2012-08-14 Thread Cornelia Huck
On Tue, 14 Aug 2012 09:40:01 +0930
Rusty Russell  wrote:

> On Mon, 13 Aug 2012 10:56:38 +0200, Cornelia Huck  
> wrote:
> > On Wed, 08 Aug 2012 13:52:57 +0930
> > Rusty Russell  wrote:
> > 
> > > On Tue,  7 Aug 2012 16:52:47 +0200, Cornelia Huck 
> > >  wrote:
> > > 1) Please don't limit yourself to 32 feature bits!  If you look at how
> > >virtio_mmio does it, they use a selector to index into a
> > >theoretically-infinite array of feature bits:
> > 
> > It should be easy to extend the data processed by the feature ccws to a
> > feature/index combination. Would it be practical to limit the index to
> > an 8 bit value?
> 
> 256 feature bits?  That seems like it could one day be limiting.  Or an
> 8 bit accessor into feature words?  8192 seems enough for anyone sane.

An 8 bit accessor. I hope everybody stays on the sane side :)

> 
> > > Note that we're also speculating a move to a new vring format, which
> > > will probably be little-endian.  But you probably want a completely new
> > > ccw code for that anyway.
> > 
> > Do you have a pointer to that discussion handy?
> > 
> > If the host may support different vring formats, I'll probably want to
> > add some kind of discovery mechanism for that as well (what discovery
> > mechanism depends on whether this would be per-device or per-machine).
> 
> It would be per-machine; per-device would be a bit crazy.  We'd
> deprecate the old ring format.
> 
> There's been no consistent thread on the ideas for a ring change,
> unfortunately, but you can find interesting parts here, off this thread:
> 
> Message-ID: <8762gj6q5r@rustcorp.com.au>
> Subject: Re: [RFC 7/11] virtio_pci: new, capability-aware driver.

I've read a bit through this and it looks like this is really virtio-2
or so. How about discoverability by the guest? Guests will likely have
to support both formats, and forcing them to look at the feature bits
for each device in order to figure out the queue format feels wrong if
it is going to be the same format for the whole machine anyway.




Re: [Qemu-devel] [PATCH 5/6 v5] deal with guest panicked event accoring to -onpanic parameter

2012-06-27 Thread Cornelia Huck
On Wed, 27 Jun 2012 15:02:23 +0800
Wen Congyang  wrote:

> When the guest is panicked, it will write 0x1 to the port KVM_PV_PORT.
> So if qemu reads 0x1 from this port, we can do the folloing three
> things according to the parameter -onpanic:
> 1. emit QEVENT_GUEST_PANICKED only
> 2. emit QEVENT_GUEST_PANICKED and pause the guest
> 3. emit QEVENT_GUEST_PANICKED and poweroff the guest
> 4. emit QEVENT_GUEST_PANICKED and reset the guest

Would it be useful to add some "dump the guest" actions here?

> 
> Note: if we emit QEVENT_GUEST_PANICKED only, and the management
> application does not receive this event(the management may not
> run when the event is emitted), the management won't know the
> guest is panicked.
> 
> Signed-off-by: Wen Congyang 

> +static void kvm_pv_port_read(IORange *iorange, uint64_t offset, unsigned 
> width,
> + uint64_t *data)
> +{
> +*data = (1 << KVM_PV_FEATURE_PANICKED);
> +}

> +
> +static void kvm_pv_port_write(IORange *iorange, uint64_t offset, unsigned 
> width,
> +  uint64_t data)
> +{
> +if (data == KVM_PV_PANICKED) {
> +panicked_perform_action();
> +}
> +}
> +
> +static void kvm_pv_port_destructor(IORange *iorange)
> +{
> +g_free(iorange);
> +}
> +
> +static IORangeOps pv_io_range_ops = {
> +.read = kvm_pv_port_read,
> +.write = kvm_pv_port_write,
> +.destructor = kvm_pv_port_destructor,
> +};
> +
> +#if defined(KVM_PV_PORT)
> +void kvm_pv_port_init(void)
> +{
> +IORange *pv_io_range = g_malloc(sizeof(IORange));
> +
> +iorange_init(pv_io_range, &pv_io_range_ops, KVM_PV_PORT, 1);
> +ioport_register(pv_io_range);
> +}
> +#else
> +void kvm_pv_port_init(void)
> +{
> +}
> +#endif

> @@ -3641,6 +3647,10 @@ int main(int argc, char **argv, char **envp)
>  }
>  }
> 
> +if (kvm_enabled()) {
> +kvm_pv_port_init();
> +}
> +
>  if (incoming) {
>  Error *errp = NULL;
>  int ret = qemu_start_incoming_migration(incoming, &errp);

I/O ports won't work for s390, yet we'll likely want panic
notifications there as well. This will need some more abstraction.

Cornelia




[Qemu-devel] [PATCH 5/8] s390: Virtual channel subsystem support.

2012-12-07 Thread Cornelia Huck
Provide a mechanism for qemu to provide fully virtual subchannels to
the guest.

Signed-off-by: Cornelia Huck 
---
 hw/s390x/Makefile.objs |1 +
 hw/s390x/css.c | 1195 
 hw/s390x/css.h |   92 
 target-s390x/cpu.h |   65 +++
 trace-events   |8 +
 5 files changed, 1361 insertions(+)
 create mode 100644 hw/s390x/css.c
 create mode 100644 hw/s390x/css.h

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 096dfcd..378b099 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -4,3 +4,4 @@ obj-y := $(addprefix ../,$(obj-y))
 obj-y += sclp.o
 obj-y += event-facility.o
 obj-y += sclpquiesce.o sclpconsole.o
+obj-y += css.o
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
new file mode 100644
index 000..0604871
--- /dev/null
+++ b/hw/s390x/css.c
@@ -0,0 +1,1195 @@
+/*
+ * Channel subsystem base support.
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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-thread.h"
+#include "qemu-queue.h"
+#include 
+#include "bitops.h"
+#include "kvm.h"
+#include "cpu.h"
+#include "ioinst.h"
+#include "css.h"
+#include "trace.h"
+
+typedef struct CrwContainer {
+CRW crw;
+QTAILQ_ENTRY(CrwContainer) sibling;
+} CrwContainer;
+
+typedef struct ChpInfo {
+uint8_t in_use;
+uint8_t type;
+uint8_t is_virtual;
+} ChpInfo;
+
+typedef struct SubchSet {
+SubchDev *sch[MAX_SCHID + 1];
+unsigned long schids_used[BITS_TO_LONGS(MAX_SCHID + 1)];
+unsigned long devnos_used[BITS_TO_LONGS(MAX_SCHID + 1)];
+} SubchSet;
+
+typedef struct CssImage {
+SubchSet *sch_set[MAX_SSID + 1];
+ChpInfo chpids[MAX_CHPID + 1];
+} CssImage;
+
+typedef struct ChannelSubSys {
+QTAILQ_HEAD(, CrwContainer) pending_crws;
+bool do_crw_mchk;
+bool crws_lost;
+uint8_t max_cssid;
+uint8_t max_ssid;
+bool chnmon_active;
+uint64_t chnmon_area;
+CssImage *css[MAX_CSSID + 1];
+uint8_t default_cssid;
+} ChannelSubSys;
+
+static ChannelSubSys *channel_subsys;
+
+int css_create_css_image(uint8_t cssid, bool default_image)
+{
+trace_css_new_image(cssid, default_image ? "(default)" : "");
+if (cssid > MAX_CSSID) {
+return -EINVAL;
+}
+if (channel_subsys->css[cssid]) {
+return -EBUSY;
+}
+channel_subsys->css[cssid] = g_try_malloc0(sizeof(CssImage));
+if (!channel_subsys->css[cssid]) {
+return -ENOMEM;
+}
+if (default_image) {
+channel_subsys->default_cssid = cssid;
+}
+return 0;
+}
+
+static void css_write_phys_pmcw(uint64_t addr, PMCW *pmcw)
+{
+int i;
+PMCW copy;
+
+copy.intparm = ldl_p(&pmcw->intparm);
+copy.flags = lduw_p(&pmcw->flags);
+copy.devno = lduw_p(&pmcw->devno);
+copy.lpm = pmcw->lpm;
+copy.pnom = pmcw->pnom;
+copy.lpum = pmcw->lpum;
+copy.pim = pmcw->pim;
+copy.mbi = lduw_p(&pmcw->mbi);
+copy.pom = pmcw->pom;
+copy.pam = pmcw->pam;
+for (i = 0; i < 8; i++) {
+copy.chpid[i] = pmcw->chpid[i];
+}
+copy.chars = ldl_p(&pmcw->chars);
+cpu_physical_memory_write(addr, ©, sizeof(PMCW));
+}
+
+static void css_write_phys_scsw(uint64_t addr, SCSW *scsw)
+{
+SCSW copy;
+
+copy.flags = lduw_p(&scsw->flags);
+copy.ctrl = lduw_p(&scsw->ctrl);
+copy.cpa = ldl_p(&scsw->cpa);
+copy.dstat = scsw->dstat;
+copy.cstat = scsw->cstat;
+copy.count = lduw_p(&scsw->count);
+cpu_physical_memory_write(addr, ©, sizeof(SCSW));
+}
+
+static void css_inject_io_interrupt(SubchDev *sch)
+{
+S390CPU *cpu = s390_cpu_addr2state(0);
+uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 11;
+
+trace_css_io_interrupt(sch->cssid, sch->ssid, sch->schid,
+   sch->curr_status.pmcw.intparm, isc, "");
+s390_io_interrupt(&cpu->env,
+  channel_subsys->max_cssid > 0 ?
+  (sch->cssid << 8) | (1 << 3) | (sch->ssid << 1) | 1 :
+  (sch->ssid << 1) | 1,
+  sch->schid,
+  sch->curr_status.pmcw.intparm,
+  (0x80 >> isc) << 24);
+}
+
+void css_conditional_io_interrupt(SubchDev *sch)
+{
+/*
+ * If the subchannel is not currently status pending, make it pending
+ * with alert status.
+ */
+if (sch && !(sch->curr_status.scsw.ctrl & SCSW_STCTL_STATUS_PEND)) {
+S390CPU *cpu = s390_cpu_addr2state(0);
+uint8_t isc = (sch->curr_status.p

[Qemu-devel] [PATCH 7/8] s390-virtio: Factor out some initialization code.

2012-12-07 Thread Cornelia Huck
Some of the machine initialization for s390-virtio will be reused
by virtio-ccw.

Signed-off-by: Cornelia Huck 
---
 hw/s390-virtio.c | 132 +--
 1 file changed, 79 insertions(+), 53 deletions(-)

diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 685cb54..9e1afb2 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -151,60 +151,12 @@ unsigned s390_del_running_cpu(CPUS390XState *env)
 return s390_running_cpus;
 }
 
-/* PC hardware initialisation */
-static void s390_init(QEMUMachineInitArgs *args)
+static CPUS390XState *s390_init_cpus(const char *cpu_model,
+ uint8_t *storage_keys)
 {
-ram_addr_t my_ram_size = args->ram_size;
-ram_addr_t ram_size = args->ram_size;
-const char *cpu_model = args->cpu_model;
-const char *kernel_filename = args->kernel_filename;
-const char *kernel_cmdline = args->kernel_cmdline;
-const char *initrd_filename = args->initrd_filename;
 CPUS390XState *env = NULL;
-MemoryRegion *sysmem = get_system_memory();
-MemoryRegion *ram = g_new(MemoryRegion, 1);
-ram_addr_t kernel_size = 0;
-ram_addr_t initrd_offset;
-ram_addr_t initrd_size = 0;
-int shift = 0;
-uint8_t *storage_keys;
-void *virtio_region;
-hwaddr virtio_region_len;
-hwaddr virtio_region_start;
 int i;
 
-/* s390x ram size detection needs a 16bit multiplier + an increment. So
-   guests > 64GB can be specified in 2MB steps etc. */
-while ((my_ram_size >> (20 + shift)) > 65535) {
-shift++;
-}
-my_ram_size = my_ram_size >> (20 + shift) << (20 + shift);
-
-/* lets propagate the changed ram size into the global variable. */
-ram_size = my_ram_size;
-
-/* get a BUS */
-s390_bus = s390_virtio_bus_init(&my_ram_size);
-s390_sclp_init();
-
-/* allocate RAM */
-memory_region_init_ram(ram, "s390.ram", my_ram_size);
-vmstate_register_ram_global(ram);
-memory_region_add_subregion(sysmem, 0, ram);
-
-/* clear virtio region */
-virtio_region_len = my_ram_size - ram_size;
-virtio_region_start = ram_size;
-virtio_region = cpu_physical_memory_map(virtio_region_start,
-&virtio_region_len, true);
-memset(virtio_region, 0, virtio_region_len);
-cpu_physical_memory_unmap(virtio_region, virtio_region_len, 1,
-  virtio_region_len);
-
-/* allocate storage keys */
-storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE);
-
-/* init CPUs */
 if (cpu_model == NULL) {
 cpu_model = "host";
 }
@@ -225,6 +177,17 @@ static void s390_init(QEMUMachineInitArgs *args)
 tmp_env->exception_index = EXCP_HLT;
 tmp_env->storage_keys = storage_keys;
 }
+return env;
+}
+
+static void s390_set_up_kernel(CPUS390XState *env,
+   const char *kernel_filename,
+   const char *kernel_cmdline,
+   const char *initrd_filename)
+{
+ram_addr_t kernel_size = 0;
+ram_addr_t initrd_offset;
+ram_addr_t initrd_size = 0;
 
 /* One CPU has to run */
 s390_add_running_cpu(env);
@@ -296,9 +259,13 @@ static void s390_init(QEMUMachineInitArgs *args)
 memcpy(rom_ptr(KERN_PARM_AREA), kernel_cmdline,
strlen(kernel_cmdline) + 1);
 }
+}
 
-/* Create VirtIO network adapters */
-for(i = 0; i < nb_nics; i++) {
+static void s390_create_virtio_net(BusState *bus, const char *name)
+{
+int i;
+
+for (i = 0; i < nb_nics; i++) {
 NICInfo *nd = &nd_table[i];
 DeviceState *dev;
 
@@ -311,10 +278,69 @@ static void s390_init(QEMUMachineInitArgs *args)
 exit(1);
 }
 
-dev = qdev_create((BusState *)s390_bus, "virtio-net-s390");
+dev = qdev_create(bus, name);
 qdev_set_nic_properties(dev, nd);
 qdev_init_nofail(dev);
 }
+}
+
+/* PC hardware initialisation */
+static void s390_init(QEMUMachineInitArgs *args)
+{
+ram_addr_t my_ram_size = args->ram_size;
+ram_addr_t ram_size = args->ram_size;
+const char *cpu_model = args->cpu_model;
+const char *kernel_filename = args->kernel_filename;
+const char *kernel_cmdline = args->kernel_cmdline;
+const char *initrd_filename = args->initrd_filename;
+CPUS390XState *env = NULL;
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+int shift = 0;
+uint8_t *storage_keys;
+void *virtio_region;
+hwaddr virtio_region_len;
+hwaddr virtio_region_start;
+int i;
+
+/* s390x ram size detection needs a 16bit multiplier + an increment. So
+   guests > 64GB can be specified in 2MB steps etc. */
+while ((my_ram_size >> (20 + shift)) > 65535) {
+shift++;

Re: [Qemu-devel] [PATCH 1/8] Update linux headers.

2012-12-07 Thread Cornelia Huck
On Fri, 7 Dec 2012 13:01:27 +
Peter Maydell  wrote:

> On 7 December 2012 12:50, Cornelia Huck  wrote:
> > Signed-off-by: Cornelia Huck 
> 
> I think it would be good if commit messages for linux-headers
> updates stated the kernel tree and commit that the updated headers
> come from.

This one should be in sync with kvm-next; I'll try to be more specific
when I'll submit this code for inclusion.




[Qemu-devel] [PATCH 8/8] s390: Add new channel I/O based virtio transport.

2012-12-07 Thread Cornelia Huck
Add a new virtio transport that uses channel commands to perform
virtio operations.

Add a new machine type s390-ccw that uses this virtio-ccw transport
and make it the default machine for s390.

Signed-off-by: Cornelia Huck 
---
 hw/s390-virtio.c   | 149 ++--
 hw/s390x/Makefile.objs |   1 +
 hw/s390x/virtio-ccw.c  | 909 +
 hw/s390x/virtio-ccw.h  |  81 +
 trace-events   |   4 +
 5 files changed, 1124 insertions(+), 20 deletions(-)
 create mode 100644 hw/s390x/virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.h

diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 9e1afb2..f29ff74 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -33,6 +33,8 @@
 
 #include "hw/s390-virtio-bus.h"
 #include "hw/s390x/sclp.h"
+#include "hw/s390x/css.h"
+#include "hw/s390x/virtio-ccw.h"
 
 //#define DEBUG_S390
 
@@ -47,6 +49,7 @@
 #define KVM_S390_VIRTIO_NOTIFY  0
 #define KVM_S390_VIRTIO_RESET   1
 #define KVM_S390_VIRTIO_SET_STATUS  2
+#define KVM_S390_VIRTIO_CCW_NOTIFY  3
 
 #define KERN_IMAGE_START0x01UL
 #define KERN_PARM_AREA  0x010480UL
@@ -63,6 +66,7 @@
 
 static VirtIOS390Bus *s390_bus;
 static S390CPU **ipi_states;
+VirtioCcwBus *ccw_bus;
 
 S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
 {
@@ -76,15 +80,21 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
 int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall)
 {
 int r = 0, i;
+int cssid, ssid, schid, m;
+SubchDev *sch;
 
 dprintf("KVM hypercall: %ld\n", hypercall);
 switch (hypercall) {
 case KVM_S390_VIRTIO_NOTIFY:
 if (mem > ram_size) {
-VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
-   mem, &i);
-if (dev) {
-virtio_queue_notify(dev->vdev, i);
+if (s390_bus) {
+VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
+   mem, &i);
+if (dev) {
+virtio_queue_notify(dev->vdev, i);
+} else {
+r = -EINVAL;
+}
 } else {
 r = -EINVAL;
 }
@@ -93,28 +103,49 @@ int s390_virtio_hypercall(CPUS390XState *env, uint64_t 
mem, uint64_t hypercall)
 }
 break;
 case KVM_S390_VIRTIO_RESET:
-{
-VirtIOS390Device *dev;
-
-dev = s390_virtio_bus_find_mem(s390_bus, mem);
-virtio_reset(dev->vdev);
-stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0);
-s390_virtio_device_sync(dev);
-s390_virtio_reset_idx(dev);
+if (s390_bus) {
+VirtIOS390Device *dev;
+
+dev = s390_virtio_bus_find_mem(s390_bus, mem);
+virtio_reset(dev->vdev);
+stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0);
+s390_virtio_device_sync(dev);
+s390_virtio_reset_idx(dev);
+} else {
+r = -EINVAL;
+}
 break;
-}
 case KVM_S390_VIRTIO_SET_STATUS:
-{
-VirtIOS390Device *dev;
+if (s390_bus) {
+VirtIOS390Device *dev;
 
-dev = s390_virtio_bus_find_mem(s390_bus, mem);
-if (dev) {
-s390_virtio_device_update_status(dev);
+dev = s390_virtio_bus_find_mem(s390_bus, mem);
+if (dev) {
+s390_virtio_device_update_status(dev);
+} else {
+r = -EINVAL;
+}
 } else {
 r = -EINVAL;
 }
 break;
-}
+case KVM_S390_VIRTIO_CCW_NOTIFY:
+if (ccw_bus) {
+if (ioinst_disassemble_sch_ident(env->regs[2], &m, &cssid, &ssid,
+ &schid)) {
+r = -EINVAL;
+} else {
+sch = css_find_subch(m, cssid, ssid, schid);
+if (sch && css_subch_visible(sch)) {
+virtio_queue_notify(virtio_ccw_get_vdev(sch), 
env->regs[3]);
+} else {
+r = -EINVAL;
+}
+}
+ } else {
+ r = -EINVAL;
+ }
+ break;
 default:
 r = -EINVAL;
 break;
@@ -370,7 +401,6 @@ static QEMUMachine s390_machine = {
 .no_sdcard = 1,
 .use_virtcon = 1,
 .max_cpus = 255,
-.is_default = 1,
 };
 
 static void s390_machine_init(void)
@@ -379,3 +409,82 @@ static void s390_machine_init(void)
 }
 
 machine_init(s390_machine_init);
+
+static void ccw_init(QEMUMachineInitArgs *args)
+{
+ram_addr_t my_ram_size = args->ram_size;
+ram_addr_t ram_size = args->ram_size;
+const char *cpu_model = args->cpu_model;
+const 

[Qemu-devel] [PATCH 3/8] s390: I/O interrupt and machine check injection.

2012-12-07 Thread Cornelia Huck
I/O interrupts are queued per isc. Only crw pending machine checks
are supported.

Signed-off-by: Cornelia Huck 
---
 target-s390x/cpu.h|  67 +++
 target-s390x/helper.c | 145 ++
 2 files changed, 212 insertions(+)

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 0f9a1f7..73bfc20 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -47,6 +47,11 @@
 #define MMU_USER_IDX 1
 
 #define MAX_EXT_QUEUE 16
+#define MAX_IO_QUEUE 16
+#define MAX_MCHK_QUEUE 16
+
+#define PSW_MCHK_MASK 0x0004
+#define PSW_IO_MASK 0x0200
 
 typedef struct PSW {
 uint64_t mask;
@@ -59,6 +64,17 @@ typedef struct ExtQueue {
 uint32_t param64;
 } ExtQueue;
 
+typedef struct IOQueue {
+uint16_t id;
+uint16_t nr;
+uint32_t parm;
+uint32_t word;
+} IOQueue;
+
+typedef struct MchkQueue {
+uint16_t type;
+} MchkQueue;
+
 typedef struct CPUS390XState {
 uint64_t regs[16]; /* GP registers */
 
@@ -88,8 +104,16 @@ typedef struct CPUS390XState {
 
 int pending_int;
 ExtQueue ext_queue[MAX_EXT_QUEUE];
+IOQueue io_queue[MAX_IO_QUEUE][8];
+MchkQueue mchk_queue[MAX_MCHK_QUEUE];
 
 int ext_index;
+int io_index[8];
+int mchk_index;
+
+uint64_t ckc;
+uint64_t cputm;
+uint32_t todpr;
 
 CPU_COMMON
 
@@ -364,12 +388,16 @@ static inline void cpu_set_tls(CPUS390XState *env, 
target_ulong newtls)
 #define EXCP_EXT 1 /* external interrupt */
 #define EXCP_SVC 2 /* supervisor call (syscall) */
 #define EXCP_PGM 3 /* program interruption */
+#define EXCP_IO  7 /* I/O interrupt */
+#define EXCP_MCHK 8 /* machine check */
 
 #endif /* CONFIG_USER_ONLY */
 
 #define INTERRUPT_EXT(1 << 0)
 #define INTERRUPT_TOD(1 << 1)
 #define INTERRUPT_CPUTIMER   (1 << 2)
+#define INTERRUPT_IO (1 << 3)
+#define INTERRUPT_MCHK   (1 << 4)
 
 /* Program Status Word.  */
 #define S390_PSWM_REGNUM 0
@@ -977,6 +1005,45 @@ static inline void cpu_inject_ext(CPUS390XState *env, 
uint32_t code, uint32_t pa
 cpu_interrupt(env, CPU_INTERRUPT_HARD);
 }
 
+static inline void cpu_inject_io(CPUS390XState *env, uint16_t subchannel_id,
+ uint16_t subchannel_number,
+ uint32_t io_int_parm, uint32_t io_int_word)
+{
+int isc = ffs(io_int_word << 2) - 1;
+
+if (env->io_index[isc] == MAX_IO_QUEUE - 1) {
+/* ugh - can't queue anymore. Let's drop. */
+return;
+}
+
+env->io_index[isc]++;
+assert(env->io_index[isc] < MAX_IO_QUEUE);
+
+env->io_queue[env->io_index[isc]][isc].id = subchannel_id;
+env->io_queue[env->io_index[isc]][isc].nr = subchannel_number;
+env->io_queue[env->io_index[isc]][isc].parm = io_int_parm;
+env->io_queue[env->io_index[isc]][isc].word = io_int_word;
+
+env->pending_int |= INTERRUPT_IO;
+cpu_interrupt(env, CPU_INTERRUPT_HARD);
+}
+
+static inline void cpu_inject_crw_mchk(CPUS390XState *env)
+{
+if (env->mchk_index == MAX_MCHK_QUEUE - 1) {
+/* ugh - can't queue anymore. Let's drop. */
+return;
+}
+
+env->mchk_index++;
+assert(env->mchk_index < MAX_MCHK_QUEUE);
+
+env->mchk_queue[env->mchk_index].type = 1;
+
+env->pending_int |= INTERRUPT_MCHK;
+cpu_interrupt(env, CPU_INTERRUPT_HARD);
+}
+
 static inline bool cpu_has_work(CPUState *cpu)
 {
 CPUS390XState *env = &S390_CPU(cpu)->env;
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index b7b812a..4ff148d 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -574,12 +574,144 @@ static void do_ext_interrupt(CPUS390XState *env)
 load_psw(env, mask, addr);
 }
 
+static void do_io_interrupt(CPUS390XState *env)
+{
+uint64_t mask, addr;
+LowCore *lowcore;
+hwaddr len = TARGET_PAGE_SIZE;
+IOQueue *q;
+uint8_t isc;
+int disable = 1;
+int found = 0;
+
+if (!(env->psw.mask & PSW_MASK_IO)) {
+cpu_abort(env, "I/O int w/o I/O mask\n");
+}
+
+for (isc = 0; isc < 8; isc++) {
+if (env->io_index[isc] < 0) {
+continue;
+}
+if (env->io_index[isc] > MAX_IO_QUEUE) {
+cpu_abort(env, "I/O queue overrun for isc %d: %d\n",
+  isc, env->io_index[isc]);
+}
+
+q = &env->io_queue[env->io_index[isc]][isc];
+if (!(env->cregs[6] & q->word)) {
+disable = 0;
+continue;
+}
+found = 1;
+lowcore = cpu_physical_memory_map(env->psa, &len, 1);
+
+lowcore->subchannel_id = cpu_to_be16(q->id);
+lowcore->subchannel_nr = cpu_to_be16(q->nr);
+lowcore->io_int_parm = cpu_to_be32(q->parm);
+lowcore->io_int_word = cpu_to_be32(q->word);
+  

[Qemu-devel] [PATCH 1/8] Update linux headers.

2012-12-07 Thread Cornelia Huck
Signed-off-by: Cornelia Huck 
---
 linux-headers/asm-generic/kvm_para.h |  4 +++
 linux-headers/asm-powerpc/kvm.h  | 59 
 linux-headers/asm-powerpc/kvm_para.h |  7 +++--
 linux-headers/linux/kvm.h| 36 +++---
 4 files changed, 98 insertions(+), 8 deletions(-)
 create mode 100644 linux-headers/asm-generic/kvm_para.h

diff --git a/linux-headers/asm-generic/kvm_para.h 
b/linux-headers/asm-generic/kvm_para.h
new file mode 100644
index 000..486f0af
--- /dev/null
+++ b/linux-headers/asm-generic/kvm_para.h
@@ -0,0 +1,4 @@
+/*
+ * There isn't anything here, but the file must not be empty or patch
+ * will delete it.
+ */
diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
index 1bea4d8..b89ae4d 100644
--- a/linux-headers/asm-powerpc/kvm.h
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -221,6 +221,12 @@ struct kvm_sregs {
 
__u32 dbsr; /* KVM_SREGS_E_UPDATE_DBSR */
__u32 dbcr[3];
+   /*
+* iac/dac registers are 64bit wide, while this API
+* interface provides only lower 32 bits on 64 bit
+* processors. ONE_REG interface is added for 64bit
+* iac/dac registers.
+*/
__u32 iac[4];
__u32 dac[2];
__u32 dvc[2];
@@ -326,5 +332,58 @@ struct kvm_book3e_206_tlb_params {
 };
 
 #define KVM_REG_PPC_HIOR   (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x1)
+#define KVM_REG_PPC_IAC1   (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x2)
+#define KVM_REG_PPC_IAC2   (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3)
+#define KVM_REG_PPC_IAC3   (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x4)
+#define KVM_REG_PPC_IAC4   (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x5)
+#define KVM_REG_PPC_DAC1   (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x6)
+#define KVM_REG_PPC_DAC2   (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x7)
+#define KVM_REG_PPC_DABR   (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8)
+#define KVM_REG_PPC_DSCR   (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x9)
+#define KVM_REG_PPC_PURR   (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa)
+#define KVM_REG_PPC_SPURR  (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb)
+#define KVM_REG_PPC_DAR(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc)
+#define KVM_REG_PPC_DSISR  (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xd)
+#define KVM_REG_PPC_AMR(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xe)
+#define KVM_REG_PPC_UAMOR  (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xf)
+
+#define KVM_REG_PPC_MMCR0  (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x10)
+#define KVM_REG_PPC_MMCR1  (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x11)
+#define KVM_REG_PPC_MMCRA  (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x12)
+
+#define KVM_REG_PPC_PMC1   (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x18)
+#define KVM_REG_PPC_PMC2   (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x19)
+#define KVM_REG_PPC_PMC3   (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1a)
+#define KVM_REG_PPC_PMC4   (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1b)
+#define KVM_REG_PPC_PMC5   (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1c)
+#define KVM_REG_PPC_PMC6   (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1d)
+#define KVM_REG_PPC_PMC7   (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1e)
+#define KVM_REG_PPC_PMC8   (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1f)
+
+/* 32 floating-point registers */
+#define KVM_REG_PPC_FPR0   (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x20)
+#define KVM_REG_PPC_FPR(n) (KVM_REG_PPC_FPR0 + (n))
+#define KVM_REG_PPC_FPR31  (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3f)
+
+/* 32 VMX/Altivec vector registers */
+#define KVM_REG_PPC_VR0(KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x40)
+#define KVM_REG_PPC_VR(n)  (KVM_REG_PPC_VR0 + (n))
+#define KVM_REG_PPC_VR31   (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x5f)
+
+/* 32 double-width FP registers for VSX */
+/* High-order halves overlap with FP regs */
+#define KVM_REG_PPC_VSR0   (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x60)
+#define KVM_REG_PPC_VSR(n) (KVM_REG_PPC_VSR0 + (n))
+#define KVM_REG_PPC_VSR31  (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x7f)
+
+/* FP and vector status/control registers */
+#define KVM_REG_PPC_FPSCR  (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x80)
+#define KVM_REG_PPC_VSCR   (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x81)
+
+/* Virtual processor areas */
+/* For SLB & DTL, address in high (first) half, length in low half */
+#define KVM_REG_PPC_VPA_ADDR   (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x82)
+#define KVM_REG_PPC_VPA_SLB(KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x83)
+#define KVM_REG_PPC_VPA_DTL(KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84)
 
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/linux-headers/asm-powerpc/kvm_para.h 
b/linux-headers/asm-powerpc/kvm_para.h
index 5e04383..ed0e025 100644
--- a/linux-headers/asm-powerpc/kvm_para.h
+++ b/linux-headers/asm-powerpc/kvm_para.h
@@ -75,9 +75,10 @@ struct kvm_vcpu_ar

[Qemu-devel] [PATCH 2/8] s390: Channel I/O basic defintions.

2012-12-07 Thread Cornelia Huck
Basic channel I/O structures and helper function.

Signed-off-by: Cornelia Huck 
---
 target-s390x/Makefile.objs |   2 +-
 target-s390x/ioinst.c  |  46 ++
 target-s390x/ioinst.h  | 207 +
 3 files changed, 254 insertions(+), 1 deletion(-)
 create mode 100644 target-s390x/ioinst.c
 create mode 100644 target-s390x/ioinst.h

diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index e728abf..3afb0b7 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,4 +1,4 @@
 obj-y += translate.o helper.o cpu.o interrupt.o
 obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
-obj-$(CONFIG_SOFTMMU) += machine.o
+obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o
 obj-$(CONFIG_KVM) += kvm.o
diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
new file mode 100644
index 000..8577b2c
--- /dev/null
+++ b/target-s390x/ioinst.c
@@ -0,0 +1,46 @@
+/*
+ * I/O instructions for S/390
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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 
+#include 
+#include 
+
+#include "cpu.h"
+#include "ioinst.h"
+
+#ifdef DEBUG_IOINST
+#define dprintf(fmt, ...) \
+do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define dprintf(fmt, ...) \
+do { } while (0)
+#endif
+
+int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
+ int *schid)
+{
+if (!(value & IOINST_SCHID_ONE)) {
+return -EINVAL;
+}
+if (!(value & IOINST_SCHID_M)) {
+if (value & IOINST_SCHID_CSSID) {
+return -EINVAL;
+}
+*cssid = 0;
+*m = 0;
+} else {
+*cssid = (value & IOINST_SCHID_CSSID) >> 24;
+*m = 1;
+}
+*ssid = (value & IOINST_SCHID_SSID) >> 17;
+*schid = value & IOINST_SCHID_NR;
+return 0;
+}
diff --git a/target-s390x/ioinst.h b/target-s390x/ioinst.h
new file mode 100644
index 000..b5b4a03
--- /dev/null
+++ b/target-s390x/ioinst.h
@@ -0,0 +1,207 @@
+/*
+ * S/390 channel I/O instructions
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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 IOINST_S390X_H
+#define IOINST_S390X_H
+/*
+ * Channel I/O related definitions, as defined in the Principles
+ * Of Operation (and taken from the Linux implementation).
+ */
+
+/* subchannel status word (command mode only) */
+typedef struct SCSW {
+uint16_t flags;
+uint16_t ctrl;
+uint32_t cpa;
+uint8_t dstat;
+uint8_t cstat;
+uint16_t count;
+} QEMU_PACKED SCSW;
+
+#define SCSW_FLAGS_MASK_KEY 0xf000
+#define SCSW_FLAGS_MASK_SCTL 0x0800
+#define SCSW_FLAGS_MASK_ESWF 0x0400
+#define SCSW_FLAGS_MASK_CC 0x0300
+#define SCSW_FLAGS_MASK_FMT 0x0080
+#define SCSW_FLAGS_MASK_PFCH 0x0040
+#define SCSW_FLAGS_MASK_ISIC 0x0020
+#define SCSW_FLAGS_MASK_ALCC 0x0010
+#define SCSW_FLAGS_MASK_SSI 0x0008
+#define SCSW_FLAGS_MASK_ZCC 0x0004
+#define SCSW_FLAGS_MASK_ECTL 0x0002
+#define SCSW_FLAGS_MASK_PNO 0x0001
+
+#define SCSW_CTRL_MASK_FCTL 0x7000
+#define SCSW_CTRL_MASK_ACTL 0x0fe0
+#define SCSW_CTRL_MASK_STCTL 0x001f
+
+#define SCSW_FCTL_CLEAR_FUNC 0x1000
+#define SCSW_FCTL_HALT_FUNC 0x2000
+#define SCSW_FCTL_START_FUNC 0x4000
+
+#define SCSW_ACTL_SUSP 0x0020
+#define SCSW_ACTL_DEVICE_ACTIVE 0x0040
+#define SCSW_ACTL_SUBCH_ACTIVE 0x0080
+#define SCSW_ACTL_CLEAR_PEND 0x0100
+#define SCSW_ACTL_HALT_PEND  0x0200
+#define SCSW_ACTL_START_PEND 0x0400
+#define SCSW_ACTL_RESUME_PEND 0x0800
+
+#define SCSW_STCTL_STATUS_PEND 0x0001
+#define SCSW_STCTL_SECONDARY 0x0002
+#define SCSW_STCTL_PRIMARY 0x0004
+#define SCSW_STCTL_INTERMEDIATE 0x0008
+#define SCSW_STCTL_ALERT 0x0010
+
+#define SCSW_DSTAT_ATTENTION 0x80
+#define SCSW_DSTAT_STAT_MOD  0x40
+#define SCSW_DSTAT_CU_END0x20
+#define SCSW_DSTAT_BUSY  0x10
+#define SCSW_DSTAT_CHANNEL_END   0x08
+#define SCSW_DSTAT_DEVICE_END0x04
+#define SCSW_DSTAT_UNIT_CHECK0x02
+#define SCSW_DSTAT_UNIT_EXCEP0x01
+
+#define SCSW_CSTAT_PCI   0x80
+#define SCSW_CSTAT_INCORR_LEN0x40
+#define SCSW_CSTAT_PROG_CHECK0x20
+#define SCSW_CSTAT_PROT_CHECK0x10
+#define SCSW_CSTAT_DATA_CHECK0x08
+#define SCSW_CSTAT_CHN_CTRL_CHK  0x04
+#define SCSW_CSTAT_INTF_CTRL_CHK 0x02
+#define SCSW_CSTAT_CHAIN_CHECK   0x01
+
+/* path management control word */
+typedef struct PMCW {
+uint32_t intparm;
+uint16_t flags;
+uint16_t devno;
+uint8_t  lpm;
+uint8_t  pnom;
+uint8_t  lpum;
+uint8_t  pim;
+uint16_t mbi;
+uint8_t  pom;
+uint8_t  pam;
+uint8_t  chpid[8];
+uint32_t chars;
+} QEMU_PA

[Qemu-devel] [PATCH 6/8] s390: Wire up channel I/O in kvm.

2012-12-07 Thread Cornelia Huck
Trigger the code for our virtual css in case of instruction
intercepts for I/O instructions.

Handle the tsch exit for the subchannel-related part of tsch.

Signed-off-by: Cornelia Huck 
---
 target-s390x/cpu.h |  11 +++
 target-s390x/kvm.c | 246 ++---
 2 files changed, 244 insertions(+), 13 deletions(-)

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index eb24c6b..1d21ca8 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1178,6 +1178,13 @@ uint32_t set_cc_nz_f64(float64 v);
 /* misc_helper.c */
 void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
 
+#ifdef CONFIG_KVM
+int kvm_s390_io_interrupt(CPUS390XState *env, uint16_t subchannel_id,
+  uint16_t subchannel_nr, uint32_t io_int_parm,
+  uint32_t io_int_word);
+int kvm_s390_crw_mchk(CPUS390XState *env);
+void kvm_s390_enable_css_support(CPUS390XState *env);
+#else
 static inline int kvm_s390_io_interrupt(CPUS390XState *env,
 uint16_t subchannel_id,
 uint16_t subchannel_nr,
@@ -1190,6 +1197,10 @@ static inline int kvm_s390_crw_mchk(CPUS390XState *env)
 {
 return -EOPNOTSUPP;
 }
+static inline void kvm_s390_enable_css_support(CPUS390XState *env)
+{
+}
+#endif
 
 static inline void s390_io_interrupt(CPUS390XState *env,
  uint16_t subchannel_id,
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 94de764..c9a4a7d 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -30,6 +30,7 @@
 #include "kvm.h"
 #include "cpu.h"
 #include "device_tree.h"
+#include "ioinst.h"
 
 /* #define DEBUG_KVM */
 
@@ -43,9 +44,27 @@
 
 #define IPA0_DIAG   0x8300
 #define IPA0_SIGP   0xae00
-#define IPA0_PRIV   0xb200
+#define IPA0_B2 0xb200
+#define IPA0_B9 0xb900
+#define IPA0_EB 0xeb00
 
 #define PRIV_SCLP_CALL  0x20
+#define PRIV_CSCH   0x30
+#define PRIV_HSCH   0x31
+#define PRIV_MSCH   0x32
+#define PRIV_SSCH   0x33
+#define PRIV_STSCH  0x34
+#define PRIV_TSCH   0x35
+#define PRIV_TPI0x36
+#define PRIV_SAL0x37
+#define PRIV_RSCH   0x38
+#define PRIV_STCRW  0x39
+#define PRIV_STCPS  0x3a
+#define PRIV_RCHP   0x3b
+#define PRIV_SCHM   0x3c
+#define PRIV_CHSC   0x5f
+#define PRIV_SIGA   0x74
+#define PRIV_XSCH   0x76
 #define DIAG_KVM_HYPERCALL  0x500
 #define DIAG_KVM_BREAKPOINT 0x501
 
@@ -350,10 +369,120 @@ static int kvm_sclp_service_call(CPUS390XState *env, 
struct kvm_run *run,
 return 0;
 }
 
-static int handle_priv(CPUS390XState *env, struct kvm_run *run, uint8_t ipa1)
+static int kvm_handle_css_inst(CPUS390XState *env, struct kvm_run *run,
+   uint8_t ipa0, uint8_t ipa1, uint8_t ipb)
+{
+int r = 0;
+int no_cc = 0;
+
+if (ipa0 != 0xb2) {
+/* Not handled for now. */
+return -1;
+}
+cpu_synchronize_state(env);
+switch (ipa1) {
+case PRIV_XSCH:
+r = ioinst_handle_xsch(env, env->regs[1]);
+break;
+case PRIV_CSCH:
+r = ioinst_handle_csch(env, env->regs[1]);
+break;
+case PRIV_HSCH:
+r = ioinst_handle_hsch(env, env->regs[1]);
+break;
+case PRIV_MSCH:
+r = ioinst_handle_msch(env, env->regs[1], run->s390_sieic.ipb);
+break;
+case PRIV_SSCH:
+r = ioinst_handle_ssch(env, env->regs[1], run->s390_sieic.ipb);
+break;
+case PRIV_STCRW:
+r = ioinst_handle_stcrw(env, run->s390_sieic.ipb);
+break;
+case PRIV_STSCH:
+r = ioinst_handle_stsch(env, env->regs[1], run->s390_sieic.ipb);
+break;
+case PRIV_TSCH:
+/* We should only get tsch via KVM_EXIT_S390_TSCH. */
+fprintf(stderr, "Spurious tsch intercept\n");
+break;
+case PRIV_CHSC:
+r = ioinst_handle_chsc(env, run->s390_sieic.ipb);
+break;
+case PRIV_TPI:
+/* This should have been handled by kvm already. */
+fprintf(stderr, "Spurious tpi intercept\n");
+break;
+case PRIV_SCHM:
+no_cc = 1;
+r = ioinst_handle_schm(env, env->regs[1], env->regs[2],
+   run->s390_sieic.ipb);
+break;
+case PRIV_RSCH:
+r = ioinst_handle_rsch(env, env->regs[1]);
+break;
+case PRIV_RCHP:
+r = ioinst_handle_rchp(env, env->regs[1]);
+brea

[Qemu-devel] [RFC PATCH v4 0/8] s390: channel I/O support in qemu.

2012-12-07 Thread Cornelia Huck
Hi,

just a quick dump of my qemu patch series for channel I/O.

I've managed to chop the virtual css patch into some smaller
chunks (patches 2-6), which are hopefully easier to review.

The virtio-ccw patch is still based upon the current virtio
infrastructure; I'll try to rebase it upon the virtio refactoring
once that has most of the infrastructure in place.

Cornelia Huck (8):
  Update linux headers.
  s390: Channel I/O basic defintions.
  s390: I/O interrupt and machine check injection.
  s390: Add channel I/O instructions.
  s390: Virtual channel subsystem support.
  s390: Wire up channel I/O in kvm.
  s390-virtio: Factor out some initialization code.
  s390: Add new channel I/O based virtio transport.

 hw/s390-virtio.c |  281 +---
 hw/s390x/Makefile.objs   |2 +
 hw/s390x/css.c   | 1195 ++
 hw/s390x/css.h   |   92 +++
 hw/s390x/virtio-ccw.c|  909 ++
 hw/s390x/virtio-ccw.h|   81 +++
 linux-headers/asm-generic/kvm_para.h |4 +
 linux-headers/asm-powerpc/kvm.h  |   59 ++
 linux-headers/asm-powerpc/kvm_para.h |7 +-
 linux-headers/linux/kvm.h|   36 +-
 target-s390x/Makefile.objs   |2 +-
 target-s390x/cpu.h   |  230 +++
 target-s390x/helper.c|  145 +
 target-s390x/ioinst.c|  726 +
 target-s390x/ioinst.h|  223 +++
 target-s390x/kvm.c   |  246 ++-
 trace-events |   18 +
 17 files changed, 4161 insertions(+), 95 deletions(-)
 create mode 100644 hw/s390x/css.c
 create mode 100644 hw/s390x/css.h
 create mode 100644 hw/s390x/virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.h
 create mode 100644 linux-headers/asm-generic/kvm_para.h
 create mode 100644 target-s390x/ioinst.c
 create mode 100644 target-s390x/ioinst.h

-- 
1.7.12.4




[Qemu-devel] [PATCH 4/8] s390: Add channel I/O instructions.

2012-12-07 Thread Cornelia Huck
Provide handlers for (most) channel I/O instructions.

Signed-off-by: Cornelia Huck 
---
 target-s390x/cpu.h|  87 +++
 target-s390x/ioinst.c | 694 +-
 target-s390x/ioinst.h |  16 ++
 trace-events  |   6 +
 4 files changed, 796 insertions(+), 7 deletions(-)

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 73bfc20..bc119f8 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -127,6 +127,8 @@ typedef struct CPUS390XState {
 QEMUTimer *tod_timer;
 
 QEMUTimer *cpu_timer;
+
+void *chsc_page;
 } CPUS390XState;
 
 #include "cpu-qom.h"
@@ -363,6 +365,91 @@ static inline unsigned s390_del_running_cpu(CPUS390XState 
*env)
 void cpu_lock(void);
 void cpu_unlock(void);
 
+typedef struct SubchDev SubchDev;
+typedef struct SCHIB SCHIB;
+typedef struct ORB ORB;
+
+static inline SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid,
+   uint16_t schid)
+{
+return NULL;
+}
+static inline bool css_subch_visible(SubchDev *sch)
+{
+return false;
+}
+static inline void css_conditional_io_interrupt(SubchDev *sch)
+{
+}
+static inline int css_do_stsch(SubchDev *sch, uint64_t addr)
+{
+return -ENODEV;
+}
+static inline bool css_schid_final(uint8_t cssid, uint8_t ssid, uint16_t schid)
+{
+return true;
+}
+static inline int css_do_msch(SubchDev *sch, SCHIB *schib)
+{
+return -ENODEV;
+}
+static inline int css_do_xsch(SubchDev *sch)
+{
+return -ENODEV;
+}
+static inline int css_do_csch(SubchDev *sch)
+{
+return -ENODEV;
+}
+static inline int css_do_hsch(SubchDev *sch)
+{
+return -ENODEV;
+}
+static inline int css_do_ssch(SubchDev *sch, ORB *orb)
+{
+return -ENODEV;
+}
+static inline int css_do_tsch(SubchDev *sch, uint64_t addr)
+{
+return -ENODEV;
+}
+static inline int css_do_stcrw(uint64_t addr)
+{
+return 1;
+}
+static inline int css_do_tpi(uint64_t addr, int lowcore)
+{
+return 0;
+}
+static inline int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid,
+   int rfmt, uint8_t l_chpid, void *buf)
+{
+return 0;
+}
+static inline void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo)
+{
+}
+static inline int css_enable_mss(void)
+{
+return -EINVAL;
+}
+static inline int css_enable_mcsse(void)
+{
+return -EINVAL;
+}
+static inline int css_do_rsch(SubchDev *sch)
+{
+return -ENODEV;
+}
+static inline int css_do_rchp(uint8_t cssid, uint8_t chpid)
+{
+return -ENODEV;
+}
+static inline bool css_present(uint8_t cssid)
+{
+return false;
+}
+
 static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls)
 {
 env->aregs[0] = newtls >> 32;
diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
index 8577b2c..60ce985 100644
--- a/target-s390x/ioinst.c
+++ b/target-s390x/ioinst.c
@@ -15,14 +15,19 @@
 
 #include "cpu.h"
 #include "ioinst.h"
+#include "trace.h"
 
-#ifdef DEBUG_IOINST
-#define dprintf(fmt, ...) \
-do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
-#else
-#define dprintf(fmt, ...) \
-do { } while (0)
-#endif
+/* Special handling for the prefix page. */
+static void *s390_get_address(CPUS390XState *env, ram_addr_t guest_addr)
+{
+if (guest_addr < 8192) {
+guest_addr += env->psa;
+} else if ((env->psa <= guest_addr) && (guest_addr < env->psa + 8192)) {
+guest_addr -= env->psa;
+}
+
+return qemu_get_ram_ptr(guest_addr);
+}
 
 int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
  int *schid)
@@ -44,3 +49,678 @@ int ioinst_disassemble_sch_ident(uint32_t value, int *m, 
int *cssid, int *ssid,
 *schid = value & IOINST_SCHID_NR;
 return 0;
 }
+
+int ioinst_handle_xsch(CPUS390XState *env, uint64_t reg1)
+{
+int cssid, ssid, schid, m;
+SubchDev *sch;
+int ret = -ENODEV;
+int cc;
+
+if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
+program_interrupt(env, PGM_OPERAND, 2);
+return -EIO;
+}
+trace_ioinst_sch_id("xsch", cssid, ssid, schid);
+sch = css_find_subch(m, cssid, ssid, schid);
+if (sch && css_subch_visible(sch)) {
+ret = css_do_xsch(sch);
+}
+switch (ret) {
+case -ENODEV:
+cc = 3;
+break;
+case -EBUSY:
+cc = 2;
+break;
+case 0:
+cc = 0;
+break;
+default:
+cc = 1;
+break;
+}
+
+return cc;
+}
+
+int ioinst_handle_csch(CPUS390XState *env, uint64_t reg1)
+{
+int cssid, ssid, schid, m;
+SubchDev *sch;
+int ret = -ENODEV;
+int cc;
+
+if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
+program_interrupt(env, PGM_OPERAND, 2);
+return -EIO;
+}
+trace_ioinst_sch_id("csch", c

Re: [Qemu-devel] [PATCH 4/8] s390: Add channel I/O instructions.

2012-12-10 Thread Cornelia Huck
On Mon, 10 Dec 2012 10:00:16 +0100
Alexander Graf  wrote:

> 
> 
> On 07.12.2012, at 13:50, Cornelia Huck  wrote:
> 
> > Provide handlers for (most) channel I/O instructions.
> > 
> > Signed-off-by: Cornelia Huck 
> > ---
> > target-s390x/cpu.h|  87 +++
> > target-s390x/ioinst.c | 694 
> > +-
> > target-s390x/ioinst.h |  16 ++
> > trace-events  |   6 +
> > 4 files changed, 796 insertions(+), 7 deletions(-)
> > 
> > diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
> > index 73bfc20..bc119f8 100644
> > --- a/target-s390x/cpu.h
> > +++ b/target-s390x/cpu.h
> > @@ -127,6 +127,8 @@ typedef struct CPUS390XState {
> > QEMUTimer *tod_timer;
> > 
> > QEMUTimer *cpu_timer;
> > +
> > +void *chsc_page;
> > } CPUS390XState;
> > 
> > #include "cpu-qom.h"
> > @@ -363,6 +365,91 @@ static inline unsigned 
> > s390_del_running_cpu(CPUS390XState *env)
> > void cpu_lock(void);
> > void cpu_unlock(void);
> > 
> > +typedef struct SubchDev SubchDev;
> > +typedef struct SCHIB SCHIB;
> > +typedef struct ORB ORB;
> > +
> > +static inline SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t 
> > ssid,
> > +   uint16_t schid)
> > +{
> > +return NULL;
> > +}
> > +static inline bool css_subch_visible(SubchDev *sch)
> > +{
> > +return false;
> > +}
> > +static inline void css_conditional_io_interrupt(SubchDev *sch)
> > +{
> > +}
> > +static inline int css_do_stsch(SubchDev *sch, uint64_t addr)
> > +{
> > +return -ENODEV;
> > +}
> > +static inline bool css_schid_final(uint8_t cssid, uint8_t ssid, uint16_t 
> > schid)
> > +{
> > +return true;
> > +}
> > +static inline int css_do_msch(SubchDev *sch, SCHIB *schib)
> > +{
> > +return -ENODEV;
> > +}
> > +static inline int css_do_xsch(SubchDev *sch)
> > +{
> > +return -ENODEV;
> > +}
> > +static inline int css_do_csch(SubchDev *sch)
> > +{
> > +return -ENODEV;
> > +}
> > +static inline int css_do_hsch(SubchDev *sch)
> > +{
> > +return -ENODEV;
> > +}
> > +static inline int css_do_ssch(SubchDev *sch, ORB *orb)
> > +{
> > +return -ENODEV;
> > +}
> > +static inline int css_do_tsch(SubchDev *sch, uint64_t addr)
> > +{
> > +return -ENODEV;
> > +}
> > +static inline int css_do_stcrw(uint64_t addr)
> > +{
> > +return 1;
> > +}
> > +static inline int css_do_tpi(uint64_t addr, int lowcore)
> > +{
> > +return 0;
> > +}
> > +static inline int css_collect_chp_desc(int m, uint8_t cssid, uint8_t 
> > f_chpid,
> > +   int rfmt, uint8_t l_chpid, void 
> > *buf)
> > +{
> > +return 0;
> > +}
> > +static inline void css_do_schm(uint8_t mbk, int update, int dct, uint64_t 
> > mbo)
> > +{
> > +}
> > +static inline int css_enable_mss(void)
> > +{
> > +return -EINVAL;
> > +}
> > +static inline int css_enable_mcsse(void)
> > +{
> > +return -EINVAL;
> > +}
> > +static inline int css_do_rsch(SubchDev *sch)
> > +{
> > +return -ENODEV;
> > +}
> > +static inline int css_do_rchp(uint8_t cssid, uint8_t chpid)
> > +{
> > +return -ENODEV;
> > +}
> > +static inline bool css_present(uint8_t cssid)
> > +{
> > +return false;
> > +}
> > +
> > static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls)
> > {
> > env->aregs[0] = newtls >> 32;
> > diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
> > index 8577b2c..60ce985 100644
> > --- a/target-s390x/ioinst.c
> > +++ b/target-s390x/ioinst.c
> > @@ -15,14 +15,19 @@
> > 
> > #include "cpu.h"
> > #include "ioinst.h"
> > +#include "trace.h"
> > 
> > -#ifdef DEBUG_IOINST
> > -#define dprintf(fmt, ...) \
> > -do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
> > -#else
> > -#define dprintf(fmt, ...) \
> > -do { } while (0)
> > -#endif
> > +/* Special handling for the prefix page. */
> > +static void *s390_get_address(CPUS390XState *env, ram_addr_t guest_addr)
> > +{
> > +if (guest_addr < 8192) {
> > +guest_addr += env->psa;
> > +} else if ((env->psa <= guest_addr) &am

Re: [Qemu-devel] [PATCH 2/8] s390: Channel I/O basic defintions.

2012-12-10 Thread Cornelia Huck
On Mon, 10 Dec 2012 09:07:57 +0100
Alexander Graf  wrote:

> 
> On 07.12.2012, at 13:50, Cornelia Huck wrote:
> 
> > Basic channel I/O structures and helper function.
> > 
> > Signed-off-by: Cornelia Huck 
> > ---
> > target-s390x/Makefile.objs |   2 +-
> > target-s390x/ioinst.c  |  46 ++
> > target-s390x/ioinst.h  | 207 
> > +
> > 3 files changed, 254 insertions(+), 1 deletion(-)
> > create mode 100644 target-s390x/ioinst.c
> > create mode 100644 target-s390x/ioinst.h
> > 
> > diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
> > index e728abf..3afb0b7 100644
> > --- a/target-s390x/Makefile.objs
> > +++ b/target-s390x/Makefile.objs
> > @@ -1,4 +1,4 @@
> > obj-y += translate.o helper.o cpu.o interrupt.o
> > obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
> > -obj-$(CONFIG_SOFTMMU) += machine.o
> > +obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o
> > obj-$(CONFIG_KVM) += kvm.o
> > diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
> > new file mode 100644
> > index 000..8577b2c
> > --- /dev/null
> > +++ b/target-s390x/ioinst.c
> > @@ -0,0 +1,46 @@
> > +/*
> > + * I/O instructions for S/390
> > + *
> > + * Copyright 2012 IBM Corp.
> > + * Author(s): Cornelia Huck 
> > + *
> > + * 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 
> > +#include 
> > +#include 
> > +
> > +#include "cpu.h"
> > +#include "ioinst.h"
> > +
> > +#ifdef DEBUG_IOINST
> > +#define dprintf(fmt, ...) \
> > +do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
> > +#else
> > +#define dprintf(fmt, ...) \
> > +do { } while (0)
> > +#endif
> > +
> > +int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int 
> > *ssid,
> > + int *schid)
> > +{
> > +if (!(value & IOINST_SCHID_ONE)) {
> > +return -EINVAL;
> > +}
> > +if (!(value & IOINST_SCHID_M)) {
> > +if (value & IOINST_SCHID_CSSID) {
> > +return -EINVAL;
> > +}
> > +*cssid = 0;
> > +*m = 0;
> > +} else {
> > +*cssid = (value & IOINST_SCHID_CSSID) >> 24;
> 
> (value & IOINST_SCHID_CSSID_MASK) >> IOINST_SCHID_CSSID_SHIFT

I think that actually decreases readability.

> 
> 
> Alex
> 
> > +*m = 1;
> > +}
> > +*ssid = (value & IOINST_SCHID_SSID) >> 17;
> > +*schid = value & IOINST_SCHID_NR;
> > +return 0;
> > +}
> > diff --git a/target-s390x/ioinst.h b/target-s390x/ioinst.h
> > new file mode 100644
> > index 000..b5b4a03
> > --- /dev/null
> > +++ b/target-s390x/ioinst.h
> > @@ -0,0 +1,207 @@
> > +/*
> > + * S/390 channel I/O instructions
> > + *
> > + * Copyright 2012 IBM Corp.
> > + * Author(s): Cornelia Huck 
> > + *
> > + * 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 IOINST_S390X_H
> > +#define IOINST_S390X_H
> > +/*
> > + * Channel I/O related definitions, as defined in the Principles
> > + * Of Operation (and taken from the Linux implementation).
> > + */
> > +
> > +/* subchannel status word (command mode only) */
> > +typedef struct SCSW {
> > +uint16_t flags;
> > +uint16_t ctrl;
> > +uint32_t cpa;
> > +uint8_t dstat;
> > +uint8_t cstat;
> > +uint16_t count;
> > +} QEMU_PACKED SCSW;
> > +
> > +#define SCSW_FLAGS_MASK_KEY 0xf000
> > +#define SCSW_FLAGS_MASK_SCTL 0x0800
> > +#define SCSW_FLAGS_MASK_ESWF 0x0400
> > +#define SCSW_FLAGS_MASK_CC 0x0300
> > +#define SCSW_FLAGS_MASK_FMT 0x0080
> > +#define SCSW_FLAGS_MASK_PFCH 0x0040
> > +#define SCSW_FLAGS_MASK_ISIC 0x0020
> > +#define SCSW_FLAGS_MASK_ALCC 0x0010
> > +#define SCSW_FLAGS_MASK_SSI 0x0008
> > +#define SCSW_FLAGS_MASK_ZCC 0x0004
> > +#define SCSW_FLAGS_MASK_ECTL 0x0002
> > +#define SCSW_FLAGS_MASK_PNO 0x0001
> > +
> > +#define SCSW_CTRL_MASK_FCTL 0x7000
> > +#define SCSW_CTRL_MASK_ACTL 0x0fe0
> > +#define SCSW_C

Re: [Qemu-devel] [PATCH 3/8] s390: I/O interrupt and machine check injection.

2012-12-10 Thread Cornelia Huck
On Mon, 10 Dec 2012 09:20:57 +0100
Alexander Graf  wrote:

> 
> On 07.12.2012, at 13:50, Cornelia Huck wrote:
> 
> > I/O interrupts are queued per isc. Only crw pending machine checks
> > are supported.
> > 
> > Signed-off-by: Cornelia Huck 
> > ---
> > target-s390x/cpu.h|  67 +++
> > target-s390x/helper.c | 145 
> > ++
> > 2 files changed, 212 insertions(+)
> > 
> > diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
> > index 0f9a1f7..73bfc20 100644
> > --- a/target-s390x/cpu.h
> > +++ b/target-s390x/cpu.h
> > @@ -47,6 +47,11 @@
> > #define MMU_USER_IDX 1
> > 
> > #define MAX_EXT_QUEUE 16
> > +#define MAX_IO_QUEUE 16
> > +#define MAX_MCHK_QUEUE 16
> > +
> > +#define PSW_MCHK_MASK 0x0004
> > +#define PSW_IO_MASK 0x0200
> > 
> > typedef struct PSW {
> > uint64_t mask;
> > @@ -59,6 +64,17 @@ typedef struct ExtQueue {
> > uint32_t param64;
> > } ExtQueue;
> > 
> > +typedef struct IOQueue {
> > +uint16_t id;
> > +uint16_t nr;
> > +uint32_t parm;
> > +uint32_t word;
> > +} IOQueue;
> > +
> > +typedef struct MchkQueue {
> > +uint16_t type;
> > +} MchkQueue;
> > +
> > typedef struct CPUS390XState {
> > uint64_t regs[16];  /* GP registers */
> > 
> > @@ -88,8 +104,16 @@ typedef struct CPUS390XState {
> > 
> > int pending_int;
> > ExtQueue ext_queue[MAX_EXT_QUEUE];
> > +IOQueue io_queue[MAX_IO_QUEUE][8];
> > +MchkQueue mchk_queue[MAX_MCHK_QUEUE];
> > 
> > int ext_index;
> > +int io_index[8];
> > +int mchk_index;
> > +
> > +uint64_t ckc;
> > +uint64_t cputm;
> > +uint32_t todpr;
> > 
> > CPU_COMMON
> > 
> > @@ -364,12 +388,16 @@ static inline void cpu_set_tls(CPUS390XState *env, 
> > target_ulong newtls)
> > #define EXCP_EXT 1 /* external interrupt */
> > #define EXCP_SVC 2 /* supervisor call (syscall) */
> > #define EXCP_PGM 3 /* program interruption */
> > +#define EXCP_IO  7 /* I/O interrupt */
> > +#define EXCP_MCHK 8 /* machine check */
> > 
> > #endif /* CONFIG_USER_ONLY */
> > 
> > #define INTERRUPT_EXT(1 << 0)
> > #define INTERRUPT_TOD(1 << 1)
> > #define INTERRUPT_CPUTIMER   (1 << 2)
> > +#define INTERRUPT_IO (1 << 3)
> > +#define INTERRUPT_MCHK   (1 << 4)
> > 
> > /* Program Status Word.  */
> > #define S390_PSWM_REGNUM 0
> > @@ -977,6 +1005,45 @@ static inline void cpu_inject_ext(CPUS390XState *env, 
> > uint32_t code, uint32_t pa
> > cpu_interrupt(env, CPU_INTERRUPT_HARD);
> > }
> > 
> > +static inline void cpu_inject_io(CPUS390XState *env, uint16_t 
> > subchannel_id,
> > + uint16_t subchannel_number,
> > + uint32_t io_int_parm, uint32_t 
> > io_int_word)
> > +{
> > +int isc = ffs(io_int_word << 2) - 1;
> > +
> > +if (env->io_index[isc] == MAX_IO_QUEUE - 1) {
> > +/* ugh - can't queue anymore. Let's drop. */
> > +return;
> > +}
> > +
> > +env->io_index[isc]++;
> > +assert(env->io_index[isc] < MAX_IO_QUEUE);
> > +
> > +env->io_queue[env->io_index[isc]][isc].id = subchannel_id;
> > +env->io_queue[env->io_index[isc]][isc].nr = subchannel_number;
> > +env->io_queue[env->io_index[isc]][isc].parm = io_int_parm;
> > +env->io_queue[env->io_index[isc]][isc].word = io_int_word;
> > +
> > +env->pending_int |= INTERRUPT_IO;
> > +cpu_interrupt(env, CPU_INTERRUPT_HARD);
> > +}
> > +
> > +static inline void cpu_inject_crw_mchk(CPUS390XState *env)
> > +{
> > +if (env->mchk_index == MAX_MCHK_QUEUE - 1) {
> > +/* ugh - can't queue anymore. Let's drop. */
> > +return;
> > +}
> > +
> > +env->mchk_index++;
> > +assert(env->mchk_index < MAX_MCHK_QUEUE);
> > +
> > +env->mchk_queue[env->mchk_index].type = 1;
> > +
> > +env->pending_int |= INTERRUPT_MCHK;
> > +cpu_interrupt(env, CPU_INTERRUPT_HARD);
> > +}
> > +
> > static inline bool cpu_has_work(CPUState *cpu)
> > {
> > CPUS390XState *env = &S390_CPU(cpu)->env;
> > diff --git a/target-s390x/helper.c b/target-s39

Re: [Qemu-devel] [PATCH 6/8] s390: Wire up channel I/O in kvm.

2012-12-10 Thread Cornelia Huck
On Mon, 10 Dec 2012 10:40:15 +0100
Alexander Graf  wrote:

> 
> 
> On 07.12.2012, at 13:50, Cornelia Huck  wrote:
> 
> > Trigger the code for our virtual css in case of instruction
> > intercepts for I/O instructions.
> > 
> > Handle the tsch exit for the subchannel-related part of tsch.
> > 
> > Signed-off-by: Cornelia Huck 
> > ---
> > target-s390x/cpu.h |  11 +++
> > target-s390x/kvm.c | 246 
> > ++---
> > 2 files changed, 244 insertions(+), 13 deletions(-)
> > 
> > diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
> > index eb24c6b..1d21ca8 100644
> > --- a/target-s390x/cpu.h
> > +++ b/target-s390x/cpu.h
> > @@ -1178,6 +1178,13 @@ uint32_t set_cc_nz_f64(float64 v);
> > /* misc_helper.c */
> > void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
> > 
> > +#ifdef CONFIG_KVM
> > +int kvm_s390_io_interrupt(CPUS390XState *env, uint16_t subchannel_id,
> > +  uint16_t subchannel_nr, uint32_t io_int_parm,
> > +  uint32_t io_int_word);
> > +int kvm_s390_crw_mchk(CPUS390XState *env);
> > +void kvm_s390_enable_css_support(CPUS390XState *env);
> > +#else
> > static inline int kvm_s390_io_interrupt(CPUS390XState *env,
> > uint16_t subchannel_id,
> > uint16_t subchannel_nr,
> > @@ -1190,6 +1197,10 @@ static inline int kvm_s390_crw_mchk(CPUS390XState 
> > *env)
> > {
> > return -EOPNOTSUPP;
> > }
> > +static inline void kvm_s390_enable_css_support(CPUS390XState *env)
> > +{
> > +}
> > +#endif
> > 
> > static inline void s390_io_interrupt(CPUS390XState *env,
> >  uint16_t subchannel_id,
> > diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
> > index 94de764..c9a4a7d 100644
> > --- a/target-s390x/kvm.c
> > +++ b/target-s390x/kvm.c
> > @@ -30,6 +30,7 @@
> > #include "kvm.h"
> > #include "cpu.h"
> > #include "device_tree.h"
> > +#include "ioinst.h"
> > 
> > /* #define DEBUG_KVM */
> > 
> > @@ -43,9 +44,27 @@
> > 
> > #define IPA0_DIAG   0x8300
> > #define IPA0_SIGP   0xae00
> > -#define IPA0_PRIV   0xb200
> > +#define IPA0_B2 0xb200
> > +#define IPA0_B9 0xb900
> > +#define IPA0_EB 0xeb00
> > 
> > #define PRIV_SCLP_CALL  0x20
> > +#define PRIV_CSCH   0x30
> > +#define PRIV_HSCH   0x31
> > +#define PRIV_MSCH   0x32
> > +#define PRIV_SSCH   0x33
> > +#define PRIV_STSCH  0x34
> > +#define PRIV_TSCH   0x35
> > +#define PRIV_TPI0x36
> > +#define PRIV_SAL0x37
> > +#define PRIV_RSCH   0x38
> > +#define PRIV_STCRW  0x39
> > +#define PRIV_STCPS  0x3a
> > +#define PRIV_RCHP   0x3b
> > +#define PRIV_SCHM   0x3c
> > +#define PRIV_CHSC   0x5f
> > +#define PRIV_SIGA   0x74
> > +#define PRIV_XSCH   0x76
> > #define DIAG_KVM_HYPERCALL  0x500
> > #define DIAG_KVM_BREAKPOINT 0x501
> > 
> > @@ -350,10 +369,120 @@ static int kvm_sclp_service_call(CPUS390XState *env, 
> > struct kvm_run *run,
> > return 0;
> > }
> > 
> > -static int handle_priv(CPUS390XState *env, struct kvm_run *run, uint8_t 
> > ipa1)
> > +static int kvm_handle_css_inst(CPUS390XState *env, struct kvm_run *run,
> > +   uint8_t ipa0, uint8_t ipa1, uint8_t ipb)
> > +{
> > +int r = 0;
> > +int no_cc = 0;
> > +
> > +if (ipa0 != 0xb2) {
> > +/* Not handled for now. */
> > +return -1;
> > +}
> > +cpu_synchronize_state(env);
> > +switch (ipa1) {
> > +case PRIV_XSCH:
> > +r = ioinst_handle_xsch(env, env->regs[1]);
> > +break;
> > +case PRIV_CSCH:
> > +r = ioinst_handle_csch(env, env->regs[1]);
> > +break;
> > +case PRIV_HSCH:
> > +r = ioinst_handle_hsch(env, env->regs[1]);
> > +break;
> > +case PRIV_MSC

Re: [Qemu-devel] [RFC PATCH v4 0/8] s390: channel I/O support in qemu.

2012-12-10 Thread Cornelia Huck
On Mon, 10 Dec 2012 09:02:51 +0100
Alexander Graf  wrote:

> 
> On 07.12.2012, at 13:50, Cornelia Huck wrote:
> 
> > Hi,
> > 
> > just a quick dump of my qemu patch series for channel I/O.
> > 
> > I've managed to chop the virtual css patch into some smaller
> > chunks (patches 2-6), which are hopefully easier to review.
> > 
> > The virtio-ccw patch is still based upon the current virtio
> > infrastructure; I'll try to rebase it upon the virtio refactoring
> > once that has most of the infrastructure in place.
> 
> I wouldn't want to hold this feature back only for some virtio refactoring. 
> Let's try to get it into shape for now and worry about the refactor work when 
> that's closer to merging.

The virtio-ccw stuff is already in a state where I welcome feedback -
if you keep in mind that the modelling will look a bit different after
the virtio refactoring. (And the other patches could be merged when
ready without waiting for the refactoring.)
> 
> 
> Alex
> 
> > 
> > Cornelia Huck (8):
> >  Update linux headers.
> >  s390: Channel I/O basic defintions.
> >  s390: I/O interrupt and machine check injection.
> >  s390: Add channel I/O instructions.
> >  s390: Virtual channel subsystem support.
> >  s390: Wire up channel I/O in kvm.
> >  s390-virtio: Factor out some initialization code.
> >  s390: Add new channel I/O based virtio transport.
> > 
> > hw/s390-virtio.c |  281 +---
> > hw/s390x/Makefile.objs   |2 +
> > hw/s390x/css.c   | 1195 
> > ++
> > hw/s390x/css.h   |   92 +++
> > hw/s390x/virtio-ccw.c|  909 ++
> > hw/s390x/virtio-ccw.h|   81 +++
> > linux-headers/asm-generic/kvm_para.h |4 +
> > linux-headers/asm-powerpc/kvm.h  |   59 ++
> > linux-headers/asm-powerpc/kvm_para.h |7 +-
> > linux-headers/linux/kvm.h|   36 +-
> > target-s390x/Makefile.objs   |2 +-
> > target-s390x/cpu.h   |  230 +++
> > target-s390x/helper.c|  145 +
> > target-s390x/ioinst.c|  726 +
> > target-s390x/ioinst.h|  223 +++
> > target-s390x/kvm.c   |  246 ++-
> > trace-events |   18 +
> > 17 files changed, 4161 insertions(+), 95 deletions(-)
> > create mode 100644 hw/s390x/css.c
> > create mode 100644 hw/s390x/css.h
> > create mode 100644 hw/s390x/virtio-ccw.c
> > create mode 100644 hw/s390x/virtio-ccw.h
> > create mode 100644 linux-headers/asm-generic/kvm_para.h
> > create mode 100644 target-s390x/ioinst.c
> > create mode 100644 target-s390x/ioinst.h
> > 
> > -- 
> > 1.7.12.4
> > 
> 




Re: [Qemu-devel] [PATCH 3/8] s390: I/O interrupt and machine check injection.

2012-12-11 Thread Cornelia Huck
On Mon, 10 Dec 2012 18:26:28 -0600
Rob Landley  wrote:

> What do you actually use to run Linux under this target? There are some  
> leads at
> http://virtuallyfun.superglobalmegacorp.com/?p=1206 which more or less  
> leads to
> http://ftp.nl.debian.org/debian/dists/Debian6.0.6/main/installer-s390/current/images/generic/
>   
> but I dunno what qemu command line would go along with those files...
> 
> Any hints?

The easiest way is probably to use an existing Linux/390 installation
on a disk attached to your system and an external monolithic kernel
containing the virtio-ccw guest support patches and the virtio drivers:

s390x-softmmu/qemu-system-s390x -machine s390-ccw -m 1024 -smp 2 -enable-kvm 
-kernel /path/to/your/kernel -drive 
file=/dev/sda,if=none,media=disk,id=drive-virtio-disk0 -device 
virtio-blk-ccw,devno=fe.0.0815,drive=drive-virtio-disk0,id=virtio-disk0 -append 
"root=/dev/vda1" -nographic




Re: [Qemu-devel] [PATCH 2/8] s390: Channel I/O basic defintions.

2012-12-11 Thread Cornelia Huck
On Tue, 11 Dec 2012 11:27:05 +0100
Alexander Graf  wrote:

> 
> On 10.12.2012, at 11:18, Cornelia Huck wrote:
> 
> > On Mon, 10 Dec 2012 09:07:57 +0100
> > Alexander Graf  wrote:
> > 
> >> 
> >> On 07.12.2012, at 13:50, Cornelia Huck wrote:
> >> 
> >>> Basic channel I/O structures and helper function.
> >>> 
> >>> Signed-off-by: Cornelia Huck 
> >>> ---
> >>> target-s390x/Makefile.objs |   2 +-
> >>> target-s390x/ioinst.c  |  46 ++
> >>> target-s390x/ioinst.h  | 207 
> >>> +
> >>> 3 files changed, 254 insertions(+), 1 deletion(-)
> >>> create mode 100644 target-s390x/ioinst.c
> >>> create mode 100644 target-s390x/ioinst.h
> >>> 
> >>> diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
> >>> index e728abf..3afb0b7 100644
> >>> --- a/target-s390x/Makefile.objs
> >>> +++ b/target-s390x/Makefile.objs
> >>> @@ -1,4 +1,4 @@
> >>> obj-y += translate.o helper.o cpu.o interrupt.o
> >>> obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
> >>> -obj-$(CONFIG_SOFTMMU) += machine.o
> >>> +obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o
> >>> obj-$(CONFIG_KVM) += kvm.o
> >>> diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
> >>> new file mode 100644
> >>> index 000..8577b2c
> >>> --- /dev/null
> >>> +++ b/target-s390x/ioinst.c
> >>> @@ -0,0 +1,46 @@
> >>> +/*
> >>> + * I/O instructions for S/390
> >>> + *
> >>> + * Copyright 2012 IBM Corp.
> >>> + * Author(s): Cornelia Huck 
> >>> + *
> >>> + * 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 
> >>> +#include 
> >>> +#include 
> >>> +
> >>> +#include "cpu.h"
> >>> +#include "ioinst.h"
> >>> +
> >>> +#ifdef DEBUG_IOINST
> >>> +#define dprintf(fmt, ...) \
> >>> +do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
> >>> +#else
> >>> +#define dprintf(fmt, ...) \
> >>> +do { } while (0)
> >>> +#endif
> >>> +
> >>> +int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int 
> >>> *ssid,
> >>> + int *schid)
> >>> +{
> >>> +if (!(value & IOINST_SCHID_ONE)) {
> >>> +return -EINVAL;
> >>> +}
> >>> +if (!(value & IOINST_SCHID_M)) {
> >>> +if (value & IOINST_SCHID_CSSID) {
> >>> +return -EINVAL;
> >>> +}
> >>> +*cssid = 0;
> >>> +*m = 0;
> >>> +} else {
> >>> +*cssid = (value & IOINST_SCHID_CSSID) >> 24;
> >> 
> >> (value & IOINST_SCHID_CSSID_MASK) >> IOINST_SCHID_CSSID_SHIFT
> > 
> > I think that actually decreases readability.
> 
> I'm fine with doing it Jocelyn-style too:
> 
> #define IOINST_SCHID_CSSID(x) ((x & 0x...) >> 24)
> 
> if you prefer that for readability :)

It's worth a try.




Re: [Qemu-devel] [PATCH 4/8] s390: Add channel I/O instructions.

2012-12-11 Thread Cornelia Huck
On Tue, 11 Dec 2012 11:18:44 +0100
Alexander Graf  wrote:

> 
> On 10.12.2012, at 10:18, Cornelia Huck wrote:
> 
> > On Mon, 10 Dec 2012 10:00:16 +0100
> > Alexander Graf  wrote:
> > 
> >> 
> >> 
> >> On 07.12.2012, at 13:50, Cornelia Huck  wrote:

> >>> +/* Special handling for the prefix page. */
> >>> +static void *s390_get_address(CPUS390XState *env, ram_addr_t guest_addr)
> >>> +{
> >>> +if (guest_addr < 8192) {
> >>> +guest_addr += env->psa;
> >>> +} else if ((env->psa <= guest_addr) && (guest_addr < env->psa + 
> >>> 8192)) {
> >>> +guest_addr -= env->psa;
> >>> +}
> >>> +
> >>> +return qemu_get_ram_ptr(guest_addr);
> >> 
> >> Do we actually need this?
> > 
> > Yes. I've seen failures for I/O instructions using the lowcore (which
> > the Linux kernel likes to do).
> 
> Then we want an s390 generic function that does this, not an io specific one 
> though, right? Also qemu_get_ram_ptr is a no-go, as it doesn't do boundary 
> checks.

Oh, wasn't aware of that.

> 
> So what we really want is something like s390_cpu_physical_memory_map(env, 
> ...) with a special case on the lowcore.

Let's see how this works out.

> >>> +addr = ipb >> 28;
> >>> +if (addr > 0) {
> >>> +addr = env->regs[addr];
> >>> +}
> >>> +addr += (ipb & 0xfff) >> 16;
> >> 
> >> This adds the upper bits twice. Are you sire that's correct?
> > 
> > If addr was 0, it doesn't. If addr was > 0 before, we grabbed the
> > address from the corresponding register and want to add to it.
> 
> This is a very confusing way of writing what you're trying to express then 
> :). How about
> 
> hwaddr addr = 0;
> 
> reg = ipb >> 28;
> if (reg) {
> addr = env->regs[reg];
> }
> addr += (ipb >> 16) & 0xfff0;

I've moved this to a helper function anyway - but this looks a bit more
readable, yes.




Re: [Qemu-devel] [PATCH 8/8] s390: Add new channel I/O based virtio transport.

2012-12-11 Thread Cornelia Huck
On Tue, 11 Dec 2012 11:53:18 +0100
Alexander Graf  wrote:

> 
> On 07.12.2012, at 13:50, Cornelia Huck wrote:
> 
> > Add a new virtio transport that uses channel commands to perform
> > virtio operations.
> > 
> > Add a new machine type s390-ccw that uses this virtio-ccw transport
> > and make it the default machine for s390.
> > 
> > Signed-off-by: Cornelia Huck 
> > ---
> > hw/s390-virtio.c   | 149 ++--
> > hw/s390x/Makefile.objs |   1 +
> > hw/s390x/virtio-ccw.c  | 909 
> > +
> > hw/s390x/virtio-ccw.h  |  81 +
> > trace-events   |   4 +
> > 5 files changed, 1124 insertions(+), 20 deletions(-)
> > create mode 100644 hw/s390x/virtio-ccw.c
> > create mode 100644 hw/s390x/virtio-ccw.h
> > 
> > diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
> > index 9e1afb2..f29ff74 100644
> > --- a/hw/s390-virtio.c
> > +++ b/hw/s390-virtio.c
> > @@ -33,6 +33,8 @@
> > 
> > #include "hw/s390-virtio-bus.h"
> > #include "hw/s390x/sclp.h"
> > +#include "hw/s390x/css.h"
> > +#include "hw/s390x/virtio-ccw.h"
> > 
> > //#define DEBUG_S390
> > 
> > @@ -47,6 +49,7 @@
> > #define KVM_S390_VIRTIO_NOTIFY  0
> > #define KVM_S390_VIRTIO_RESET   1
> > #define KVM_S390_VIRTIO_SET_STATUS  2
> > +#define KVM_S390_VIRTIO_CCW_NOTIFY  3
> > 
> > #define KERN_IMAGE_START0x01UL
> > #define KERN_PARM_AREA  0x010480UL
> > @@ -63,6 +66,7 @@
> > 
> > static VirtIOS390Bus *s390_bus;
> > static S390CPU **ipi_states;
> > +VirtioCcwBus *ccw_bus;
> > 
> > S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
> > {
> > @@ -76,15 +80,21 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
> > int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t 
> > hypercall)
> > {
> > int r = 0, i;
> > +int cssid, ssid, schid, m;
> > +SubchDev *sch;
> > 
> > dprintf("KVM hypercall: %ld\n", hypercall);
> > switch (hypercall) {
> > case KVM_S390_VIRTIO_NOTIFY:
> > if (mem > ram_size) {
> > -VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
> > -   mem, &i);
> > -if (dev) {
> > -virtio_queue_notify(dev->vdev, i);
> > +if (s390_bus) {
> > +VirtIOS390Device *dev = 
> > s390_virtio_bus_find_vring(s390_bus,
> > +   mem, 
> > &i);
> > +if (dev) {
> > +virtio_queue_notify(dev->vdev, i);
> > +} else {
> > +r = -EINVAL;
> > +}
> 
> We really want to factor out the DIAG handling code similar to how spapr 
> handles its hypercalls. That way the legacy s390-virtio machine can register 
> a VIRTIO_NOTIFY hypercall that works for it here, while the s390-virtio-ccw 
> machine doesn't.
> 
> > } else {
> > r = -EINVAL;
> > }
> > @@ -93,28 +103,49 @@ int s390_virtio_hypercall(CPUS390XState *env, uint64_t 
> > mem, uint64_t hypercall)
> > }
> > break;
> > case KVM_S390_VIRTIO_RESET:
> > -{
> > -VirtIOS390Device *dev;
> > -
> > -dev = s390_virtio_bus_find_mem(s390_bus, mem);
> > -virtio_reset(dev->vdev);
> > -stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0);
> > -s390_virtio_device_sync(dev);
> > -s390_virtio_reset_idx(dev);
> > +if (s390_bus) {
> > +VirtIOS390Device *dev;
> > +
> > +dev = s390_virtio_bus_find_mem(s390_bus, mem);
> > +virtio_reset(dev->vdev);
> > +stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0);
> > +s390_virtio_device_sync(dev);
> > +s390_virtio_reset_idx(dev);
> > +} else {
> > +r = -EINVAL;
> > +}
> > break;
> > -}
> > case KVM_S390_VIRTIO_SET_STATUS:
> > -{
> > -VirtIOS390Device *dev;
> > +if (s390_bus) {
> > +VirtIOS390Device *dev;
> > 
> > -dev = s390_virtio_bus_find_mem(s390_bus, mem);
> > -if (dev) {
> > -s390_virtio_device_update_status(d

Re: [Qemu-devel] [PATCH 3/8] s390: I/O interrupt and machine check injection.

2012-12-11 Thread Cornelia Huck
On Tue, 11 Dec 2012 11:29:16 +0100
Alexander Graf  wrote:

> 
> On 10.12.2012, at 11:27, Cornelia Huck wrote:
> 
> > On Mon, 10 Dec 2012 09:20:57 +0100
> > Alexander Graf  wrote:
> > 
> >> 
> >> On 07.12.2012, at 13:50, Cornelia Huck wrote:

> >>> +/* CRW machine checks disabled */
> >>> +return;
> >>> +}
> >>> +
> >>> +lowcore = cpu_physical_memory_map(env->psa, &len, 1);
> >> 
> >> Check missing again.
> > 
> > Perhaps we want {map,unmap}_lowcore() functions?
> 
> Awesome idea!

I'll cook up an extra patch for this then (and make the ext stuff use
it).




Re: [Qemu-devel] [PATCH v2 3/5] s390: Add new channel I/O based virtio transport.

2012-12-18 Thread Cornelia Huck
On Tue, 18 Dec 2012 09:45:27 +0100
Paolo Bonzini  wrote:

> Il 04/09/2012 17:13, Cornelia Huck ha scritto:
> > +VirtioCcwBus *virtio_ccw_bus_init(void)
> > +{
> > +VirtioCcwBus *cbus;
> > +BusState *bus;
> > +DeviceState *dev;
> > +
> > +/* Create bridge device */
> > +dev = qdev_create(NULL, "virtio-ccw-bridge");
> > +qdev_init_nofail(dev);
> > +
> > +/* Create bus on bridge device */
> > +bus = qbus_create(TYPE_VIRTIO_CCW_BUS, dev, "virtio-ccw");
> > +cbus = DO_UPCAST(VirtioCcwBus, bus, bus);
> > +
> > +/* Enable hotplugging */
> > +bus->allow_hotplug = 1;
> > +
> > +qemu_register_reset(virtio_ccw_reset_subchannels, cbus);
> 
> Please use qdev device-reset and bus-reset callbacks instead of this.

Will do for the next version.
> 
> In particular, when writing the status you should call
> qdev_reset_all(DEVICE(sch)), and whatever state should be reset will
> have to be cleared by the device-reset callback of SubchDev, including
> calling virtio_reset.

With "writing the status" you mean "the guest sets the status to 0",
right?

> 
> Everything else will be cleared instead by the bus-reset callback of
> virtio-ccw-bus, similar to what you are doing in
> virtio_ccw_reset_subchannels.

Looking at the reset handler, css_reset() is a bit oddly placed, as it
doesn't really have anything to do with virtio-ccw; virtio-ccw is just
the only current creator of channel subsystem images. I'll try to come
up with a better model.

> 
> Paolo
> 
> 
> > +return cbus;
> > +}
> 




Re: [Qemu-devel] [RFC PATCH V8 06/15] virtio-s390-bus : Add virtio-s390-bus.

2012-12-19 Thread Cornelia Huck
On Wed, 19 Dec 2012 10:53:32 +0100
fred.kon...@greensocs.com wrote:

> From: KONRAD Frederic 
> 
> Introduce virtio-s390-bus, which extends virtio-bus. It is used with s390
> transport device.
> 
> Signed-off-by: KONRAD Frederic 
> ---
>  hw/s390-virtio-bus.c | 28 
>  hw/s390-virtio-bus.h | 13 +
>  2 files changed, 41 insertions(+)
> 
> diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
> index e0ac2d1..720dbb9 100644
> --- a/hw/s390-virtio-bus.c
> +++ b/hw/s390-virtio-bus.c
> @@ -33,6 +33,7 @@
>  #include "kvm.h"
> 
>  #include "hw/s390-virtio-bus.h"
> +#include "hw/virtio-bus.h"
> 
>  /* #define DEBUG_S390 */
> 
> @@ -556,8 +557,35 @@ static TypeInfo s390_virtio_bridge_info = {
>  .class_init= s390_virtio_bridge_class_init,
>  };
> 
> +/* virtio-s390-bus */
> +
> +VirtioBusState *virtio_s390_bus_new(VirtIOS390Device *dev)
> +{
> +DeviceState *qdev = DEVICE(dev);
> +BusState *qbus = qbus_create(TYPE_VIRTIO_S390_BUS, qdev, NULL);
> +VirtioBusState *bus = VIRTIO_BUS(qbus);
> +qbus->allow_hotplug = 0;
> +qbus->max_dev = 1;
> +return bus;
> +}
> +
> +static void virtio_s390_bus_class_init(ObjectClass *klass, void *data)
> +{
> +VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
> +k->notify = virtio_s390_notify;
> +k->get_features = virtio_s390_get_features;
> +}
> +
> +static const TypeInfo virtio_s390_bus_info = {
> +.name  = TYPE_VIRTIO_S390_BUS,
> +.parent= TYPE_VIRTIO_BUS,
> +.instance_size = sizeof(VirtioBusState),
> +.class_init= virtio_s390_bus_class_init,
> +};
> +
>  static void s390_virtio_register_types(void)
>  {
> +type_register_static(&virtio_s390_bus_info);
>  type_register_static(&s390_virtio_bus_info);
>  type_register_static(&virtio_s390_device_info);
>  type_register_static(&s390_virtio_serial);
> diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
> index a83afe7..7c5a945 100644
> --- a/hw/s390-virtio-bus.h
> +++ b/hw/s390-virtio-bus.h
> @@ -22,6 +22,7 @@
>  #include "virtio-rng.h"
>  #include "virtio-serial.h"
>  #include "virtio-scsi.h"
> +#include "virtio-bus.h"
> 
>  #define VIRTIO_DEV_OFFS_TYPE 0   /* 8 bits */
>  #define VIRTIO_DEV_OFFS_NUM_VQ   1   /* 8 bits */
> @@ -57,8 +58,20 @@
>  #define S390_VIRTIO_BUS(obj) \
>   OBJECT_CHECK(VirtIOS390Bus, (obj), TYPE_S390_VIRTIO_BUS)
> 
> +/* virtio-s390-bus */
> +
> +#define TYPE_VIRTIO_S390_BUS "virtio-s390-bus"
> +#define VIRTIO_S390_BUS_GET_CLASS(obj) \
> +OBJECT_GET_CLASS(VirtioBusClass, obj, TYPE_VIRTIO_S390_BUS)
> +#define VIRTIO_PCI_BUS_CLASS(klass) \
> +OBJECT_CLASS_CHECK(VirtioBusClass, klass, TYPE_VIRTIO_S390_BUS)
> +#define VIRTIO_PCI_BUS(obj) \
> +OBJECT_CHECK(VirtioBusState, (obj), TYPE_VIRTIO_S390_BUS)

PCI? This looks wrong.

> +
>  typedef struct VirtIOS390Device VirtIOS390Device;
> 
> +VirtioBusState *virtio_s390_bus_new(VirtIOS390Device *dev);
> +
>  typedef struct VirtIOS390DeviceClass {
>  DeviceClass qdev;
>  int (*init)(VirtIOS390Device *dev);




[Qemu-devel] [PATCH 02/11] s390: Add mapping helper functions.

2013-01-24 Thread Cornelia Huck
Add s390_cpu_physical_memory_{map,unmap} with special handling
for the lowcore.

Signed-off-by: Cornelia Huck 

---

v5 -> v6:

 - Make lowcore/0 page handling easier to read
 - Make len a pointer
---
 target-s390x/cpu.h|  4 
 target-s390x/helper.c | 25 +
 2 files changed, 29 insertions(+)

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 1f2d942..7951aab 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -302,6 +302,10 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, 
target_ulong address, int rw
 
 
 #ifndef CONFIG_USER_ONLY
+void *s390_cpu_physical_memory_map(CPUS390XState *env, hwaddr addr, hwaddr 
*len,
+   int is_write);
+void s390_cpu_physical_memory_unmap(CPUS390XState *env, void *addr, hwaddr len,
+int is_write);
 void s390x_tod_timer(void *opaque);
 void s390x_cpu_timer(void *opaque);
 
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 023c074..3109c77 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -490,6 +490,31 @@ static void cpu_unmap_lowcore(LowCore *lowcore)
 cpu_physical_memory_unmap(lowcore, sizeof(LowCore), 1, sizeof(LowCore));
 }
 
+void *s390_cpu_physical_memory_map(CPUS390XState *env, hwaddr addr, hwaddr 
*len,
+   int is_write)
+{
+hwaddr start = addr;
+
+/* Mind the prefix area. */
+if (addr < 8192) {
+/* Map the lowcore. */
+start += env->psa;
+*len = MIN(*len, 8192 - addr);
+} else if ((addr >= env->psa) && (addr < env->psa + 8192)) {
+/* Map the 0 page. */
+start -= env->psa;
+*len = MIN(*len, 8192 - start);
+}
+
+return cpu_physical_memory_map(start, len, is_write);
+}
+
+void s390_cpu_physical_memory_unmap(CPUS390XState *env, void *addr, hwaddr len,
+int is_write)
+{
+cpu_physical_memory_unmap(addr, len, is_write, len);
+}
+
 static void do_svc_interrupt(CPUS390XState *env)
 {
 uint64_t mask, addr;
-- 
1.7.12.4




[Qemu-devel] [PATCH v6 00/11] s390: channel I/O support in qemu.

2013-01-24 Thread Cornelia Huck
Hi,

another round for virtual channel I/O in qemu.

The patches have been respun against current master; changelogs
are in the patches themselves.

Changes are mostly some cleanups; of note are the preparations
for VirtioBus and some changes for making the code endianness
aware.

Making s390-ccw-virtio the default machine has been deferred until
after tcg support is available.

Alexander Graf (1):
  s390: Add default support for SCLP console

Cornelia Huck (10):
  s390: Lowcore mapping helper.
  s390: Add mapping helper functions.
  s390: Channel I/O basic definitions.
  s390: I/O interrupt and machine check injection.
  s390: Add channel I/O instructions.
  s390: Virtual channel subsystem support.
  s390: Wire up channel I/O in kvm.
  s390: Add new channel I/O based virtio transport.
  s390-virtio: Factor out some initialization code.
  s390: Add s390-ccw-virtio machine.

 hw/boards.h|1 +
 hw/s390-virtio.c   |  118 ++--
 hw/s390-virtio.h   |6 +
 hw/s390x/Makefile.objs |3 +
 hw/s390x/css.c | 1277 
 hw/s390x/css.h |   99 
 hw/s390x/s390-virtio-ccw.c |  134 +
 hw/s390x/virtio-ccw.c  |  947 
 hw/s390x/virtio-ccw.h  |   94 
 target-s390x/Makefile.objs |2 +-
 target-s390x/cpu.h |  247 -
 target-s390x/helper.c  |  200 ++-
 target-s390x/ioinst.c  |  752 ++
 target-s390x/ioinst.h  |  223 
 target-s390x/kvm.c |  239 -
 trace-events   |   18 +
 vl.c   |   48 ++
 17 files changed, 4333 insertions(+), 75 deletions(-)
 create mode 100644 hw/s390x/css.c
 create mode 100644 hw/s390x/css.h
 create mode 100644 hw/s390x/s390-virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.h
 create mode 100644 target-s390x/ioinst.c
 create mode 100644 target-s390x/ioinst.h

-- 
1.7.12.4




[Qemu-devel] [PATCH 10/11] s390: Add default support for SCLP console

2013-01-24 Thread Cornelia Huck
From: Alexander Graf 

The current s390 machine uses the virtio console as default console,
but this doesn't mean that we always want to keep it that way for new
machines.

This patch introduces a way for a machine type to specify that it wants
the default console to be an SCLP console, which is a lot closer to what
real hardware does.

Signed-off-by: Alexander Graf 
Signed-off-by: Cornelia Huck 
---
 hw/boards.h |  1 +
 vl.c| 48 
 2 files changed, 49 insertions(+)

diff --git a/hw/boards.h b/hw/boards.h
index 3ff9665..3813d4e 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -33,6 +33,7 @@ typedef struct QEMUMachine {
 unsigned int no_serial:1,
 no_parallel:1,
 use_virtcon:1,
+use_sclp:1,
 no_floppy:1,
 no_cdrom:1,
 no_sdcard:1;
diff --git a/vl.c b/vl.c
index 4ee1302..6a19a8f 100644
--- a/vl.c
+++ b/vl.c
@@ -176,6 +176,7 @@ int main(int argc, char **argv)
 #define DEFAULT_RAM_SIZE 128
 
 #define MAX_VIRTIO_CONSOLES 1
+#define MAX_SCLP_CONSOLES 1
 
 static const char *data_dir;
 const char *bios_name = NULL;
@@ -203,6 +204,7 @@ int no_quit = 0;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
 CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
+CharDriverState *sclp_hds[MAX_SCLP_CONSOLES];
 int win2k_install_hack = 0;
 int singlestep = 0;
 int smp_cpus = 1;
@@ -271,6 +273,7 @@ static int tcg_tb_size;
 static int default_serial = 1;
 static int default_parallel = 1;
 static int default_virtcon = 1;
+static int default_sclp = 1;
 static int default_monitor = 1;
 static int default_floppy = 1;
 static int default_cdrom = 1;
@@ -2340,6 +2343,7 @@ struct device_config {
 DEV_VIRTCON,   /* -virtioconsole */
 DEV_DEBUGCON,  /* -debugcon */
 DEV_GDB,   /* -gdb, -s */
+DEV_SCLP,  /* s390 sclp */
 } type;
 const char *cmdline;
 Location loc;
@@ -2458,6 +2462,39 @@ static int virtcon_parse(const char *devname)
 return 0;
 }
 
+static int sclp_parse(const char *devname)
+{
+QemuOptsList *device = qemu_find_opts("device");
+static int index = 0;
+char label[32];
+QemuOpts *dev_opts;
+
+if (strcmp(devname, "none") == 0) {
+return 0;
+}
+if (index == MAX_SCLP_CONSOLES) {
+fprintf(stderr, "qemu: too many sclp consoles\n");
+exit(1);
+}
+
+assert(arch_type == QEMU_ARCH_S390X);
+
+dev_opts = qemu_opts_create(device, NULL, 0, NULL);
+qemu_opt_set(dev_opts, "driver", "sclpconsole");
+
+snprintf(label, sizeof(label), "sclpcon%d", index);
+sclp_hds[index] = qemu_chr_new(label, devname, NULL);
+if (!sclp_hds[index]) {
+fprintf(stderr, "qemu: could not connect sclp console"
+" to character backend '%s'\n", devname);
+return -1;
+}
+qemu_opt_set(dev_opts, "chardev", label);
+
+index++;
+return 0;
+}
+
 static int debugcon_parse(const char *devname)
 {   
 QemuOpts *opts;
@@ -3832,6 +3869,9 @@ int main(int argc, char **argv, char **envp)
 if (!machine->use_virtcon) {
 default_virtcon = 0;
 }
+if (!machine->use_sclp) {
+default_sclp = 0;
+}
 if (machine->no_floppy) {
 default_floppy = 0;
 }
@@ -3873,11 +3913,15 @@ int main(int argc, char **argv, char **envp)
 add_device_config(DEV_SERIAL, "mon:stdio");
 } else if (default_virtcon && default_monitor) {
 add_device_config(DEV_VIRTCON, "mon:stdio");
+} else if (default_sclp && default_monitor) {
+add_device_config(DEV_SCLP, "mon:stdio");
 } else {
 if (default_serial)
 add_device_config(DEV_SERIAL, "stdio");
 if (default_virtcon)
 add_device_config(DEV_VIRTCON, "stdio");
+if (default_sclp)
+add_device_config(DEV_SCLP, "stdio");
 if (default_monitor)
 monitor_parse("stdio", "readline");
 }
@@ -3890,6 +3934,8 @@ int main(int argc, char **argv, char **envp)
 monitor_parse("vc:80Cx24C", "readline");
 if (default_virtcon)
 add_device_config(DEV_VIRTCON, "vc:80Cx24C");
+if (default_sclp)
+add_device_config(DEV_SCLP, "vc:80Cx24C");
 }
 
 socket_init();
@@ -4060,6 +4106,8 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 if (foreach_device_config(DEV_VIRTCON, virtcon_parse) < 0)
 exit(1);
+if (foreach_device_config(DEV_SCLP, sclp_parse) < 0)
+exit(1);
 if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
 exit(1);
 
-- 
1.7.12.4




[Qemu-devel] [PATCH 11/11] s390: Add s390-ccw-virtio machine.

2013-01-24 Thread Cornelia Huck
Add a new machine type, s390-ccw-virtio, making use of the
virtio-ccw transport to present virtio devices as channel
devices.

Signed-off-by: Cornelia Huck 

---

v5 -> v6:
- Don't make virtio-ccw the default yet
- Adapt to ipl device changes
- Adapt to VirtioBus changes
- Default to sclp console
---
 hw/s390-virtio.h   |   1 +
 hw/s390x/Makefile.objs |   1 +
 hw/s390x/s390-virtio-ccw.c | 134 +
 3 files changed, 136 insertions(+)
 create mode 100644 hw/s390x/s390-virtio-ccw.c

diff --git a/hw/s390-virtio.h b/hw/s390-virtio.h
index 67bfd20..a6c4c19 100644
--- a/hw/s390-virtio.h
+++ b/hw/s390-virtio.h
@@ -15,6 +15,7 @@
 #define KVM_S390_VIRTIO_NOTIFY  0
 #define KVM_S390_VIRTIO_RESET   1
 #define KVM_S390_VIRTIO_SET_STATUS  2
+#define KVM_S390_VIRTIO_CCW_NOTIFY  3
 
 typedef int (*s390_virtio_fn)(const uint64_t *args);
 void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn);
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index f6b461b..9eed6d9 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -7,4 +7,5 @@ obj-y += event-facility.o
 obj-y += sclpquiesce.o sclpconsole.o
 obj-y += ipl.o
 obj-y += css.o
+obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
new file mode 100644
index 000..9575d00
--- /dev/null
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -0,0 +1,134 @@
+/*
+ * virtio ccw machine
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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 "hw/boards.h"
+#include "exec/address-spaces.h"
+#include "hw/s390-virtio.h"
+#include "hw/s390x/sclp.h"
+#include "ioinst.h"
+#include "css.h"
+#include "virtio-ccw.h"
+
+static int virtio_ccw_hcall_notify(const uint64_t *args)
+{
+uint64_t subch_id = args[0];
+uint64_t queue = args[1];
+SubchDev *sch;
+int cssid, ssid, schid, m;
+
+if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {
+return -EINVAL;
+}
+sch = css_find_subch(m, cssid, ssid, schid);
+if (!sch || !css_subch_visible(sch)) {
+return -EINVAL;
+}
+virtio_queue_notify(virtio_ccw_get_vdev(sch), queue);
+return 0;
+
+}
+
+static int virtio_ccw_hcall_early_printk(const uint64_t *args)
+{
+uint64_t mem = args[0];
+
+if (mem < ram_size) {
+/* Early printk */
+return 0;
+}
+return -EINVAL;
+}
+
+static void virtio_ccw_register_hcalls(void)
+{
+s390_register_virtio_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY,
+   virtio_ccw_hcall_notify);
+/* Tolerate early printk. */
+s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY,
+   virtio_ccw_hcall_early_printk);
+}
+
+static void ccw_init(QEMUMachineInitArgs *args)
+{
+ram_addr_t my_ram_size = args->ram_size;
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+int shift = 0;
+uint8_t *storage_keys;
+int ret;
+VirtualCssBus *css_bus;
+
+/* s390x ram size detection needs a 16bit multiplier + an increment. So
+   guests > 64GB can be specified in 2MB steps etc. */
+while ((my_ram_size >> (20 + shift)) > 65535) {
+shift++;
+}
+my_ram_size = my_ram_size >> (20 + shift) << (20 + shift);
+
+/* lets propagate the changed ram size into the global variable. */
+ram_size = my_ram_size;
+
+/* get a BUS */
+css_bus = virtual_css_bus_init();
+s390_sclp_init();
+s390_init_ipl_dev(args->kernel_filename, args->kernel_cmdline,
+  args->initrd_filename);
+
+/* register hypercalls */
+virtio_ccw_register_hcalls();
+
+/* allocate RAM */
+memory_region_init_ram(ram, "s390.ram", my_ram_size);
+vmstate_register_ram_global(ram);
+memory_region_add_subregion(sysmem, 0, ram);
+
+/* allocate storage keys */
+storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE);
+
+/* init CPUs */
+s390_init_cpus(args->cpu_model, storage_keys);
+
+if (kvm_enabled()) {
+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.
+ */
+ret = css_create_css_image(VIRTUAL_CSSID, true);
+assert(ret == 0);
+
+/* Create VirtIO network adapters */
+s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw");
+}
+
+static QEMUMachine ccw_machine = {
+.name = "s390-ccw-virtio",
+.alias = "s390-ccw",
+.desc = "VirtIO-ccw based S390 machine",

[Qemu-devel] [PATCH 05/11] s390: Add channel I/O instructions.

2013-01-24 Thread Cornelia Huck
Provide handlers for (most) channel I/O instructions.

Signed-off-by: Cornelia Huck 

---

v5 -> v6:
- Adapt to s390_cpu_physical_memory_map changes
- Simplify chsc handling
- Handle endianness
---
 target-s390x/cpu.h| 100 +++
 target-s390x/ioinst.c | 716 ++
 target-s390x/ioinst.h |  16 ++
 trace-events  |   6 +
 4 files changed, 838 insertions(+)

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 3e00d38..76a822c 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -147,6 +147,9 @@ static inline void cpu_clone_regs(CPUS390XState *env, 
target_ulong newsp)
 }
 #endif
 
+/* distinguish between 24 bit and 31 bit addressing */
+#define HIGH_ORDER_BIT 0x8000
+
 /* Interrupt Codes */
 /* Program Interrupts */
 #define PGM_OPERATION   0x0001
@@ -331,6 +334,20 @@ void *s390_cpu_physical_memory_map(CPUS390XState *env, 
hwaddr addr, hwaddr *len,
int is_write);
 void s390_cpu_physical_memory_unmap(CPUS390XState *env, void *addr, hwaddr len,
 int is_write);
+static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb)
+{
+hwaddr addr = 0;
+uint8_t reg;
+
+reg = ipb >> 28;
+if (reg > 0) {
+addr = env->regs[reg];
+}
+addr += (ipb >> 16) & 0xfff;
+
+return addr;
+}
+
 void s390x_tod_timer(void *opaque);
 void s390x_cpu_timer(void *opaque);
 
@@ -380,6 +397,89 @@ static inline unsigned s390_del_running_cpu(CPUS390XState 
*env)
 void cpu_lock(void);
 void cpu_unlock(void);
 
+typedef struct SubchDev SubchDev;
+
+static inline SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid,
+   uint16_t schid)
+{
+return NULL;
+}
+static inline bool css_subch_visible(SubchDev *sch)
+{
+return false;
+}
+static inline void css_conditional_io_interrupt(SubchDev *sch)
+{
+}
+static inline int css_do_stsch(SubchDev *sch, SCHIB *schib)
+{
+return -ENODEV;
+}
+static inline bool css_schid_final(uint8_t cssid, uint8_t ssid, uint16_t schid)
+{
+return true;
+}
+static inline int css_do_msch(SubchDev *sch, SCHIB *schib)
+{
+return -ENODEV;
+}
+static inline int css_do_xsch(SubchDev *sch)
+{
+return -ENODEV;
+}
+static inline int css_do_csch(SubchDev *sch)
+{
+return -ENODEV;
+}
+static inline int css_do_hsch(SubchDev *sch)
+{
+return -ENODEV;
+}
+static inline int css_do_ssch(SubchDev *sch, ORB *orb)
+{
+return -ENODEV;
+}
+static inline int css_do_tsch(SubchDev *sch, IRB *irb)
+{
+return -ENODEV;
+}
+static inline int css_do_stcrw(CRW *crw)
+{
+return 1;
+}
+static inline int css_do_tpi(uint64_t addr, int lowcore)
+{
+return 0;
+}
+static inline int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid,
+   int rfmt, uint8_t l_chpid, void *buf)
+{
+return 0;
+}
+static inline void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo)
+{
+}
+static inline int css_enable_mss(void)
+{
+return -EINVAL;
+}
+static inline int css_enable_mcsse(void)
+{
+return -EINVAL;
+}
+static inline int css_do_rsch(SubchDev *sch)
+{
+return -ENODEV;
+}
+static inline int css_do_rchp(uint8_t cssid, uint8_t chpid)
+{
+return -ENODEV;
+}
+static inline bool css_present(uint8_t cssid)
+{
+return false;
+}
+
 static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls)
 {
 env->aregs[0] = newtls >> 32;
diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
index 06a16ee..4ef2d73 100644
--- a/target-s390x/ioinst.c
+++ b/target-s390x/ioinst.c
@@ -13,6 +13,7 @@
 
 #include "cpu.h"
 #include "ioinst.h"
+#include "trace.h"
 
 int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
  int *schid)
@@ -34,3 +35,718 @@ int ioinst_disassemble_sch_ident(uint32_t value, int *m, 
int *cssid, int *ssid,
 *schid = IOINST_SCHID_NR(value);
 return 0;
 }
+
+int ioinst_handle_xsch(CPUS390XState *env, uint64_t reg1)
+{
+int cssid, ssid, schid, m;
+SubchDev *sch;
+int ret = -ENODEV;
+int cc;
+
+if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
+program_interrupt(env, PGM_OPERAND, 2);
+return -EIO;
+}
+trace_ioinst_sch_id("xsch", cssid, ssid, schid);
+sch = css_find_subch(m, cssid, ssid, schid);
+if (sch && css_subch_visible(sch)) {
+ret = css_do_xsch(sch);
+}
+switch (ret) {
+case -ENODEV:
+cc = 3;
+break;
+case -EBUSY:
+cc = 2;
+break;
+case 0:
+cc = 0;
+break;
+default:
+cc = 1;
+break;
+}
+
+return cc;
+}
+
+int ioinst_handle_csch(CPUS390XState *env, uint64_t reg1)
+{
+int cssid, ssid, schid, m;
+SubchDev *sch;
+int r

[Qemu-devel] [PATCH 08/11] s390: Add new channel I/O based virtio transport.

2013-01-24 Thread Cornelia Huck
Add a new virtio transport that uses channel commands to perform
virtio operations.

Signed-off-by: Cornelia Huck 

---

v5 -> v6:
- Get rid of qemu_get_ram_ptr usage
- Adapt to virtual css changes
- Constify TypeInfos
- Prepare for VirtioBus
---
 hw/s390x/Makefile.objs |   1 +
 hw/s390x/virtio-ccw.c  | 947 +
 hw/s390x/virtio-ccw.h  |  94 +
 trace-events   |   4 +
 4 files changed, 1046 insertions(+)
 create mode 100644 hw/s390x/virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.h

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index ab99da6..f6b461b 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -7,3 +7,4 @@ obj-y += event-facility.o
 obj-y += sclpquiesce.o sclpconsole.o
 obj-y += ipl.o
 obj-y += css.o
+obj-y += virtio-ccw.o
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
new file mode 100644
index 000..58f9982
--- /dev/null
+++ b/hw/s390x/virtio-ccw.c
@@ -0,0 +1,947 @@
+/*
+ * virtio ccw target implementation
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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 
+#include "block/block.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/sysemu.h"
+#include "net/net.h"
+#include "monitor/monitor.h"
+#include "hw/virtio.h"
+#include "hw/virtio-serial.h"
+#include "hw/virtio-net.h"
+#include "hw/sysbus.h"
+#include "qemu/bitops.h"
+#include "hw/virtio-bus.h"
+
+#include "ioinst.h"
+#include "css.h"
+#include "virtio-ccw.h"
+#include "trace.h"
+
+static const TypeInfo virtual_css_bus_info = {
+.name = TYPE_VIRTUAL_CSS_BUS,
+.parent = TYPE_BUS,
+.instance_size = sizeof(VirtualCssBus),
+};
+
+static const VirtIOBindings virtio_ccw_bindings;
+
+VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
+{
+VirtIODevice *vdev = NULL;
+
+if (sch->driver_data) {
+vdev = ((VirtioCcwData *)sch->driver_data)->vdev;
+}
+return vdev;
+}
+
+static void virtio_ccw_reset_subchannels(void *opaque)
+{
+VirtualCssBus *bus = opaque;
+BusChild *kid;
+VirtioCcwData *data;
+BusState *parent = BUS(bus);
+
+QTAILQ_FOREACH(kid, &parent->children, sibling) {
+data = (VirtioCcwData *)kid->child;
+virtio_reset(data->vdev);
+css_reset_sch(data->sch);
+}
+css_reset();
+}
+
+VirtualCssBus *virtual_css_bus_init(void)
+{
+VirtualCssBus *cbus;
+BusState *bus;
+DeviceState *dev;
+
+/* Create bridge device */
+dev = qdev_create(NULL, "virtual-css-bridge");
+qdev_init_nofail(dev);
+
+/* Create bus on bridge device */
+bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
+cbus = VIRTUAL_CSS_BUS(bus);
+
+/* Enable hotplugging */
+bus->allow_hotplug = 1;
+
+qemu_register_reset(virtio_ccw_reset_subchannels, cbus);
+return cbus;
+}
+
+/* Communication blocks used by several channel commands. */
+typedef struct VqInfoBlock {
+uint64_t queue;
+uint32_t align;
+uint16_t index;
+uint16_t num;
+} QEMU_PACKED VqInfoBlock;
+
+typedef struct VqConfigBlock {
+uint16_t index;
+uint16_t num_max;
+} QEMU_PACKED VqConfigBlock;
+
+typedef struct VirtioFeatDesc {
+uint32_t features;
+uint8_t index;
+} QEMU_PACKED VirtioFeatDesc;
+
+/* Specify where the virtqueues for the subchannel are in guest memory. */
+static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
+  uint16_t index, uint16_t num)
+{
+VirtioCcwData *data = sch->driver_data;
+
+if (index > VIRTIO_PCI_QUEUE_MAX) {
+return -EINVAL;
+}
+
+/* Current code in virtio.c relies on 4K alignment. */
+if (addr && (align != 4096)) {
+return -EINVAL;
+}
+
+if (!data) {
+return -EINVAL;
+}
+
+virtio_queue_set_addr(data->vdev, index, addr);
+if (!addr) {
+virtio_queue_set_vector(data->vdev, index, 0);
+} else {
+/* Fail if we don't have a big enough queue. */
+/* TODO: Add interface to handle vring.num changing */
+if (virtio_queue_get_num(data->vdev, index) > num) {
+return -EINVAL;
+}
+virtio_queue_set_vector(data->vdev, index, index);
+}
+/* tell notify handler in case of config change */
+data->vdev->config_vector = VIRTIO_PCI_QUEUE_MAX;
+return 0;
+}
+
+static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+{
+int ret;
+VqInfoBlock info;
+uint8_t status;
+VirtioFeatDesc features;
+void *config;
+hwaddr indicators;
+VqConfigBlock vq_config;
+VirtioCcwData *data = sch->driver_data;
+

[Qemu-devel] [PATCH 07/11] s390: Wire up channel I/O in kvm.

2013-01-24 Thread Cornelia Huck
Trigger the code for our virtual css in case of instruction
intercepts for I/O instructions.

Handle the tsch exit for the subchannel-related part of tsch.

Signed-off-by: Cornelia Huck 
---
 target-s390x/cpu.h |  11 +++
 target-s390x/kvm.c | 239 ++---
 2 files changed, 237 insertions(+), 13 deletions(-)

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 778065c..ce12fa4 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1058,6 +1058,13 @@ void QEMU_NORETURN runtime_exception(CPUS390XState *env, 
int excp,
 
 #include 
 
+#ifdef CONFIG_KVM
+void kvm_s390_io_interrupt(S390CPU *cpu, uint16_t subchannel_id,
+   uint16_t subchannel_nr, uint32_t io_int_parm,
+   uint32_t io_int_word);
+void kvm_s390_crw_mchk(S390CPU *cpu);
+void kvm_s390_enable_css_support(S390CPU *cpu);
+#else
 static inline void kvm_s390_io_interrupt(S390CPU *cpu,
 uint16_t subchannel_id,
 uint16_t subchannel_nr,
@@ -1068,6 +1075,10 @@ static inline void kvm_s390_io_interrupt(S390CPU *cpu,
 static inline void kvm_s390_crw_mchk(S390CPU *cpu)
 {
 }
+static inline void kvm_s390_enable_css_support(S390CPU *cpu)
+{
+}
+#endif
 
 static inline void s390_io_interrupt(S390CPU *cpu,
  uint16_t subchannel_id,
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index add6a58..e876406 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -47,9 +47,29 @@
 
 #define IPA0_DIAG   0x8300
 #define IPA0_SIGP   0xae00
-#define IPA0_PRIV   0xb200
+#define IPA0_B2 0xb200
+#define IPA0_B9 0xb900
+#define IPA0_EB 0xeb00
 
 #define PRIV_SCLP_CALL  0x20
+#define PRIV_CSCH   0x30
+#define PRIV_HSCH   0x31
+#define PRIV_MSCH   0x32
+#define PRIV_SSCH   0x33
+#define PRIV_STSCH  0x34
+#define PRIV_TSCH   0x35
+#define PRIV_TPI0x36
+#define PRIV_SAL0x37
+#define PRIV_RSCH   0x38
+#define PRIV_STCRW  0x39
+#define PRIV_STCPS  0x3a
+#define PRIV_RCHP   0x3b
+#define PRIV_SCHM   0x3c
+#define PRIV_CHSC   0x5f
+#define PRIV_SIGA   0x74
+#define PRIV_XSCH   0x76
+#define PRIV_SQBS   0x8a
+#define PRIV_EQBS   0x9c
 #define DIAG_KVM_HYPERCALL  0x500
 #define DIAG_KVM_BREAKPOINT 0x501
 
@@ -375,10 +395,123 @@ static int kvm_sclp_service_call(S390CPU *cpu, struct 
kvm_run *run,
 return 0;
 }
 
-static int handle_priv(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
+static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run,
+   uint8_t ipa0, uint8_t ipa1, uint8_t ipb)
+{
+int r = 0;
+int no_cc = 0;
+CPUS390XState *env = &cpu->env;
+
+if (ipa0 != 0xb2) {
+/* Not handled for now. */
+return -1;
+}
+cpu_synchronize_state(env);
+switch (ipa1) {
+case PRIV_XSCH:
+r = ioinst_handle_xsch(env, env->regs[1]);
+break;
+case PRIV_CSCH:
+r = ioinst_handle_csch(env, env->regs[1]);
+break;
+case PRIV_HSCH:
+r = ioinst_handle_hsch(env, env->regs[1]);
+break;
+case PRIV_MSCH:
+r = ioinst_handle_msch(env, env->regs[1], run->s390_sieic.ipb);
+break;
+case PRIV_SSCH:
+r = ioinst_handle_ssch(env, env->regs[1], run->s390_sieic.ipb);
+break;
+case PRIV_STCRW:
+r = ioinst_handle_stcrw(env, run->s390_sieic.ipb);
+break;
+case PRIV_STSCH:
+r = ioinst_handle_stsch(env, env->regs[1], run->s390_sieic.ipb);
+break;
+case PRIV_TSCH:
+/* We should only get tsch via KVM_EXIT_S390_TSCH. */
+fprintf(stderr, "Spurious tsch intercept\n");
+break;
+case PRIV_CHSC:
+r = ioinst_handle_chsc(env, run->s390_sieic.ipb);
+break;
+case PRIV_TPI:
+/* This should have been handled by kvm already. */
+fprintf(stderr, "Spurious tpi intercept\n");
+break;
+case PRIV_SCHM:
+no_cc = 1;
+r = ioinst_handle_schm(env, env->regs[1], env->regs[2],
+   run->s390_sieic.ipb);
+break;
+case PRIV_RSCH:
+r = ioinst_handle_rsch(env, env->regs[1]);
+break;
+case PRIV_RCHP:
+r = ioinst_handle_rchp(env, env->regs[1]);
+break;
+case PRIV_STCPS:
+/* We do not provide this instruction, it is suppressed

[Qemu-devel] [PATCH 03/11] s390: Channel I/O basic definitions.

2013-01-24 Thread Cornelia Huck
Basic channel I/O structures and helper function.

Signed-off-by: Cornelia Huck 

---

v5 -> v6:
 - Move typedefs into ioinst.h and include ioinst.h in cpu.h instead
---
 target-s390x/Makefile.objs |   2 +-
 target-s390x/cpu.h |   1 +
 target-s390x/ioinst.c  |  36 
 target-s390x/ioinst.h  | 207 +
 4 files changed, 245 insertions(+), 1 deletion(-)
 create mode 100644 target-s390x/ioinst.c
 create mode 100644 target-s390x/ioinst.h

diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index e728abf..3afb0b7 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,4 +1,4 @@
 obj-y += translate.o helper.o cpu.o interrupt.o
 obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
-obj-$(CONFIG_SOFTMMU) += machine.o
+obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o
 obj-$(CONFIG_KVM) += kvm.o
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 7951aab..c1a0040 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -300,6 +300,7 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, 
target_ulong address, int rw
 int mmu_idx);
 #define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault
 
+#include "ioinst.h"
 
 #ifndef CONFIG_USER_ONLY
 void *s390_cpu_physical_memory_map(CPUS390XState *env, hwaddr addr, hwaddr 
*len,
diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
new file mode 100644
index 000..06a16ee
--- /dev/null
+++ b/target-s390x/ioinst.c
@@ -0,0 +1,36 @@
+/*
+ * I/O instructions for S/390
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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 
+
+#include "cpu.h"
+#include "ioinst.h"
+
+int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
+ int *schid)
+{
+if (!IOINST_SCHID_ONE(value)) {
+return -EINVAL;
+}
+if (!IOINST_SCHID_M(value)) {
+if (IOINST_SCHID_CSSID(value)) {
+return -EINVAL;
+}
+*cssid = 0;
+*m = 0;
+} else {
+*cssid = IOINST_SCHID_CSSID(value);
+*m = 1;
+}
+*ssid = IOINST_SCHID_SSID(value);
+*schid = IOINST_SCHID_NR(value);
+return 0;
+}
diff --git a/target-s390x/ioinst.h b/target-s390x/ioinst.h
new file mode 100644
index 000..037aabc
--- /dev/null
+++ b/target-s390x/ioinst.h
@@ -0,0 +1,207 @@
+/*
+ * S/390 channel I/O instructions
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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 IOINST_S390X_H
+#define IOINST_S390X_H
+/*
+ * Channel I/O related definitions, as defined in the Principles
+ * Of Operation (and taken from the Linux implementation).
+ */
+
+/* subchannel status word (command mode only) */
+typedef struct SCSW {
+uint16_t flags;
+uint16_t ctrl;
+uint32_t cpa;
+uint8_t dstat;
+uint8_t cstat;
+uint16_t count;
+} QEMU_PACKED SCSW;
+
+#define SCSW_FLAGS_MASK_KEY 0xf000
+#define SCSW_FLAGS_MASK_SCTL 0x0800
+#define SCSW_FLAGS_MASK_ESWF 0x0400
+#define SCSW_FLAGS_MASK_CC 0x0300
+#define SCSW_FLAGS_MASK_FMT 0x0080
+#define SCSW_FLAGS_MASK_PFCH 0x0040
+#define SCSW_FLAGS_MASK_ISIC 0x0020
+#define SCSW_FLAGS_MASK_ALCC 0x0010
+#define SCSW_FLAGS_MASK_SSI 0x0008
+#define SCSW_FLAGS_MASK_ZCC 0x0004
+#define SCSW_FLAGS_MASK_ECTL 0x0002
+#define SCSW_FLAGS_MASK_PNO 0x0001
+
+#define SCSW_CTRL_MASK_FCTL 0x7000
+#define SCSW_CTRL_MASK_ACTL 0x0fe0
+#define SCSW_CTRL_MASK_STCTL 0x001f
+
+#define SCSW_FCTL_CLEAR_FUNC 0x1000
+#define SCSW_FCTL_HALT_FUNC 0x2000
+#define SCSW_FCTL_START_FUNC 0x4000
+
+#define SCSW_ACTL_SUSP 0x0020
+#define SCSW_ACTL_DEVICE_ACTIVE 0x0040
+#define SCSW_ACTL_SUBCH_ACTIVE 0x0080
+#define SCSW_ACTL_CLEAR_PEND 0x0100
+#define SCSW_ACTL_HALT_PEND  0x0200
+#define SCSW_ACTL_START_PEND 0x0400
+#define SCSW_ACTL_RESUME_PEND 0x0800
+
+#define SCSW_STCTL_STATUS_PEND 0x0001
+#define SCSW_STCTL_SECONDARY 0x0002
+#define SCSW_STCTL_PRIMARY 0x0004
+#define SCSW_STCTL_INTERMEDIATE 0x0008
+#define SCSW_STCTL_ALERT 0x0010
+
+#define SCSW_DSTAT_ATTENTION 0x80
+#define SCSW_DSTAT_STAT_MOD  0x40
+#define SCSW_DSTAT_CU_END0x20
+#define SCSW_DSTAT_BUSY  0x10
+#define SCSW_DSTAT_CHANNEL_END   0x08
+#define SCSW_DSTAT_DEVICE_END0x04
+#define SCSW_DSTAT_UNIT_CHECK0x02
+#define SCSW_DSTAT_UNIT_EXCEP0x01
+
+#define SCSW_CSTAT_PCI   0x80
+#define SCSW_CSTAT_INCORR_LEN0x40
+#define SCSW_CSTAT_PROG_CHECK0x20
+#define SCSW_CSTAT_PROT_CHECK0x10
+#define SCSW_CSTAT_DATA_CHECK0x08
+#define SCSW_CSTAT_CHN_CTRL_CHK  0x04
+#define SCSW_CSTAT_INTF_CTRL_CHK 0x02
+#define SCSW_CS

[Qemu-devel] [PATCH 09/11] s390-virtio: Factor out some initialization code.

2013-01-24 Thread Cornelia Huck
Some of the machine initialization for s390-virtio will be reused
by virtio-ccw.

Signed-off-by: Cornelia Huck 

---

v5 -> v6:
- Adapt to ipl device changes
---
 hw/s390-virtio.c | 118 +++
 hw/s390-virtio.h |   5 +++
 2 files changed, 72 insertions(+), 51 deletions(-)

diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 5edaabb..6e0f53b 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -147,13 +147,73 @@ unsigned s390_del_running_cpu(CPUS390XState *env)
 return s390_running_cpus;
 }
 
+void s390_init_ipl_dev(const char *kernel_filename,
+   const char *kernel_cmdline,
+   const char *initrd_filename)
+{
+DeviceState *dev;
+
+dev  = qdev_create(NULL, "s390-ipl");
+if (kernel_filename) {
+qdev_prop_set_string(dev, "kernel", kernel_filename);
+}
+if (initrd_filename) {
+qdev_prop_set_string(dev, "initrd", initrd_filename);
+}
+qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
+qdev_init_nofail(dev);
+}
+
+void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys)
+{
+int i;
+
+if (cpu_model == NULL) {
+cpu_model = "host";
+}
+
+ipi_states = g_malloc(sizeof(S390CPU *) * smp_cpus);
+
+for (i = 0; i < smp_cpus; i++) {
+S390CPU *cpu;
+
+cpu = cpu_s390x_init(cpu_model);
+
+ipi_states[i] = cpu;
+cpu->env.halted = 1;
+cpu->env.exception_index = EXCP_HLT;
+cpu->env.storage_keys = storage_keys;
+}
+}
+
+
+void s390_create_virtio_net(BusState *bus, const char *name)
+{
+int i;
+
+for (i = 0; i < nb_nics; i++) {
+NICInfo *nd = &nd_table[i];
+DeviceState *dev;
+
+if (!nd->model) {
+nd->model = g_strdup("virtio");
+}
+
+if (strcmp(nd->model, "virtio")) {
+fprintf(stderr, "S390 only supports VirtIO nics\n");
+exit(1);
+}
+
+dev = qdev_create(bus, name);
+qdev_set_nic_properties(dev, nd);
+qdev_init_nofail(dev);
+}
+}
+
 /* PC hardware initialisation */
 static void s390_init(QEMUMachineInitArgs *args)
 {
 ram_addr_t my_ram_size = args->ram_size;
-const char *cpu_model = args->cpu_model;
-CPUS390XState *env = NULL;
-DeviceState *dev;
 MemoryRegion *sysmem = get_system_memory();
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 int shift = 0;
@@ -161,7 +221,6 @@ static void s390_init(QEMUMachineInitArgs *args)
 void *virtio_region;
 hwaddr virtio_region_len;
 hwaddr virtio_region_start;
-int i;
 
 /* s390x ram size detection needs a 16bit multiplier + an increment. So
guests > 64GB can be specified in 2MB steps etc. */
@@ -176,15 +235,8 @@ static void s390_init(QEMUMachineInitArgs *args)
 /* get a BUS */
 s390_bus = s390_virtio_bus_init(&my_ram_size);
 s390_sclp_init();
-dev  = qdev_create(NULL, "s390-ipl");
-if (args->kernel_filename) {
-qdev_prop_set_string(dev, "kernel", args->kernel_filename);
-}
-if (args->initrd_filename) {
-qdev_prop_set_string(dev, "initrd", args->initrd_filename);
-}
-qdev_prop_set_string(dev, "cmdline", args->kernel_cmdline);
-qdev_init_nofail(dev);
+s390_init_ipl_dev(args->kernel_filename, args->kernel_cmdline,
+  args->initrd_filename);
 
 /* register hypercalls */
 s390_virtio_register_hcalls();
@@ -207,46 +259,10 @@ static void s390_init(QEMUMachineInitArgs *args)
 storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE);
 
 /* init CPUs */
-if (cpu_model == NULL) {
-cpu_model = "host";
-}
-
-ipi_states = g_malloc(sizeof(S390CPU *) * smp_cpus);
-
-for (i = 0; i < smp_cpus; i++) {
-S390CPU *cpu;
-CPUS390XState *tmp_env;
-
-cpu = cpu_s390x_init(cpu_model);
-tmp_env = &cpu->env;
-if (!env) {
-env = tmp_env;
-}
-ipi_states[i] = cpu;
-tmp_env->halted = 1;
-tmp_env->exception_index = EXCP_HLT;
-tmp_env->storage_keys = storage_keys;
-}
-
+s390_init_cpus(args->cpu_model, storage_keys);
 
 /* Create VirtIO network adapters */
-for(i = 0; i < nb_nics; i++) {
-NICInfo *nd = &nd_table[i];
-DeviceState *dev;
-
-if (!nd->model) {
-nd->model = g_strdup("virtio");
-}
-
-if (strcmp(nd->model, "virtio")) {
-fprintf(stderr, "S390 only supports VirtIO nics\n");
-exit(1);
-}
-
-dev = qdev_create((BusState *)s390_bus, "virtio-net-s390");
-qdev_set_nic_properties(dev, nd);
-qdev_init_nofail(dev)

[Qemu-devel] [PATCH 06/11] s390: Virtual channel subsystem support.

2013-01-24 Thread Cornelia Huck
Provide a mechanism for qemu to provide fully virtual subchannels to
the guest.

Signed-off-by: Cornelia Huck 

---

v5 -> v6:
- Remove extraneous NULL pointer checks
- Use helper function to build subchannel id
- Endianness
- Get rid of qemu_get_ram_ptr
- Move kvm_enabled() check into generic code
- Define CIWs properly
---
 hw/s390x/Makefile.objs |1 +
 hw/s390x/css.c | 1277 
 hw/s390x/css.h |   99 
 target-s390x/cpu.h |   62 +++
 trace-events   |8 +
 5 files changed, 1447 insertions(+)
 create mode 100644 hw/s390x/css.c
 create mode 100644 hw/s390x/css.h

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 1b40c2e..ab99da6 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -6,3 +6,4 @@ obj-y += sclp.o
 obj-y += event-facility.o
 obj-y += sclpquiesce.o sclpconsole.o
 obj-y += ipl.o
+obj-y += css.o
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
new file mode 100644
index 000..113ac9a
--- /dev/null
+++ b/hw/s390x/css.c
@@ -0,0 +1,1277 @@
+/*
+ * Channel subsystem base support.
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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 
+#include "qemu/bitops.h"
+#include "cpu.h"
+#include "ioinst.h"
+#include "css.h"
+#include "trace.h"
+
+typedef struct CrwContainer {
+CRW crw;
+QTAILQ_ENTRY(CrwContainer) sibling;
+} CrwContainer;
+
+typedef struct ChpInfo {
+uint8_t in_use;
+uint8_t type;
+uint8_t is_virtual;
+} ChpInfo;
+
+typedef struct SubchSet {
+SubchDev *sch[MAX_SCHID + 1];
+unsigned long schids_used[BITS_TO_LONGS(MAX_SCHID + 1)];
+unsigned long devnos_used[BITS_TO_LONGS(MAX_SCHID + 1)];
+} SubchSet;
+
+typedef struct CssImage {
+SubchSet *sch_set[MAX_SSID + 1];
+ChpInfo chpids[MAX_CHPID + 1];
+} CssImage;
+
+typedef struct ChannelSubSys {
+QTAILQ_HEAD(, CrwContainer) pending_crws;
+bool do_crw_mchk;
+bool crws_lost;
+uint8_t max_cssid;
+uint8_t max_ssid;
+bool chnmon_active;
+uint64_t chnmon_area;
+CssImage *css[MAX_CSSID + 1];
+uint8_t default_cssid;
+} ChannelSubSys;
+
+static ChannelSubSys *channel_subsys;
+
+int css_create_css_image(uint8_t cssid, bool default_image)
+{
+trace_css_new_image(cssid, default_image ? "(default)" : "");
+if (cssid > MAX_CSSID) {
+return -EINVAL;
+}
+if (channel_subsys->css[cssid]) {
+return -EBUSY;
+}
+channel_subsys->css[cssid] = g_malloc0(sizeof(CssImage));
+if (default_image) {
+channel_subsys->default_cssid = cssid;
+}
+return 0;
+}
+
+static uint16_t css_build_subchannel_id(SubchDev *sch)
+{
+if (channel_subsys->max_cssid > 0) {
+return (sch->cssid << 8) | (1 << 3) | (sch->ssid << 1) | 1;
+}
+return (sch->ssid << 1) | 1;
+}
+
+static void css_inject_io_interrupt(SubchDev *sch)
+{
+S390CPU *cpu = s390_cpu_addr2state(0);
+uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 11;
+
+trace_css_io_interrupt(sch->cssid, sch->ssid, sch->schid,
+   sch->curr_status.pmcw.intparm, isc, "");
+s390_io_interrupt(cpu,
+  css_build_subchannel_id(sch),
+  sch->schid,
+  sch->curr_status.pmcw.intparm,
+  (0x80 >> isc) << 24);
+}
+
+void css_conditional_io_interrupt(SubchDev *sch)
+{
+/*
+ * If the subchannel is not currently status pending, make it pending
+ * with alert status.
+ */
+if (!(sch->curr_status.scsw.ctrl & SCSW_STCTL_STATUS_PEND)) {
+S390CPU *cpu = s390_cpu_addr2state(0);
+uint8_t isc = (sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ISC) >> 
11;
+
+trace_css_io_interrupt(sch->cssid, sch->ssid, sch->schid,
+   sch->curr_status.pmcw.intparm, isc,
+   "(unsolicited)");
+sch->curr_status.scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
+sch->curr_status.scsw.ctrl |=
+SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
+/* Inject an I/O interrupt. */
+s390_io_interrupt(cpu,
+  css_build_subchannel_id(sch),
+  sch->schid,
+  sch->curr_status.pmcw.intparm,
+  (0x80 >> isc) << 24);
+}
+}
+
+static void sch_handle_clear_func(SubchDev *sch)
+{
+PMCW *p = &sch->curr_status.pmcw;
+SCSW *s = &sch->curr_status.scsw;
+int path;
+
+/* Path management: In our simple css, we always choose the only pat

[Qemu-devel] [PATCH 01/11] s390: Lowcore mapping helper.

2013-01-24 Thread Cornelia Huck
Create a lowcore mapping helper that includes a check for sufficient
length.

Signed-off-by: Cornelia Huck 

---

v5 -> v6:

 - Check returned len of cpu_physical_memory_map
 - Don't pass lowcore len
---
 target-s390x/helper.c | 34 +-
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 9a132e6..023c074 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -471,13 +471,31 @@ static uint64_t get_psw_mask(CPUS390XState *env)
 return r;
 }
 
+static LowCore *cpu_map_lowcore(CPUS390XState *env)
+{
+LowCore *lowcore;
+hwaddr len = sizeof(LowCore);
+
+lowcore = cpu_physical_memory_map(env->psa, &len, 1);
+
+if (len < sizeof(LowCore)) {
+cpu_abort(env, "Could not map lowcore\n");
+}
+
+return lowcore;
+}
+
+static void cpu_unmap_lowcore(LowCore *lowcore)
+{
+cpu_physical_memory_unmap(lowcore, sizeof(LowCore), 1, sizeof(LowCore));
+}
+
 static void do_svc_interrupt(CPUS390XState *env)
 {
 uint64_t mask, addr;
 LowCore *lowcore;
-hwaddr len = TARGET_PAGE_SIZE;
 
-lowcore = cpu_physical_memory_map(env->psa, &len, 1);
+lowcore = cpu_map_lowcore(env);
 
 lowcore->svc_code = cpu_to_be16(env->int_svc_code);
 lowcore->svc_ilen = cpu_to_be16(env->int_svc_ilen);
@@ -486,7 +504,7 @@ static void do_svc_interrupt(CPUS390XState *env)
 mask = be64_to_cpu(lowcore->svc_new_psw.mask);
 addr = be64_to_cpu(lowcore->svc_new_psw.addr);
 
-cpu_physical_memory_unmap(lowcore, len, 1, len);
+cpu_unmap_lowcore(lowcore);
 
 load_psw(env, mask, addr);
 }
@@ -495,7 +513,6 @@ static void do_program_interrupt(CPUS390XState *env)
 {
 uint64_t mask, addr;
 LowCore *lowcore;
-hwaddr len = TARGET_PAGE_SIZE;
 int ilen = env->int_pgm_ilen;
 
 switch (ilen) {
@@ -513,7 +530,7 @@ static void do_program_interrupt(CPUS390XState *env)
 qemu_log_mask(CPU_LOG_INT, "%s: code=0x%x ilen=%d\n",
   __func__, env->int_pgm_code, ilen);
 
-lowcore = cpu_physical_memory_map(env->psa, &len, 1);
+lowcore = cpu_map_lowcore(env);
 
 lowcore->pgm_ilen = cpu_to_be16(ilen);
 lowcore->pgm_code = cpu_to_be16(env->int_pgm_code);
@@ -522,7 +539,7 @@ static void do_program_interrupt(CPUS390XState *env)
 mask = be64_to_cpu(lowcore->program_new_psw.mask);
 addr = be64_to_cpu(lowcore->program_new_psw.addr);
 
-cpu_physical_memory_unmap(lowcore, len, 1, len);
+cpu_unmap_lowcore(lowcore);
 
 DPRINTF("%s: %x %x %" PRIx64 " %" PRIx64 "\n", __func__,
 env->int_pgm_code, ilen, env->psw.mask,
@@ -537,7 +554,6 @@ static void do_ext_interrupt(CPUS390XState *env)
 {
 uint64_t mask, addr;
 LowCore *lowcore;
-hwaddr len = TARGET_PAGE_SIZE;
 ExtQueue *q;
 
 if (!(env->psw.mask & PSW_MASK_EXT)) {
@@ -549,7 +565,7 @@ static void do_ext_interrupt(CPUS390XState *env)
 }
 
 q = &env->ext_queue[env->ext_index];
-lowcore = cpu_physical_memory_map(env->psa, &len, 1);
+lowcore = cpu_map_lowcore(env);
 
 lowcore->ext_int_code = cpu_to_be16(q->code);
 lowcore->ext_params = cpu_to_be32(q->param);
@@ -560,7 +576,7 @@ static void do_ext_interrupt(CPUS390XState *env)
 mask = be64_to_cpu(lowcore->external_new_psw.mask);
 addr = be64_to_cpu(lowcore->external_new_psw.addr);
 
-cpu_physical_memory_unmap(lowcore, len, 1, len);
+cpu_unmap_lowcore(lowcore);
 
 env->ext_index--;
 if (env->ext_index == -1) {
-- 
1.7.12.4




[Qemu-devel] [PATCH 04/11] s390: I/O interrupt and machine check injection.

2013-01-24 Thread Cornelia Huck
I/O interrupts are queued per isc. Only crw pending machine checks
are supported.

Signed-off-by: Cornelia Huck 

---

v5 -> v6:
 - Adapt to cpu_map_lowcore changes
---
 target-s390x/cpu.h|  69 +++-
 target-s390x/helper.c | 141 ++
 2 files changed, 209 insertions(+), 1 deletion(-)

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index c1a0040..3e00d38 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -50,6 +50,11 @@
 #define MMU_USER_IDX 1
 
 #define MAX_EXT_QUEUE 16
+#define MAX_IO_QUEUE 16
+#define MAX_MCHK_QUEUE 16
+
+#define PSW_MCHK_MASK 0x0004
+#define PSW_IO_MASK 0x0200
 
 typedef struct PSW {
 uint64_t mask;
@@ -62,6 +67,17 @@ typedef struct ExtQueue {
 uint32_t param64;
 } ExtQueue;
 
+typedef struct IOIntQueue {
+uint16_t id;
+uint16_t nr;
+uint32_t parm;
+uint32_t word;
+} IOIntQueue;
+
+typedef struct MchkQueue {
+uint16_t type;
+} MchkQueue;
+
 typedef struct CPUS390XState {
 uint64_t regs[16]; /* GP registers */
 CPU_DoubleU fregs[16]; /* FP registers */
@@ -93,9 +109,17 @@ typedef struct CPUS390XState {
 uint64_t cregs[16]; /* control registers */
 
 ExtQueue ext_queue[MAX_EXT_QUEUE];
-int pending_int;
+IOIntQueue io_queue[MAX_IO_QUEUE][8];
+MchkQueue mchk_queue[MAX_MCHK_QUEUE];
 
+int pending_int;
 int ext_index;
+int io_index[8];
+int mchk_index;
+
+uint64_t ckc;
+uint64_t cputm;
+uint32_t todpr;
 
 CPU_COMMON
 
@@ -375,10 +399,14 @@ void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 #define EXCP_EXT 1 /* external interrupt */
 #define EXCP_SVC 2 /* supervisor call (syscall) */
 #define EXCP_PGM 3 /* program interruption */
+#define EXCP_IO  7 /* I/O interrupt */
+#define EXCP_MCHK 8 /* machine check */
 
 #define INTERRUPT_EXT(1 << 0)
 #define INTERRUPT_TOD(1 << 1)
 #define INTERRUPT_CPUTIMER   (1 << 2)
+#define INTERRUPT_IO (1 << 3)
+#define INTERRUPT_MCHK   (1 << 4)
 
 /* Program Status Word.  */
 #define S390_PSWM_REGNUM 0
@@ -841,6 +869,45 @@ static inline void cpu_inject_ext(CPUS390XState *env, 
uint32_t code, uint32_t pa
 cpu_interrupt(env, CPU_INTERRUPT_HARD);
 }
 
+static inline void cpu_inject_io(CPUS390XState *env, uint16_t subchannel_id,
+ uint16_t subchannel_number,
+ uint32_t io_int_parm, uint32_t io_int_word)
+{
+int isc = ffs(io_int_word << 2) - 1;
+
+if (env->io_index[isc] == MAX_IO_QUEUE - 1) {
+/* ugh - can't queue anymore. Let's drop. */
+return;
+}
+
+env->io_index[isc]++;
+assert(env->io_index[isc] < MAX_IO_QUEUE);
+
+env->io_queue[env->io_index[isc]][isc].id = subchannel_id;
+env->io_queue[env->io_index[isc]][isc].nr = subchannel_number;
+env->io_queue[env->io_index[isc]][isc].parm = io_int_parm;
+env->io_queue[env->io_index[isc]][isc].word = io_int_word;
+
+env->pending_int |= INTERRUPT_IO;
+cpu_interrupt(env, CPU_INTERRUPT_HARD);
+}
+
+static inline void cpu_inject_crw_mchk(CPUS390XState *env)
+{
+if (env->mchk_index == MAX_MCHK_QUEUE - 1) {
+/* ugh - can't queue anymore. Let's drop. */
+return;
+}
+
+env->mchk_index++;
+assert(env->mchk_index < MAX_MCHK_QUEUE);
+
+env->mchk_queue[env->mchk_index].type = 1;
+
+env->pending_int |= INTERRUPT_MCHK;
+cpu_interrupt(env, CPU_INTERRUPT_HARD);
+}
+
 static inline bool cpu_has_work(CPUState *cpu)
 {
 CPUS390XState *env = &S390_CPU(cpu)->env;
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 3109c77..857c897 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -614,12 +614,140 @@ static void do_ext_interrupt(CPUS390XState *env)
 load_psw(env, mask, addr);
 }
 
+static void do_io_interrupt(CPUS390XState *env)
+{
+uint64_t mask, addr;
+LowCore *lowcore;
+IOIntQueue *q;
+uint8_t isc;
+int disable = 1;
+int found = 0;
+
+if (!(env->psw.mask & PSW_MASK_IO)) {
+cpu_abort(env, "I/O int w/o I/O mask\n");
+}
+
+for (isc = 0; isc < ARRAY_SIZE(env->io_index); isc++) {
+if (env->io_index[isc] < 0) {
+continue;
+}
+if (env->io_index[isc] > MAX_IO_QUEUE) {
+cpu_abort(env, "I/O queue overrun for isc %d: %d\n",
+  isc, env->io_index[isc]);
+}
+
+q = &env->io_queue[env->io_index[isc]][isc];
+if (!(env->cregs[6] & q->word)) {
+disable = 0;
+continue;
+}
+found = 1;
+lowcore = cpu_map_lowcore(env);
+
+lowcore->subchannel_id = cpu_to_be16(q->id);
+lowcore->subchannel_nr = cpu_to_be16(q->nr);
+  

Re: [Qemu-devel] [PATCH 08/11] s390: Add new channel I/O based virtio transport.

2013-01-24 Thread Cornelia Huck
On Thu, 24 Jan 2013 14:18:10 +0100
Andreas Färber  wrote:

> Am 24.01.2013 13:28, schrieb Cornelia Huck:
> > Add a new virtio transport that uses channel commands to perform
> > virtio operations.
> > 
> > Signed-off-by: Cornelia Huck 
> > 
> > ---
> > 
> > v5 -> v6:
> > - Get rid of qemu_get_ram_ptr usage
> > - Adapt to virtual css changes
> > - Constify TypeInfos
> > - Prepare for VirtioBus
> > ---
> >  hw/s390x/Makefile.objs |   1 +
> >  hw/s390x/virtio-ccw.c  | 947 
> > +
> >  hw/s390x/virtio-ccw.h  |  94 +
> >  trace-events   |   4 +
> >  4 files changed, 1046 insertions(+)
> >  create mode 100644 hw/s390x/virtio-ccw.c
> >  create mode 100644 hw/s390x/virtio-ccw.h
> > 
> > diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
> > index ab99da6..f6b461b 100644
> > --- a/hw/s390x/Makefile.objs
> > +++ b/hw/s390x/Makefile.objs
> > @@ -7,3 +7,4 @@ obj-y += event-facility.o
> >  obj-y += sclpquiesce.o sclpconsole.o
> >  obj-y += ipl.o
> >  obj-y += css.o
> > +obj-y += virtio-ccw.o
> > diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> > new file mode 100644
> > index 000..58f9982
> > --- /dev/null
> > +++ b/hw/s390x/virtio-ccw.c
> > @@ -0,0 +1,947 @@
> > +/*
> > + * virtio ccw target implementation
> > + *
> > + * Copyright 2012 IBM Corp.
> > + * Author(s): Cornelia Huck 
> > + *
> > + * 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 
> 
> "hw/hw.h"?

ok

> 
> > +#include "block/block.h"
> > +#include "sysemu/blockdev.h"
> > +#include "sysemu/sysemu.h"
> > +#include "net/net.h"
> > +#include "monitor/monitor.h"
> > +#include "hw/virtio.h"
> > +#include "hw/virtio-serial.h"
> > +#include "hw/virtio-net.h"
> > +#include "hw/sysbus.h"
> > +#include "qemu/bitops.h"
> > +#include "hw/virtio-bus.h"
> > +
> > +#include "ioinst.h"
> > +#include "css.h"
> > +#include "virtio-ccw.h"
> > +#include "trace.h"
> > +
> > +static const TypeInfo virtual_css_bus_info = {
> > +.name = TYPE_VIRTUAL_CSS_BUS,
> > +.parent = TYPE_BUS,
> > +.instance_size = sizeof(VirtualCssBus),
> > +};
> > +
> > +static const VirtIOBindings virtio_ccw_bindings;
> > +
> > +VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
> > +{
> > +VirtIODevice *vdev = NULL;
> > +
> > +if (sch->driver_data) {
> > +vdev = ((VirtioCcwData *)sch->driver_data)->vdev;
> > +}
> > +return vdev;
> > +}
> > +
> > +static void virtio_ccw_reset_subchannels(void *opaque)
> > +{
> > +VirtualCssBus *bus = opaque;
> > +BusChild *kid;
> > +VirtioCcwData *data;
> > +BusState *parent = BUS(bus);
> > +
> > +QTAILQ_FOREACH(kid, &parent->children, sibling) {
> > +data = (VirtioCcwData *)kid->child;
> > +virtio_reset(data->vdev);
> > +css_reset_sch(data->sch);
> > +}
> > +css_reset();
> > +}
> > +
> > +VirtualCssBus *virtual_css_bus_init(void)
> > +{
> > +VirtualCssBus *cbus;
> > +BusState *bus;
> > +DeviceState *dev;
> > +
> > +/* Create bridge device */
> > +dev = qdev_create(NULL, "virtual-css-bridge");
> > +qdev_init_nofail(dev);
> > +
> > +/* Create bus on bridge device */
> > +bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
> > +cbus = VIRTUAL_CSS_BUS(bus);
> > +
> > +/* Enable hotplugging */
> > +bus->allow_hotplug = 1;
> > +
> > +qemu_register_reset(virtio_ccw_reset_subchannels, cbus);
> 
> Can't this be done via BusClass::reset? (requires reordering before
> TypeInfo / class_init)

This got lost somewhere during my rebasing, I'll re-add.

> 
> > +return cbus;
> > +}
> > +
> > +/* Communication blocks used by several channel commands. */
> > +typedef struct VqInfoBlock {
> > +uint64_t queue;
> > +uint32_t align;
> > +uint16_t index;
> > +uint16_t num;
> > +} QEMU_PACKED VqInfoBlock;
> >

Re: [Qemu-devel] [PATCH 08/11] s390: Add new channel I/O based virtio transport.

2013-01-24 Thread Cornelia Huck
On Thu, 24 Jan 2013 14:18:10 +0100
Andreas Färber  wrote:

Forgot one point :)

> > +/* DeviceState to VirtioCcwData. Note: used on datapath,
> > + * be careful and test performance if you change this.
> > + */
> > +static inline VirtioCcwData *to_virtio_ccw_data_fast(DeviceState *d)
> > +{
> > +return container_of(d, VirtioCcwData, parent_obj);
> > +}
> > +
> > +/* DeviceState to VirtioCcwData. TODO: use QOM. */
> 
> Are the prerequisites to resolve this TODO not yet in qemu.git?

This is copied verbatim from s390-virtio-bus/virtio-pci; my guess it
that it will be resolved tree-wide.

> 
> > +static inline VirtioCcwData *to_virtio_ccw_data(DeviceState *d)
> > +{
> > +return container_of(d, VirtioCcwData, parent_obj);
> > +}
> > +




[Qemu-devel] [PATCH v7 0/2] s390: virtio-ccw transport.

2013-01-24 Thread Cornelia Huck
Hi,

here's the next iteration of virtio-ccw and s390-ccw-virtio
support, with comments addressed and rebased against s390-next.

Cornelia Huck (2):
  s390: Add new channel I/O based virtio transport.
  s390: Add s390-ccw-virtio machine.

 hw/s390-virtio.h   |   1 +
 hw/s390x/Makefile.objs |   2 +
 hw/s390x/s390-virtio-ccw.c | 134 +++
 hw/s390x/virtio-ccw.c  | 966 +
 hw/s390x/virtio-ccw.h  |  98 +
 trace-events   |   4 +
 6 files changed, 1205 insertions(+)
 create mode 100644 hw/s390x/s390-virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.h

-- 
1.7.12.4




[Qemu-devel] [PATCH 2/2] s390: Add s390-ccw-virtio machine.

2013-01-24 Thread Cornelia Huck
Add a new machine type, s390-ccw-virtio, making use of the
virtio-ccw transport to present virtio devices as channel
devices.

Signed-off-by: Cornelia Huck 

---

v5 -> v6:
- Don't make virtio-ccw the default yet
- Adapt to ipl device changes
- Adapt to VirtioBus changes
- Default to sclp console
---
 hw/s390-virtio.h   |   1 +
 hw/s390x/Makefile.objs |   1 +
 hw/s390x/s390-virtio-ccw.c | 134 +
 3 files changed, 136 insertions(+)
 create mode 100644 hw/s390x/s390-virtio-ccw.c

diff --git a/hw/s390-virtio.h b/hw/s390-virtio.h
index 67bfd20..a6c4c19 100644
--- a/hw/s390-virtio.h
+++ b/hw/s390-virtio.h
@@ -15,6 +15,7 @@
 #define KVM_S390_VIRTIO_NOTIFY  0
 #define KVM_S390_VIRTIO_RESET   1
 #define KVM_S390_VIRTIO_SET_STATUS  2
+#define KVM_S390_VIRTIO_CCW_NOTIFY  3
 
 typedef int (*s390_virtio_fn)(const uint64_t *args);
 void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn);
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index f6b461b..9eed6d9 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -7,4 +7,5 @@ obj-y += event-facility.o
 obj-y += sclpquiesce.o sclpconsole.o
 obj-y += ipl.o
 obj-y += css.o
+obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
new file mode 100644
index 000..9575d00
--- /dev/null
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -0,0 +1,134 @@
+/*
+ * virtio ccw machine
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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 "hw/boards.h"
+#include "exec/address-spaces.h"
+#include "hw/s390-virtio.h"
+#include "hw/s390x/sclp.h"
+#include "ioinst.h"
+#include "css.h"
+#include "virtio-ccw.h"
+
+static int virtio_ccw_hcall_notify(const uint64_t *args)
+{
+uint64_t subch_id = args[0];
+uint64_t queue = args[1];
+SubchDev *sch;
+int cssid, ssid, schid, m;
+
+if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {
+return -EINVAL;
+}
+sch = css_find_subch(m, cssid, ssid, schid);
+if (!sch || !css_subch_visible(sch)) {
+return -EINVAL;
+}
+virtio_queue_notify(virtio_ccw_get_vdev(sch), queue);
+return 0;
+
+}
+
+static int virtio_ccw_hcall_early_printk(const uint64_t *args)
+{
+uint64_t mem = args[0];
+
+if (mem < ram_size) {
+/* Early printk */
+return 0;
+}
+return -EINVAL;
+}
+
+static void virtio_ccw_register_hcalls(void)
+{
+s390_register_virtio_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY,
+   virtio_ccw_hcall_notify);
+/* Tolerate early printk. */
+s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY,
+   virtio_ccw_hcall_early_printk);
+}
+
+static void ccw_init(QEMUMachineInitArgs *args)
+{
+ram_addr_t my_ram_size = args->ram_size;
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+int shift = 0;
+uint8_t *storage_keys;
+int ret;
+VirtualCssBus *css_bus;
+
+/* s390x ram size detection needs a 16bit multiplier + an increment. So
+   guests > 64GB can be specified in 2MB steps etc. */
+while ((my_ram_size >> (20 + shift)) > 65535) {
+shift++;
+}
+my_ram_size = my_ram_size >> (20 + shift) << (20 + shift);
+
+/* lets propagate the changed ram size into the global variable. */
+ram_size = my_ram_size;
+
+/* get a BUS */
+css_bus = virtual_css_bus_init();
+s390_sclp_init();
+s390_init_ipl_dev(args->kernel_filename, args->kernel_cmdline,
+  args->initrd_filename);
+
+/* register hypercalls */
+virtio_ccw_register_hcalls();
+
+/* allocate RAM */
+memory_region_init_ram(ram, "s390.ram", my_ram_size);
+vmstate_register_ram_global(ram);
+memory_region_add_subregion(sysmem, 0, ram);
+
+/* allocate storage keys */
+storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE);
+
+/* init CPUs */
+s390_init_cpus(args->cpu_model, storage_keys);
+
+if (kvm_enabled()) {
+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.
+ */
+ret = css_create_css_image(VIRTUAL_CSSID, true);
+assert(ret == 0);
+
+/* Create VirtIO network adapters */
+s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw");
+}
+
+static QEMUMachine ccw_machine = {
+.name = "s390-ccw-virtio",
+.alias = "s390-ccw",
+.desc = "VirtIO-ccw based S390 machine",

[Qemu-devel] [PATCH 1/2] s390: Add new channel I/O based virtio transport.

2013-01-24 Thread Cornelia Huck
Add a new virtio transport that uses channel commands to perform
virtio operations.

Signed-off-by: Cornelia Huck 

---

v6 -> v7:

- class reset handling
- header guard
- coding style

v5 -> v6:
- Get rid of qemu_get_ram_ptr usage
- Adapt to virtual css changes
- Constify TypeInfos
- Prepare for VirtioBus
---
 hw/s390x/Makefile.objs |   1 +
 hw/s390x/virtio-ccw.c  | 966 +
 hw/s390x/virtio-ccw.h  |  98 +
 trace-events   |   4 +
 4 files changed, 1069 insertions(+)
 create mode 100644 hw/s390x/virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.h

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index ab99da6..f6b461b 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -7,3 +7,4 @@ obj-y += event-facility.o
 obj-y += sclpquiesce.o sclpconsole.o
 obj-y += ipl.o
 obj-y += css.o
+obj-y += virtio-ccw.o
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
new file mode 100644
index 000..357c2d7
--- /dev/null
+++ b/hw/s390x/virtio-ccw.c
@@ -0,0 +1,966 @@
+/*
+ * virtio ccw target implementation
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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 "hw/hw.h"
+#include "block/block.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/sysemu.h"
+#include "net/net.h"
+#include "monitor/monitor.h"
+#include "hw/virtio.h"
+#include "hw/virtio-serial.h"
+#include "hw/virtio-net.h"
+#include "hw/sysbus.h"
+#include "qemu/bitops.h"
+#include "hw/virtio-bus.h"
+
+#include "ioinst.h"
+#include "css.h"
+#include "virtio-ccw.h"
+#include "trace.h"
+
+static int virtual_css_bus_reset(BusState *qbus)
+{
+/* This should actually be modelled via the generic css */
+css_reset();
+
+/* we dont traverse ourself, return 0 */
+return 0;
+}
+
+
+static void virtual_css_bus_class_init(ObjectClass *klass, void *data)
+{
+BusClass *k = BUS_CLASS(klass);
+
+k->reset = virtual_css_bus_reset;
+}
+
+static const TypeInfo virtual_css_bus_info = {
+.name = TYPE_VIRTUAL_CSS_BUS,
+.parent = TYPE_BUS,
+.instance_size = sizeof(VirtualCssBus),
+.class_init = virtual_css_bus_class_init,
+};
+
+static const VirtIOBindings virtio_ccw_bindings;
+
+VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
+{
+VirtIODevice *vdev = NULL;
+
+if (sch->driver_data) {
+vdev = ((VirtioCcwDevice *)sch->driver_data)->vdev;
+}
+return vdev;
+}
+
+VirtualCssBus *virtual_css_bus_init(void)
+{
+VirtualCssBus *cbus;
+BusState *bus;
+DeviceState *dev;
+
+/* Create bridge device */
+dev = qdev_create(NULL, "virtual-css-bridge");
+qdev_init_nofail(dev);
+
+/* Create bus on bridge device */
+bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
+cbus = VIRTUAL_CSS_BUS(bus);
+
+/* Enable hotplugging */
+bus->allow_hotplug = 1;
+
+return cbus;
+}
+
+/* Communication blocks used by several channel commands. */
+typedef struct VqInfoBlock {
+uint64_t queue;
+uint32_t align;
+uint16_t index;
+uint16_t num;
+} QEMU_PACKED VqInfoBlock;
+
+typedef struct VqConfigBlock {
+uint16_t index;
+uint16_t num_max;
+} QEMU_PACKED VqConfigBlock;
+
+typedef struct VirtioFeatDesc {
+uint32_t features;
+uint8_t index;
+} QEMU_PACKED VirtioFeatDesc;
+
+/* Specify where the virtqueues for the subchannel are in guest memory. */
+static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
+  uint16_t index, uint16_t num)
+{
+VirtioCcwDevice *dev = sch->driver_data;
+
+if (index > VIRTIO_PCI_QUEUE_MAX) {
+return -EINVAL;
+}
+
+/* Current code in virtio.c relies on 4K alignment. */
+if (addr && (align != 4096)) {
+return -EINVAL;
+}
+
+if (!dev) {
+return -EINVAL;
+}
+
+virtio_queue_set_addr(dev->vdev, index, addr);
+if (!addr) {
+virtio_queue_set_vector(dev->vdev, index, 0);
+} else {
+/* Fail if we don't have a big enough queue. */
+/* TODO: Add interface to handle vring.num changing */
+if (virtio_queue_get_num(dev->vdev, index) > num) {
+return -EINVAL;
+}
+virtio_queue_set_vector(dev->vdev, index, index);
+}
+/* tell notify handler in case of config change */
+dev->vdev->config_vector = VIRTIO_PCI_QUEUE_MAX;
+return 0;
+}
+
+static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+{
+int ret;
+VqInfoBlock info;
+uint8_t status;
+VirtioFeatDesc features;
+void *config;
+hwaddr indicators;
+VqConfi

[Qemu-devel] [PATCH v8 0/2] s390: virtio-ccw transport.

2013-01-24 Thread Cornelia Huck
Hi,

patches against s390-next again, with coding style fixes.

Cornelia Huck (2):
  s390: Add new channel I/O based virtio transport.
  s390: Add s390-ccw-virtio machine.

 hw/s390-virtio.h   |   1 +
 hw/s390x/Makefile.objs |   2 +
 hw/s390x/s390-virtio-ccw.c | 134 +++
 hw/s390x/virtio-ccw.c  | 960 +
 hw/s390x/virtio-ccw.h  |  98 +
 trace-events   |   4 +
 6 files changed, 1199 insertions(+)
 create mode 100644 hw/s390x/s390-virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.h

-- 
1.7.12.4




[Qemu-devel] [PATCH 2/2] s390: Add s390-ccw-virtio machine.

2013-01-24 Thread Cornelia Huck
Add a new machine type, s390-ccw-virtio, making use of the
virtio-ccw transport to present virtio devices as channel
devices.

Signed-off-by: Cornelia Huck 

---

v7 -> v8:
- Coding style

v5 -> v6:
- Don't make virtio-ccw the default yet
- Adapt to ipl device changes
- Adapt to VirtioBus changes
- Default to sclp console
---
 hw/s390-virtio.h   |   1 +
 hw/s390x/Makefile.objs |   1 +
 hw/s390x/s390-virtio-ccw.c | 134 +
 3 files changed, 136 insertions(+)
 create mode 100644 hw/s390x/s390-virtio-ccw.c

diff --git a/hw/s390-virtio.h b/hw/s390-virtio.h
index 67bfd20..a6c4c19 100644
--- a/hw/s390-virtio.h
+++ b/hw/s390-virtio.h
@@ -15,6 +15,7 @@
 #define KVM_S390_VIRTIO_NOTIFY  0
 #define KVM_S390_VIRTIO_RESET   1
 #define KVM_S390_VIRTIO_SET_STATUS  2
+#define KVM_S390_VIRTIO_CCW_NOTIFY  3
 
 typedef int (*s390_virtio_fn)(const uint64_t *args);
 void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn);
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index f6b461b..9eed6d9 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -7,4 +7,5 @@ obj-y += event-facility.o
 obj-y += sclpquiesce.o sclpconsole.o
 obj-y += ipl.o
 obj-y += css.o
+obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
new file mode 100644
index 000..f39e0f9
--- /dev/null
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -0,0 +1,134 @@
+/*
+ * virtio ccw machine
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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 "hw/boards.h"
+#include "exec/address-spaces.h"
+#include "hw/s390-virtio.h"
+#include "hw/s390x/sclp.h"
+#include "ioinst.h"
+#include "css.h"
+#include "virtio-ccw.h"
+
+static int virtio_ccw_hcall_notify(const uint64_t *args)
+{
+uint64_t subch_id = args[0];
+uint64_t queue = args[1];
+SubchDev *sch;
+int cssid, ssid, schid, m;
+
+if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {
+return -EINVAL;
+}
+sch = css_find_subch(m, cssid, ssid, schid);
+if (!sch || !css_subch_visible(sch)) {
+return -EINVAL;
+}
+virtio_queue_notify(virtio_ccw_get_vdev(sch), queue);
+return 0;
+
+}
+
+static int virtio_ccw_hcall_early_printk(const uint64_t *args)
+{
+uint64_t mem = args[0];
+
+if (mem < ram_size) {
+/* Early printk */
+return 0;
+}
+return -EINVAL;
+}
+
+static void virtio_ccw_register_hcalls(void)
+{
+s390_register_virtio_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY,
+   virtio_ccw_hcall_notify);
+/* Tolerate early printk. */
+s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY,
+   virtio_ccw_hcall_early_printk);
+}
+
+static void ccw_init(QEMUMachineInitArgs *args)
+{
+ram_addr_t my_ram_size = args->ram_size;
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+int shift = 0;
+uint8_t *storage_keys;
+int ret;
+VirtualCssBus *css_bus;
+
+/* s390x ram size detection needs a 16bit multiplier + an increment. So
+   guests > 64GB can be specified in 2MB steps etc. */
+while ((my_ram_size >> (20 + shift)) > 65535) {
+shift++;
+}
+my_ram_size = my_ram_size >> (20 + shift) << (20 + shift);
+
+/* lets propagate the changed ram size into the global variable. */
+ram_size = my_ram_size;
+
+/* get a BUS */
+css_bus = virtual_css_bus_init();
+s390_sclp_init();
+s390_init_ipl_dev(args->kernel_filename, args->kernel_cmdline,
+  args->initrd_filename);
+
+/* register hypercalls */
+virtio_ccw_register_hcalls();
+
+/* allocate RAM */
+memory_region_init_ram(ram, "s390.ram", my_ram_size);
+vmstate_register_ram_global(ram);
+memory_region_add_subregion(sysmem, 0, ram);
+
+/* allocate storage keys */
+storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE);
+
+/* init CPUs */
+s390_init_cpus(args->cpu_model, storage_keys);
+
+if (kvm_enabled()) {
+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.
+ */
+ret = css_create_css_image(VIRTUAL_CSSID, true);
+assert(ret == 0);
+
+/* Create VirtIO network adapters */
+s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw");
+}
+
+static QEMUMachine ccw_machine = {
+.name = "s390-ccw-virtio",
+.alias = "s390-ccw",
+.desc = "VirtIO-ccw ba

[Qemu-devel] [PATCH 1/2] s390: Add new channel I/O based virtio transport.

2013-01-24 Thread Cornelia Huck
Add a new virtio transport that uses channel commands to perform
virtio operations.

Signed-off-by: Cornelia Huck 

---

v7 -> v8:
- to_virtio_ccw_dev -> VIRTIO_CCW_DEVICE

v6 -> v7:

- class reset handling
- header guard
- coding style

v5 -> v6:
- Get rid of qemu_get_ram_ptr usage
- Adapt to virtual css changes
- Constify TypeInfos
- Prepare for VirtioBus
---
 hw/s390x/Makefile.objs |   1 +
 hw/s390x/virtio-ccw.c  | 960 +
 hw/s390x/virtio-ccw.h  |  98 +
 trace-events   |   4 +
 4 files changed, 1063 insertions(+)
 create mode 100644 hw/s390x/virtio-ccw.c
 create mode 100644 hw/s390x/virtio-ccw.h

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index ab99da6..f6b461b 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -7,3 +7,4 @@ obj-y += event-facility.o
 obj-y += sclpquiesce.o sclpconsole.o
 obj-y += ipl.o
 obj-y += css.o
+obj-y += virtio-ccw.o
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
new file mode 100644
index 000..8c9b745
--- /dev/null
+++ b/hw/s390x/virtio-ccw.c
@@ -0,0 +1,960 @@
+/*
+ * virtio ccw target implementation
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck 
+ *
+ * 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 "hw/hw.h"
+#include "block/block.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/sysemu.h"
+#include "net/net.h"
+#include "monitor/monitor.h"
+#include "hw/virtio.h"
+#include "hw/virtio-serial.h"
+#include "hw/virtio-net.h"
+#include "hw/sysbus.h"
+#include "qemu/bitops.h"
+#include "hw/virtio-bus.h"
+
+#include "ioinst.h"
+#include "css.h"
+#include "virtio-ccw.h"
+#include "trace.h"
+
+static int virtual_css_bus_reset(BusState *qbus)
+{
+/* This should actually be modelled via the generic css */
+css_reset();
+
+/* we dont traverse ourself, return 0 */
+return 0;
+}
+
+
+static void virtual_css_bus_class_init(ObjectClass *klass, void *data)
+{
+BusClass *k = BUS_CLASS(klass);
+
+k->reset = virtual_css_bus_reset;
+}
+
+static const TypeInfo virtual_css_bus_info = {
+.name = TYPE_VIRTUAL_CSS_BUS,
+.parent = TYPE_BUS,
+.instance_size = sizeof(VirtualCssBus),
+.class_init = virtual_css_bus_class_init,
+};
+
+static const VirtIOBindings virtio_ccw_bindings;
+
+VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
+{
+VirtIODevice *vdev = NULL;
+
+if (sch->driver_data) {
+vdev = ((VirtioCcwDevice *)sch->driver_data)->vdev;
+}
+return vdev;
+}
+
+VirtualCssBus *virtual_css_bus_init(void)
+{
+VirtualCssBus *cbus;
+BusState *bus;
+DeviceState *dev;
+
+/* Create bridge device */
+dev = qdev_create(NULL, "virtual-css-bridge");
+qdev_init_nofail(dev);
+
+/* Create bus on bridge device */
+bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
+cbus = VIRTUAL_CSS_BUS(bus);
+
+/* Enable hotplugging */
+bus->allow_hotplug = 1;
+
+return cbus;
+}
+
+/* Communication blocks used by several channel commands. */
+typedef struct VqInfoBlock {
+uint64_t queue;
+uint32_t align;
+uint16_t index;
+uint16_t num;
+} QEMU_PACKED VqInfoBlock;
+
+typedef struct VqConfigBlock {
+uint16_t index;
+uint16_t num_max;
+} QEMU_PACKED VqConfigBlock;
+
+typedef struct VirtioFeatDesc {
+uint32_t features;
+uint8_t index;
+} QEMU_PACKED VirtioFeatDesc;
+
+/* Specify where the virtqueues for the subchannel are in guest memory. */
+static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
+  uint16_t index, uint16_t num)
+{
+VirtioCcwDevice *dev = sch->driver_data;
+
+if (index > VIRTIO_PCI_QUEUE_MAX) {
+return -EINVAL;
+}
+
+/* Current code in virtio.c relies on 4K alignment. */
+if (addr && (align != 4096)) {
+return -EINVAL;
+}
+
+if (!dev) {
+return -EINVAL;
+}
+
+virtio_queue_set_addr(dev->vdev, index, addr);
+if (!addr) {
+virtio_queue_set_vector(dev->vdev, index, 0);
+} else {
+/* Fail if we don't have a big enough queue. */
+/* TODO: Add interface to handle vring.num changing */
+if (virtio_queue_get_num(dev->vdev, index) > num) {
+return -EINVAL;
+}
+virtio_queue_set_vector(dev->vdev, index, index);
+}
+/* tell notify handler in case of config change */
+dev->vdev->config_vector = VIRTIO_PCI_QUEUE_MAX;
+return 0;
+}
+
+static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+{
+int ret;
+VqInfoBlock info;
+uint8_t status;
+VirtioFeatDesc features;
+void *config;
+hw

Re: [Qemu-devel] [PATCH v8 0/2] s390: virtio-ccw transport.

2013-01-25 Thread Cornelia Huck
On Thu, 24 Jan 2013 17:17:46 +0100
Alexander Graf  wrote:

> 
> On 24.01.2013, at 17:08, Cornelia Huck wrote:
> 
> > Hi,
> > 
> > patches against s390-next again, with coding style fixes.
> 
> Thanks, applied to s390-next.

Hm, did you forget to apply 2/2?

> 
> 
> Alex
> 




Re: [Qemu-devel] [PATCH 06/15] s390: Add channel I/O instructions.

2013-01-28 Thread Cornelia Huck
On Fri, 25 Jan 2013 20:28:31 +0100
Alexander Graf  wrote:

> However, I do agree that this duplicates logic. Cornelia, mind to instead 
> call our map helper in css_do_tpi?

Well, ioinst_handle_tpi() looks like the better place to do this.

Can you put this into the series, or should I re-send?

From a8064d80759e30662b0ac41643a29b41e9015a3f Mon Sep 17 00:00:00 2001
From: Cornelia Huck 
Date: Mon, 28 Jan 2013 10:42:44 +0100
Subject: [PATCH] s390: Use s390_cpu_physical_memory_map for tpi.

Map the I/O interruption code before calling into css.

Signed-off-by: Cornelia Huck 
---
 hw/s390x/css.c|  2 +-
 target-s390x/cpu.h|  4 ++--
 target-s390x/ioinst.c | 19 ++-
 target-s390x/ioinst.h |  7 +++
 4 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 113ac9a..84efd4a 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -852,7 +852,7 @@ int css_do_stcrw(CRW *crw)
 return ret;
 }
 
-int css_do_tpi(uint64_t addr, int lowcore)
+int css_do_tpi(IOIntCode *int_code, int lowcore)
 {
 /* No pending interrupts for !KVM. */
 return 0;
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index ce12fa4..9be4a47 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -413,7 +413,7 @@ int css_do_hsch(SubchDev *sch);
 int css_do_ssch(SubchDev *sch, ORB *orb);
 int css_do_tsch(SubchDev *sch, IRB *irb);
 int css_do_stcrw(CRW *crw);
-int css_do_tpi(uint64_t addr, int lowcore);
+int css_do_tpi(IOIntCode *int_code, int lowcore);
 int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t 
l_chpid,
  int rfmt, void *buf);
 void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo);
@@ -471,7 +471,7 @@ static inline int css_do_stcrw(CRW *crw)
 {
 return 1;
 }
-static inline int css_do_tpi(uint64_t addr, int lowcore)
+static inline int css_do_tpi(IOIntCode *int_code, int lowcore)
 {
 return 0;
 }
diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
index 4ef2d73..e3531f3 100644
--- a/target-s390x/ioinst.c
+++ b/target-s390x/ioinst.c
@@ -619,16 +619,25 @@ int ioinst_handle_tpi(CPUS390XState *env, uint32_t ipb)
 {
 uint64_t addr;
 int lowcore;
+IOIntCode *int_code;
+hwaddr len, orig_len;
+int ret;
 
 trace_ioinst("tpi");
 addr = decode_basedisp_s(env, ipb);
 lowcore = addr ? 0 : 1;
-if (addr < 8192) {
-addr += env->psa;
-} else if ((env->psa <= addr) && (addr < env->psa + 8192)) {
-addr -= env->psa;
+len = lowcore ? 8 /* two words */ : 12 /* three words */;
+orig_len = len;
+int_code = s390_cpu_physical_memory_map(env, addr, &len, 1);
+if (!int_code || (len != orig_len)) {
+program_interrupt(env, PGM_SPECIFICATION, 2);
+ret = -EIO;
+goto out;
 }
-return css_do_tpi(addr, lowcore);
+ret = css_do_tpi(int_code, lowcore);
+out:
+s390_cpu_physical_memory_unmap(env, int_code, len, 1);
+return ret;
 }
 
 #define SCHM_REG1_RES(_reg) (_reg & 0x0ffc)
diff --git a/target-s390x/ioinst.h b/target-s390x/ioinst.h
index a59742c..d5a43f4 100644
--- a/target-s390x/ioinst.h
+++ b/target-s390x/ioinst.h
@@ -195,6 +195,13 @@ typedef struct CRW {
 #define CRW_RSC_SUBCH 0x3
 #define CRW_RSC_CHP   0x4
 
+/* I/O interruption code */
+typedef struct IOIntCode {
+uint32_t subsys_id;
+uint32_t intparm;
+uint32_t interrupt_id;
+} QEMU_PACKED IOIntCode;
+
 /* schid disintegration */
 #define IOINST_SCHID_ONE(_schid)   ((_schid & 0x0001) >> 16)
 #define IOINST_SCHID_M(_schid) ((_schid & 0x0008) >> 19)
-- 
1.7.12.4




Re: [Qemu-devel] [PULL 00/15] s390 patch queue 2013-01-25

2013-01-28 Thread Cornelia Huck
On Sat, 26 Jan 2013 14:17:36 +
Blue Swirl  wrote:

> On Fri, Jan 25, 2013 at 12:48 PM, Alexander Graf  wrote:
> > Hi Blue / Aurelien,
> >
> > This is my current patch queue for s390.  Please pull.
> >
> > Alex
> >
> >
> > The following changes since commit 11c29918be32be5b00f367c7da9724a5cddbbb0f:
> >   Anthony Liguori (1):
> > Merge remote-tracking branch 'bonzini/scsi-next' into staging
> >
> > are available in the git repository at:
> >
> >   git://repo.or.cz/qemu/agraf.git s390-for-upstream
> >
> > Alexander Graf (3):
> >   s390: Add default support for SCLP console
> >   s390: Make typeinfo const
> >   s390: Move hw files to hw/s390x
> >
> > Andreas Färber (1):
> >   s390-virtio: Check for NULL device in reset hypercall
> >
> > Cornelia Huck (10):
> >   s390: Lowcore mapping helper.
> >   s390: Add mapping helper functions.
> >   s390: Channel I/O basic definitions.
> >   s390: I/O interrupt and machine check injection.
> >   s390: Add channel I/O instructions.
> >   s390: Virtual channel subsystem support.
> 
> This would break build on mingw32:
>   CCs390x-softmmu/hw/s390x/css.o
> /src/qemu/hw/s390x/css.c: In function 'css_interpret_ccw':
> /src/qemu/hw/s390x/css.c:226:17: error: 'ERESTART' undeclared (first
> use in this function)
> /src/qemu/hw/s390x/css.c:226:17: note: each undeclared identifier is
> reported only once for each function it appears in
> /src/qemu/hw/s390x/css.c:294:20: error: 'EOPNOTSUPP' undeclared (first
> use in this function)
> /src/qemu/hw/s390x/css.c: In function 'sch_handle_start_func':
> /src/qemu/hw/s390x/css.c:350:15: error: 'EOPNOTSUPP' undeclared (first
> use in this function)
> /src/qemu/hw/s390x/css.c:375:15: error: 'ERESTART' undeclared (first
> use in this function)

That's unfortunate :(

Are there some kinds of compatibility headers that define the missing
error codes, or does something need to be fenced off here?

I would appreciate it if somebody could give me a hand here, especially
as I don't have a mingw32 environment around...

> 
> >   s390: Wire up channel I/O in kvm.
> >   s390-virtio: Factor out some initialization code.
> >   s390: Add new channel I/O based virtio transport.
> >   s390: Add s390-ccw-virtio machine.
> >
> > Paolo Bonzini (1):
> >   virtio-s390: add a reset function to virtio-s390 devices
> >
> >  hw/boards.h  |1 +
> >  hw/s390-virtio.h |   22 -
> >  hw/s390x/Makefile.objs   |5 +-
> >  hw/s390x/css.c   | 1277 
> > ++
> >  hw/s390x/css.h   |   99 +++
> >  hw/s390x/ipl.c   |2 +-
> >  hw/{ => s390x}/s390-virtio-bus.c |   16 +-
> >  hw/{ => s390x}/s390-virtio-bus.h |   12 +-
> >  hw/s390x/s390-virtio-ccw.c   |  134 
> >  hw/s390x/s390-virtio-hcall.c |2 +-
> >  hw/{ => s390x}/s390-virtio.c |  131 +++--
> >  hw/s390x/s390-virtio.h   |   28 +
> >  hw/s390x/virtio-ccw.c|  960 
> >  hw/s390x/virtio-ccw.h|   98 +++
> >  target-s390x/Makefile.objs   |2 +-
> >  target-s390x/cpu.h   |  247 -
> >  target-s390x/helper.c|  200 ++-
> >  target-s390x/ioinst.c|  752 ++
> >  target-s390x/ioinst.h|  223 +++
> >  target-s390x/kvm.c   |  239 +++-
> >  trace-events |   18 +
> >  vl.c |   51 ++
> >  22 files changed, 4403 insertions(+), 116 deletions(-)
> >  delete mode 100644 hw/s390-virtio.h
> >  create mode 100644 hw/s390x/css.c
> >  create mode 100644 hw/s390x/css.h
> >  rename hw/{ => s390x}/s390-virtio-bus.c (98%)
> >  rename hw/{ => s390x}/s390-virtio-bus.h (95%)
> >  create mode 100644 hw/s390x/s390-virtio-ccw.c
> >  rename hw/{ => s390x}/s390-virtio.c (85%)
> >  create mode 100644 hw/s390x/s390-virtio.h
> >  create mode 100644 hw/s390x/virtio-ccw.c
> >  create mode 100644 hw/s390x/virtio-ccw.h
> >  create mode 100644 target-s390x/ioinst.c
> >  create mode 100644 target-s390x/ioinst.h
> 




Re: [Qemu-devel] [PULL 00/15] s390 patch queue 2013-01-25

2013-01-28 Thread Cornelia Huck
On Sat, 26 Jan 2013 14:17:36 +
Blue Swirl  wrote:

> On Fri, Jan 25, 2013 at 12:48 PM, Alexander Graf  wrote:
> > Hi Blue / Aurelien,
> >
> > This is my current patch queue for s390.  Please pull.
> >
> > Alex
> >
> >
> > The following changes since commit 11c29918be32be5b00f367c7da9724a5cddbbb0f:
> >   Anthony Liguori (1):
> > Merge remote-tracking branch 'bonzini/scsi-next' into staging
> >
> > are available in the git repository at:
> >
> >   git://repo.or.cz/qemu/agraf.git s390-for-upstream
> >
> > Alexander Graf (3):
> >   s390: Add default support for SCLP console
> >   s390: Make typeinfo const
> >   s390: Move hw files to hw/s390x
> >
> > Andreas Färber (1):
> >   s390-virtio: Check for NULL device in reset hypercall
> >
> > Cornelia Huck (10):
> >   s390: Lowcore mapping helper.
> >   s390: Add mapping helper functions.
> >   s390: Channel I/O basic definitions.
> >   s390: I/O interrupt and machine check injection.
> >   s390: Add channel I/O instructions.
> >   s390: Virtual channel subsystem support.
> 
> This would break build on mingw32:
>   CCs390x-softmmu/hw/s390x/css.o
> /src/qemu/hw/s390x/css.c: In function 'css_interpret_ccw':
> /src/qemu/hw/s390x/css.c:226:17: error: 'ERESTART' undeclared (first
> use in this function)
> /src/qemu/hw/s390x/css.c:226:17: note: each undeclared identifier is
> reported only once for each function it appears in
> /src/qemu/hw/s390x/css.c:294:20: error: 'EOPNOTSUPP' undeclared (first
> use in this function)
> /src/qemu/hw/s390x/css.c: In function 'sch_handle_start_func':
> /src/qemu/hw/s390x/css.c:350:15: error: 'EOPNOTSUPP' undeclared (first
> use in this function)
> /src/qemu/hw/s390x/css.c:375:15: error: 'ERESTART' undeclared (first
> use in this function)

The following patch might help for now, as those error codes already
seem to be used in generic code.

From a32da08a8474aa6fde65d7bc1616b42dce9d7252 Mon Sep 17 00:00:00 2001
From: Cornelia Huck 
Date: Mon, 28 Jan 2013 17:01:30 +0100
Subject: [PATCH] s390: css error codes.

Changed error codes in the channel subsystem / virtio-ccw code
(-EOPNOTSUPP -> -ENOSYS, -ERESTART -> -EINPROGRESS).

This should hopefully fix building on mingw32.

Signed-off-by: Cornelia Huck 
---
 hw/s390x/css.c|8 
 hw/s390x/virtio-ccw.c |2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 84efd4a..3244201 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -223,7 +223,7 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr)
 }
 
 if (ccw.flags & CCW_FLAG_SUSPEND) {
-return -ERESTART;
+return -EINPROGRESS;
 }
 
 check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));
@@ -291,7 +291,7 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr)
 /* Handle device specific commands. */
 ret = sch->ccw_cb(sch, ccw);
 } else {
-ret = -EOPNOTSUPP;
+ret = -ENOSYS;
 }
 break;
 }
@@ -347,7 +347,7 @@ static void sch_handle_start_func(SubchDev *sch)
 SCSW_STCTL_STATUS_PEND;
 s->dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END;
 break;
-case -EOPNOTSUPP:
+case -ENOSYS:
 /* unsupported command, generate unit check (command reject) */
 s->ctrl &= ~SCSW_ACTL_START_PEND;
 s->dstat = SCSW_DSTAT_UNIT_CHECK;
@@ -372,7 +372,7 @@ static void sch_handle_start_func(SubchDev *sch)
 s->ctrl &= ~SCSW_CTRL_MASK_STCTL;
 s->ctrl |= SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
 break;
-case -ERESTART:
+case -EINPROGRESS:
 /* channel program has been suspended */
 s->ctrl &= ~SCSW_ACTL_START_PEND;
 s->ctrl |= SCSW_ACTL_SUSP;
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 8c9b745..7d7f336 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -384,7 +384,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
 }
 break;
 default:
-ret = -EOPNOTSUPP;
+ret = -ENOSYS;
 break;
 }
 return ret;
-- 
1.7.6.2




Re: [Qemu-devel] [PULL 00/15] s390 patch queue 2013-01-25

2013-01-28 Thread Cornelia Huck
On Mon, 28 Jan 2013 18:08:10 +0100
Stefan Weil  wrote:

> Am 28.01.2013 17:06, schrieb Cornelia Huck:
> > On Sat, 26 Jan 2013 14:17:36 +
> > Blue Swirl  wrote:
> >
> >> On Fri, Jan 25, 2013 at 12:48 PM, Alexander Graf  wrote:
> >>> Hi Blue / Aurelien,
> >>>
> >>> This is my current patch queue for s390.  Please pull.
> >>>
> >>> Alex
> >>>
> >>>
> >>> The following changes since commit 
> >>> 11c29918be32be5b00f367c7da9724a5cddbbb0f:
> >>>   Anthony Liguori (1):
> >>> Merge remote-tracking branch 'bonzini/scsi-next' into staging
> >>>
> >>> are available in the git repository at:
> >>>
> >>>   git://repo.or.cz/qemu/agraf.git s390-for-upstream
> >>>
> >>> Alexander Graf (3):
> >>>   s390: Add default support for SCLP console
> >>>   s390: Make typeinfo const
> >>>   s390: Move hw files to hw/s390x
> >>>
> >>> Andreas Färber (1):
> >>>   s390-virtio: Check for NULL device in reset hypercall
> >>>
> >>> Cornelia Huck (10):
> >>>   s390: Lowcore mapping helper.
> >>>   s390: Add mapping helper functions.
> >>>   s390: Channel I/O basic definitions.
> >>>   s390: I/O interrupt and machine check injection.
> >>>   s390: Add channel I/O instructions.
> >>>   s390: Virtual channel subsystem support.
> >> This would break build on mingw32:
> >>   CCs390x-softmmu/hw/s390x/css.o
> >> /src/qemu/hw/s390x/css.c: In function 'css_interpret_ccw':
> >> /src/qemu/hw/s390x/css.c:226:17: error: 'ERESTART' undeclared (first
> >> use in this function)
> >> /src/qemu/hw/s390x/css.c:226:17: note: each undeclared identifier is
> >> reported only once for each function it appears in
> >> /src/qemu/hw/s390x/css.c:294:20: error: 'EOPNOTSUPP' undeclared (first
> >> use in this function)
> >> /src/qemu/hw/s390x/css.c: In function 'sch_handle_start_func':
> >> /src/qemu/hw/s390x/css.c:350:15: error: 'EOPNOTSUPP' undeclared (first
> >> use in this function)
> >> /src/qemu/hw/s390x/css.c:375:15: error: 'ERESTART' undeclared (first
> >> use in this function)
> > The following patch might help for now, as those error codes already
> > seem to be used in generic code.
> >
> > From a32da08a8474aa6fde65d7bc1616b42dce9d7252 Mon Sep 17 00:00:00 2001
> > From: Cornelia Huck 
> > Date: Mon, 28 Jan 2013 17:01:30 +0100
> > Subject: [PATCH] s390: css error codes.
> >
> > Changed error codes in the channel subsystem / virtio-ccw code
> > (-EOPNOTSUPP -> -ENOSYS, -ERESTART -> -EINPROGRESS).
> >
> > This should hopefully fix building on mingw32.
> >
> > Signed-off-by: Cornelia Huck 
> > ---
> >  hw/s390x/css.c|8 
> >  hw/s390x/virtio-ccw.c |2 +-
> >  2 files changed, 5 insertions(+), 5 deletions(-)
> >
> > diff --git a/hw/s390x/css.c b/hw/s390x/css.c
> > index 84efd4a..3244201 100644
> > --- a/hw/s390x/css.c
> > +++ b/hw/s390x/css.c
> > @@ -223,7 +223,7 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr 
> > ccw_addr)
> >  }
> >  
> >  if (ccw.flags & CCW_FLAG_SUSPEND) {
> > -return -ERESTART;
> > +return -EINPROGRESS;
> >  }
> >  
> >  check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & 
> > CCW_FLAG_DC));
> > @@ -291,7 +291,7 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr 
> > ccw_addr)
> >  /* Handle device specific commands. */
> >  ret = sch->ccw_cb(sch, ccw);
> >  } else {
> > -ret = -EOPNOTSUPP;
> > +ret = -ENOSYS;
> >  }
> >  break;
> >  }
> > @@ -347,7 +347,7 @@ static void sch_handle_start_func(SubchDev *sch)
> >  SCSW_STCTL_STATUS_PEND;
> >  s->dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END;
> >  break;
> > -case -EOPNOTSUPP:
> > +case -ENOSYS:
> >  /* unsupported command, generate unit check (command reject) */
> >  s->ctrl &= ~SCSW_ACTL_START_PEND;
> >  s->dstat = SCSW_DSTAT_UNIT_CHECK;
> > @@ -372,7 +372,7 @@ static void sch_handle_start_func(SubchDev *sch)
> >  s->ct

Re: [Qemu-devel] [PATCH 06/15] s390: Add channel I/O instructions.

2013-01-29 Thread Cornelia Huck
On Tue, 29 Jan 2013 16:09:38 +0100
Alexander Graf  wrote:

> On 01/28/2013 10:59 AM, Cornelia Huck wrote:
> > On Fri, 25 Jan 2013 20:28:31 +0100
> > Alexander Graf  wrote:
> >
> >> However, I do agree that this duplicates logic. Cornelia, mind to instead 
> >> call our map helper in css_do_tpi?
> > Well, ioinst_handle_tpi() looks like the better place to do this.
> >
> > Can you put this into the series, or should I re-send?
> 
> It still breaks for 32-bit targets. Could you please replace the set_bit 
> call by normal bit shift operations?
> 

Here you are:

From f85a2507c4c5887e308dcd7dfcfebc386d802ea5 Mon Sep 17 00:00:00 2001
From: Cornelia Huck 
Date: Tue, 29 Jan 2013 16:33:04 +0100
Subject: [PATCH] s390: Drop set_bit usage in virtio_ccw.

set_bit on indicators doesn't go well on 32 bit targets:

note: expected 'long unsigned int *' but argument is of type 'uint64_t *'

Switch to bit shifts instead.

Signed-off-by: Cornelia Huck 
---
 hw/s390x/virtio-ccw.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 7d7f336..77e8f32 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -662,12 +662,12 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t 
vector)
 
 if (vector < VIRTIO_PCI_QUEUE_MAX) {
 indicators = ldq_phys(dev->indicators);
-set_bit(vector, &indicators);
+indicators |= 1 << vector;
 stq_phys(dev->indicators, indicators);
 } else {
 vector = 0;
 indicators = ldq_phys(dev->indicators2);
-set_bit(vector, &indicators);
+indicators |= 1 << vector;
 stq_phys(dev->indicators2, indicators);
 }
 
-- 
1.7.6.2




Re: [Qemu-devel] [PATCH for-1.4 0/2] target-s390x: CPU cleanups preparing for 1.5

2013-01-31 Thread Cornelia Huck
On Wed, 30 Jan 2013 23:48:23 +0100
Andreas Färber  wrote:

> Hi Alex,
> 
> Here's a cleanup of all of cpu_inject_*(), as requested by Cornelia, plus
> another API preparation for my CPUState part 8 series, to go along with my
> debug output bug fixes.
> 
> As a reminder here's a link to one of my original discussions of the new 
> types:
> https://lists.nongnu.org/archive/html/qemu-devel/2012-05/msg01286.html
> 
> That is, for any non-TCG functions (TCG does not support CPUState yet) an
> S390CPU argument should be preferred over CPUS390XState since it allows cheap
> access to its own fields, CPUState's via CPU() and to CPUS390XState via ->env.
> Doing this consistently avoids costs of casting back and forth unnecessarily.
> 
> s390 code should use s390_env_get_cpu() where needed, not ENV_GET_CPU().
> 
> As a rule of thumb, any field in include/exec/cpu-defs.h:CPU_COMMON can be
> expected to end up in CPUState (or accessible from there) sooner or later.
> Per-target functions can be expected to change to CPUState soon.
> 
> New fields that do not need to be accessed via TCGv or from a hot TCG helper
> function should be added to S390CPU, not to CPUS390XState.
> 
> Regards,
> Andreas
> 
> Cc: Alexander Graf 
> Cc: Cornelia Huck 
> Cc: Christian Borntraeger 
> 
> Andreas Färber (2):
>   target-s390x: Clean up cpu_inject_*() signatures
>   target-s390x: Pass S390CPU to s390_{add,del}_running_cpu()
> 
>  hw/s390x/ipl.c |6 --
>  hw/s390x/s390-virtio-bus.c |4 +---
>  hw/s390x/s390-virtio.c |8 ++--
>  target-s390x/cpu.c |2 +-
>  target-s390x/cpu.h |   23 ++-
>  target-s390x/helper.c  |   11 +++
>  target-s390x/interrupt.c   |2 +-
>  target-s390x/kvm.c     |   13 +
>  8 Dateien geändert, 39 Zeilen hinzugefügt(+), 30 Zeilen entfernt(-)
> 

Looks sane and works for me.

Acked-by: Cornelia Huck 




Re: [Qemu-devel] [PATCH for 1.4] target-s390x: Fix wrong comparison in interrupt handling

2013-02-04 Thread Cornelia Huck
On Sun,  3 Feb 2013 21:33:16 +0100
Stefan Weil  wrote:

> gcc with -Wextra complains about an ordered pointer comparison:
> 
> target-s390x/helper.c:660:27: warning:
>  ordered comparison of pointer with integer zero [-Wextra]
> 
> Obviously the index was missing in the code.
> 
> Signed-off-by: Stefan Weil 
> ---
> 
> I hope my analysis and the fix is correct - please review.
> 
> For local builds, I always compile with -Wextra. This bug shows that -Wextra
> would be good as a default compiler option for QEMU. Of course some extra
> warnings must be explicitly disabled then. I'll send a patch for this after 
> 1.4.
> 
> Regards,
> 
> Stefan W.
> 
> 
>  target-s390x/helper.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target-s390x/helper.c b/target-s390x/helper.c
> index 3180b90..8bd84ef 100644
> --- a/target-s390x/helper.c
> +++ b/target-s390x/helper.c
> @@ -657,7 +657,7 @@ static void do_io_interrupt(CPUS390XState *env)
>  cpu_unmap_lowcore(lowcore);
> 
>  env->io_index[isc]--;
> -if (env->io_index >= 0) {
> +if (env->io_index[isc] >= 0) {
>  disable = 0;
>  }
>  break;

Oops, obvious bug when you look at it :)

Acked-by: Cornelia Huck 




Re: [Qemu-devel] [PATCH] s390x: silence warning from GCC on uninitialized values

2013-02-05 Thread Cornelia Huck
On Mon, 04 Feb 2013 22:57:43 +0100
Stefan Weil  wrote:

> Am 04.02.2013 22:23, schrieb Anthony Liguori:
> > As best I can tell, this is a false positive.
> >
> >   [aliguori@ccnode4 qemu-s390]$ make
> > CCs390x-softmmu/target-s390x/helper.o
> >   /home/aliguori/git/qemu/target-s390x/helper.c: In function ‘do_interrupt’:
> >   /home/aliguori/git/qemu/target-s390x/helper.c:673:17: error: ‘addr’ may 
> > be used uninitialized in this function [-Werror=maybe-uninitialized]
> >   /home/aliguori/git/qemu/target-s390x/helper.c:620:20: note: ‘addr’ was 
> > declared here
> >   /home/aliguori/git/qemu/target-s390x/helper.c:673:17: error: ‘mask’ may 
> > be used uninitialized in this function [-Werror=maybe-uninitialized]
> >   /home/aliguori/git/qemu/target-s390x/helper.c:620:14: note: ‘mask’ was 
> > declared here
> >   cc1: all warnings being treated as errors
> >   make[1]: *** [target-s390x/helper.o] Error 1
> >   make: *** [subdir-s390x-softmmu] Error 2
> >
> 
> Yes, this is a false positive. A better compiler will complain when your
> patch was applied because addr, mask are assigned values which are
> never used...
> 
> Would it be possible to completely eliminate variable "found" and
> move the DPRINTF, load_psw statements into the for loop (just before
> the break statement)?

We could move the lpsw. However, this made me notice another problem:
We stop scanning subsequent iscs if we found an interrupt to inject...

This is not a problem for current virtio-ccw based Linux guests since
they never use anything else than isc 3, but we'll probably want the
following patch.

From 8b2f40e8eaac16b55a72ab1e36a4c5de0b016495 Mon Sep 17 00:00:00 2001
From: Cornelia Huck 
Date: Tue, 5 Feb 2013 10:14:49 +0100
Subject: [PATCH] s390: Keep I/O interrupts enabled for all iscs.

do_io_interrupt() would stop scanning further iscs if it found
an I/O interrupt it could inject. This might cause the pending
interrupt indication for I/O interrupts to be reset although there
might be queued I/O interrupts for subsequent iscs.

Fix this by reordering the logic: Inject the I/O interrupt immediately
and continue searching all iscs for queued interrupts.

Signed-off-by: Cornelia Huck 
---
 target-s390x/helper.c | 40 +---
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 043feb2..9f9088b 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -617,7 +617,6 @@ static void do_ext_interrupt(CPUS390XState *env)
 
 static void do_io_interrupt(CPUS390XState *env)
 {
-uint64_t mask = 0, addr = 0;
 LowCore *lowcore;
 IOIntQueue *q;
 uint8_t isc;
@@ -642,36 +641,39 @@ static void do_io_interrupt(CPUS390XState *env)
 disable = 0;
 continue;
 }
-found = 1;
-lowcore = cpu_map_lowcore(env);
+if (!found) {
+uint64_t mask, addr;
 
-lowcore->subchannel_id = cpu_to_be16(q->id);
-lowcore->subchannel_nr = cpu_to_be16(q->nr);
-lowcore->io_int_parm = cpu_to_be32(q->parm);
-lowcore->io_int_word = cpu_to_be32(q->word);
-lowcore->io_old_psw.mask = cpu_to_be64(get_psw_mask(env));
-lowcore->io_old_psw.addr = cpu_to_be64(env->psw.addr);
-mask = be64_to_cpu(lowcore->io_new_psw.mask);
-addr = be64_to_cpu(lowcore->io_new_psw.addr);
+found = 1;
+lowcore = cpu_map_lowcore(env);
 
-cpu_unmap_lowcore(lowcore);
+lowcore->subchannel_id = cpu_to_be16(q->id);
+lowcore->subchannel_nr = cpu_to_be16(q->nr);
+lowcore->io_int_parm = cpu_to_be32(q->parm);
+lowcore->io_int_word = cpu_to_be32(q->word);
+lowcore->io_old_psw.mask = cpu_to_be64(get_psw_mask(env));
+lowcore->io_old_psw.addr = cpu_to_be64(env->psw.addr);
+mask = be64_to_cpu(lowcore->io_new_psw.mask);
+addr = be64_to_cpu(lowcore->io_new_psw.addr);
 
-env->io_index[isc]--;
+cpu_unmap_lowcore(lowcore);
+
+env->io_index[isc]--;
+
+DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __func__,
+env->psw.mask, env->psw.addr);
+load_psw(env, mask, addr);
+}
 if (env->io_index[isc] >= 0) {
 disable = 0;
 }
-break;
+continue;
 }
 
 if (disable) {
 env->pending_int &= ~INTERRUPT_IO;
 }
 
-if (found) {
-DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __func__,
-env->psw.mask, env->psw.addr);
-load_psw(env, mask, addr);
-}
 }
 
 static void do_mchk_interrupt(CPUS390XState *env)
-- 
1.7.12.4




Re: [Qemu-devel] [PATCH] s390x: silence warning from GCC on uninitialized values

2013-02-07 Thread Cornelia Huck
On Tue, 5 Feb 2013 10:27:00 +0100
Cornelia Huck  wrote:

> On Mon, 04 Feb 2013 22:57:43 +0100
> Stefan Weil  wrote:
> 
> > Am 04.02.2013 22:23, schrieb Anthony Liguori:
> > > As best I can tell, this is a false positive.
> > >
> > >   [aliguori@ccnode4 qemu-s390]$ make
> > > CCs390x-softmmu/target-s390x/helper.o
> > >   /home/aliguori/git/qemu/target-s390x/helper.c: In function 
> > > ‘do_interrupt’:
> > >   /home/aliguori/git/qemu/target-s390x/helper.c:673:17: error: ‘addr’ may 
> > > be used uninitialized in this function [-Werror=maybe-uninitialized]
> > >   /home/aliguori/git/qemu/target-s390x/helper.c:620:20: note: ‘addr’ was 
> > > declared here
> > >   /home/aliguori/git/qemu/target-s390x/helper.c:673:17: error: ‘mask’ may 
> > > be used uninitialized in this function [-Werror=maybe-uninitialized]
> > >   /home/aliguori/git/qemu/target-s390x/helper.c:620:14: note: ‘mask’ was 
> > > declared here
> > >   cc1: all warnings being treated as errors
> > >   make[1]: *** [target-s390x/helper.o] Error 1
> > >   make: *** [subdir-s390x-softmmu] Error 2
> > >
> > 
> > Yes, this is a false positive. A better compiler will complain when your
> > patch was applied because addr, mask are assigned values which are
> > never used...
> > 
> > Would it be possible to completely eliminate variable "found" and
> > move the DPRINTF, load_psw statements into the for loop (just before
> > the break statement)?
> 
> We could move the lpsw. However, this made me notice another problem:
> We stop scanning subsequent iscs if we found an interrupt to inject...
> 
> This is not a problem for current virtio-ccw based Linux guests since
> they never use anything else than isc 3, but we'll probably want the
> following patch.
> 
> From 8b2f40e8eaac16b55a72ab1e36a4c5de0b016495 Mon Sep 17 00:00:00 2001
> From: Cornelia Huck 
> Date: Tue, 5 Feb 2013 10:14:49 +0100
> Subject: [PATCH] s390: Keep I/O interrupts enabled for all iscs.
> 
> do_io_interrupt() would stop scanning further iscs if it found
> an I/O interrupt it could inject. This might cause the pending
> interrupt indication for I/O interrupts to be reset although there
> might be queued I/O interrupts for subsequent iscs.
> 
> Fix this by reordering the logic: Inject the I/O interrupt immediately
> and continue searching all iscs for queued interrupts.
> 
> Signed-off-by: Cornelia Huck 

Any opinions on this? I have another fix touching this code and I'd
like to base that patch on top of this one.

> ---
>  target-s390x/helper.c | 40 +---
>  1 file changed, 21 insertions(+), 19 deletions(-)
> 
> diff --git a/target-s390x/helper.c b/target-s390x/helper.c
> index 043feb2..9f9088b 100644
> --- a/target-s390x/helper.c
> +++ b/target-s390x/helper.c
> @@ -617,7 +617,6 @@ static void do_ext_interrupt(CPUS390XState *env)
>  
>  static void do_io_interrupt(CPUS390XState *env)
>  {
> -uint64_t mask = 0, addr = 0;
>  LowCore *lowcore;
>  IOIntQueue *q;
>  uint8_t isc;
> @@ -642,36 +641,39 @@ static void do_io_interrupt(CPUS390XState *env)
>  disable = 0;
>  continue;
>  }
> -found = 1;
> -lowcore = cpu_map_lowcore(env);
> +if (!found) {
> +uint64_t mask, addr;
>  
> -lowcore->subchannel_id = cpu_to_be16(q->id);
> -lowcore->subchannel_nr = cpu_to_be16(q->nr);
> -lowcore->io_int_parm = cpu_to_be32(q->parm);
> -lowcore->io_int_word = cpu_to_be32(q->word);
> -lowcore->io_old_psw.mask = cpu_to_be64(get_psw_mask(env));
> -lowcore->io_old_psw.addr = cpu_to_be64(env->psw.addr);
> -mask = be64_to_cpu(lowcore->io_new_psw.mask);
> -addr = be64_to_cpu(lowcore->io_new_psw.addr);
> +found = 1;
> +lowcore = cpu_map_lowcore(env);
>  
> -cpu_unmap_lowcore(lowcore);
> +lowcore->subchannel_id = cpu_to_be16(q->id);
> +lowcore->subchannel_nr = cpu_to_be16(q->nr);
> +lowcore->io_int_parm = cpu_to_be32(q->parm);
> +lowcore->io_int_word = cpu_to_be32(q->word);
> +lowcore->io_old_psw.mask = cpu_to_be64(get_psw_mask(env));
> +lowcore->io_old_psw.addr = cpu_to_be64(env->psw.addr);
> +mask = be64_to_cpu(lowcore->io_new_psw.mask);
> +addr = be64_to_cpu(lowcore->io_new_psw.addr);
>  
> -env->io_index[isc]--;
> +cpu_unmap_lowcore(lowcore);
> +
> + 

[Qemu-devel] [PATCH for-1.4 0/2] s390: I/O interrupt fixes.

2013-02-07 Thread Cornelia Huck
Hi,

here are two fixes for the new s390 I/O interrupt code that I'd really
want to have in 1.4.

The first patch has already been sent (see
http://marc.info/?l=qemu-devel&m=136005644027411&w=2).

The second one fixes a thinko in the isc handling code.

Patches are against master, as s390-next is missing patches that are
already in master.

Please apply.

Cornelia Huck (2):
  s390: Keep I/O interrupts enabled for all iscs.
  s390: Fix handling of iscs.

 hw/s390x/css.c|  4 ++--
 target-s390x/cpu.h|  2 +-
 target-s390x/helper.c | 45 +
 target-s390x/ioinst.h |  3 +++
 4 files changed, 31 insertions(+), 23 deletions(-)

-- 
1.7.12.4




[Qemu-devel] [PATCH 2/2] s390: Fix handling of iscs.

2013-02-07 Thread Cornelia Huck
There are two ways to express an interruption subclass:
- As a bitmask, as used in cr6.
- As a number, as used in the I/O interruption word.

Unfortunately, we have treated to I/O interruption word as if it
contained the bitmask as well, which went unnoticed so far as
- (queued-for-next) kvm made the same mistake, and
- Linux guest kernels don't check the isc value in the I/O interruption
  word for subchannel interrupts.

Make sure that we treat the I/O interruption word correctly.

Signed-off-by: Cornelia Huck 
---
 hw/s390x/css.c| 4 ++--
 target-s390x/cpu.h| 2 +-
 target-s390x/helper.c | 5 -
 target-s390x/ioinst.h | 3 +++
 4 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 3244201..85f6f22 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -87,7 +87,7 @@ static void css_inject_io_interrupt(SubchDev *sch)
   css_build_subchannel_id(sch),
   sch->schid,
   sch->curr_status.pmcw.intparm,
-  (0x80 >> isc) << 24);
+  isc << 27);
 }
 
 void css_conditional_io_interrupt(SubchDev *sch)
@@ -111,7 +111,7 @@ void css_conditional_io_interrupt(SubchDev *sch)
   css_build_subchannel_id(sch),
   sch->schid,
   sch->curr_status.pmcw.intparm,
-  (0x80 >> isc) << 24);
+  isc << 27);
 }
 }
 
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 01e59b9..fa8dfe0 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1001,7 +1001,7 @@ static inline void cpu_inject_io(S390CPU *cpu, uint16_t 
subchannel_id,
  uint32_t io_int_parm, uint32_t io_int_word)
 {
 CPUS390XState *env = &cpu->env;
-int isc = ffs(io_int_word << 2) - 1;
+int isc = IO_INT_WORD_ISC(io_int_word);
 
 if (env->io_index[isc] == MAX_IO_QUEUE - 1) {
 /* ugh - can't queue anymore. Let's drop. */
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 9f9088b..7626831 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -628,6 +628,8 @@ static void do_io_interrupt(CPUS390XState *env)
 }
 
 for (isc = 0; isc < ARRAY_SIZE(env->io_index); isc++) {
+uint64_t isc_bits;
+
 if (env->io_index[isc] < 0) {
 continue;
 }
@@ -637,7 +639,8 @@ static void do_io_interrupt(CPUS390XState *env)
 }
 
 q = &env->io_queue[env->io_index[isc]][isc];
-if (!(env->cregs[6] & q->word)) {
+isc_bits = ISC_TO_ISC_BITS(IO_INT_WORD_ISC(q->word));
+if (!(env->cregs[6] & isc_bits)) {
 disable = 0;
 continue;
 }
diff --git a/target-s390x/ioinst.h b/target-s390x/ioinst.h
index d5a43f4..7bed291 100644
--- a/target-s390x/ioinst.h
+++ b/target-s390x/ioinst.h
@@ -209,6 +209,9 @@ typedef struct IOIntCode {
 #define IOINST_SCHID_SSID(_schid)  ((_schid & 0x0006) >> 17)
 #define IOINST_SCHID_NR(_schid)(_schid & 0x)
 
+#define IO_INT_WORD_ISC(_int_word) ((_int_word & 0x3800) >> 24)
+#define ISC_TO_ISC_BITS(_isc)  ((0x80 >> _isc) << 24)
+
 int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
  int *schid);
 int ioinst_handle_xsch(CPUS390XState *env, uint64_t reg1);
-- 
1.7.12.4




[Qemu-devel] [PATCH 1/2] s390: Keep I/O interrupts enabled for all iscs.

2013-02-07 Thread Cornelia Huck
do_io_interrupt() would stop scanning further iscs if it found
an I/O interrupt it could inject. This might cause the pending
interrupt indication for I/O interrupts to be reset although there
might be queued I/O interrupts for subsequent iscs.

Fix this by reordering the logic: Inject the I/O interrupt immediately
and continue searching all iscs for queued interrupts.

Signed-off-by: Cornelia Huck 
---
 target-s390x/helper.c | 40 +---
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 043feb2..9f9088b 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -617,7 +617,6 @@ static void do_ext_interrupt(CPUS390XState *env)
 
 static void do_io_interrupt(CPUS390XState *env)
 {
-uint64_t mask = 0, addr = 0;
 LowCore *lowcore;
 IOIntQueue *q;
 uint8_t isc;
@@ -642,36 +641,39 @@ static void do_io_interrupt(CPUS390XState *env)
 disable = 0;
 continue;
 }
-found = 1;
-lowcore = cpu_map_lowcore(env);
+if (!found) {
+uint64_t mask, addr;
 
-lowcore->subchannel_id = cpu_to_be16(q->id);
-lowcore->subchannel_nr = cpu_to_be16(q->nr);
-lowcore->io_int_parm = cpu_to_be32(q->parm);
-lowcore->io_int_word = cpu_to_be32(q->word);
-lowcore->io_old_psw.mask = cpu_to_be64(get_psw_mask(env));
-lowcore->io_old_psw.addr = cpu_to_be64(env->psw.addr);
-mask = be64_to_cpu(lowcore->io_new_psw.mask);
-addr = be64_to_cpu(lowcore->io_new_psw.addr);
+found = 1;
+lowcore = cpu_map_lowcore(env);
 
-cpu_unmap_lowcore(lowcore);
+lowcore->subchannel_id = cpu_to_be16(q->id);
+lowcore->subchannel_nr = cpu_to_be16(q->nr);
+lowcore->io_int_parm = cpu_to_be32(q->parm);
+lowcore->io_int_word = cpu_to_be32(q->word);
+lowcore->io_old_psw.mask = cpu_to_be64(get_psw_mask(env));
+lowcore->io_old_psw.addr = cpu_to_be64(env->psw.addr);
+mask = be64_to_cpu(lowcore->io_new_psw.mask);
+addr = be64_to_cpu(lowcore->io_new_psw.addr);
 
-env->io_index[isc]--;
+cpu_unmap_lowcore(lowcore);
+
+env->io_index[isc]--;
+
+DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __func__,
+env->psw.mask, env->psw.addr);
+load_psw(env, mask, addr);
+}
 if (env->io_index[isc] >= 0) {
 disable = 0;
 }
-break;
+continue;
 }
 
 if (disable) {
 env->pending_int &= ~INTERRUPT_IO;
 }
 
-if (found) {
-DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __func__,
-env->psw.mask, env->psw.addr);
-load_psw(env, mask, addr);
-}
 }
 
 static void do_mchk_interrupt(CPUS390XState *env)
-- 
1.7.12.4




Re: [Qemu-devel] [PATCH for-1.5 0/8] virtio-blk refactoring.

2013-02-11 Thread Cornelia Huck
On Mon, 11 Feb 2013 10:37:20 +0100
fred.kon...@greensocs.com wrote:

> From: KONRAD Frederic 
> 
> This is the next part of virtio-refactoring.
> 
> I send it now to have it reviewed.
> 
> Basically it creates virtio-blk device which extends virtio-device.
> Then a virtio-blk can be connected on a virtio-bus.
> virtio-blk-pci, virtio-blk-s390x, virtio-blk-ccw are created too, they extend
> respectively virtio-pci, virtio-s390-device, virtio-ccw-device and have a
> virtio-blk.
> 
> It is on top of "virtio: make virtio device's structures public" I posted
> before, but you can checkout my branch here:
> 
> git://git.greensocs.com/qemu_virtio.git virtio-blk-v4
> 
> I made basic tests (with linux guests) on:
>  * qemu-system-i386
>  * qemu-system-s390x
> 
> I didn't test dataplane as I don't know how it works? Depends on linux AIO?
> 
> Stefan can you try launching dataplane with my tree?
> 
> I didn't test virtio-ccw as I don't have the hardware.
> 
> Anyone can try it on ccw hardware?

Compiles and works for me. My block device shows up in 'info qtree' as
follows:

  dev: virtual-css-bridge, id ""
irq 0
bus: virtual-css
  type virtual-css-bus
  dev: virtio-blk-ccw, id "virtio-disk0"
devno = "fe.0.0815"
drive = drive-virtio-disk0
logical_block_size = 512
physical_block_size = 512
min_io_size = 0
opt_io_size = 0
bootindex = -1
discard_granularity = 0
serial = 
scsi = on
indirect_desc = on
event_idx = on
bus: virtio-disk0.0
  type virtio-ccw-bus
  dev: virtio-blk, id ""
drive = drive-virtio-disk0
logical_block_size = 512
physical_block_size = 512
min_io_size = 0
opt_io_size = 0
bootindex = -1
discard_granularity = 0
cyls = 16383
heads = 16
secs = 63
serial = 
config-wce = off
scsi = on




[Qemu-devel] [RFC PATCH 3/3] KVM: s390: Hook up ioeventfds.

2013-02-21 Thread Cornelia Huck
As s390 doesn't use memory writes for virtio notifcations, create
a special kind of ioeventfd instead that hooks up into diagnose
0x500 (kvm hypercall) with function code 3 (virtio-ccw notification).

Signed-off-by: Cornelia Huck 
---
 arch/s390/include/asm/kvm_host.h |  23 ++
 arch/s390/kvm/Kconfig|   1 +
 arch/s390/kvm/Makefile   |   2 +-
 arch/s390/kvm/diag.c |  23 ++
 arch/s390/kvm/kvm-s390.c | 165 +++
 arch/s390/kvm/kvm-s390.h |   3 +
 6 files changed, 216 insertions(+), 1 deletion(-)

diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 16bd5d1..8dad9dc 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define KVM_MAX_VCPUS 64
 #define KVM_USER_MEM_SLOTS 32
@@ -262,8 +263,30 @@ struct kvm_arch{
debug_info_t *dbf;
struct kvm_s390_float_interrupt float_int;
struct gmap *gmap;
+   struct list_head sch_fds;
+   struct rw_semaphore sch_fds_sem;
int css_support;
 };
 
 extern int sie64a(struct kvm_s390_sie_block *, u64 *);
+#define __KVM_HAVE_ARCH_IOEVENTFD
+
+#define KVM_S390_IOEVENTFD_VIRTIO_CCW_NOTIFY 1
+
+struct kvm_s390_ioeventfd_data {
+   __u8 type;
+   union {
+   /* VIRTIO_CCW_NOTIFY */
+   struct {
+   __u64 vq;
+   struct subchannel_id schid;
+   } virtio_ccw_vq;
+   char padding[35];
+   };
+} __packed;
+
+struct kvm_arch_ioeventfd {
+   struct list_head entry;
+   struct kvm_s390_ioeventfd_data data;
+};
 #endif
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index b58dd86..3c43e30 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -22,6 +22,7 @@ config KVM
select PREEMPT_NOTIFIERS
select ANON_INODES
select HAVE_KVM_CPU_RELAX_INTERCEPT
+   select HAVE_KVM_EVENTFD
---help---
  Support hosting paravirtualized guest machines using the SIE
  virtualization capability on the mainframe. This should work
diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile
index 2441ffd..dbd8cc9 100644
--- a/arch/s390/kvm/Makefile
+++ b/arch/s390/kvm/Makefile
@@ -6,7 +6,7 @@
 # it under the terms of the GNU General Public License (version 2 only)
 # as published by the Free Software Foundation.
 
-common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o)
+common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o eventfd.o)
 
 ccflags-y := -Ivirt/kvm -Iarch/s390/kvm
 
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index a390687..51ea66f 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -104,6 +104,27 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
return -EREMOTE;
 }
 
+static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)
+{
+   struct kvm_s390_ioeventfd_data data;
+   u32 tmp;
+
+   /* No channel I/O? Get out quickly. */
+   if (!vcpu->kvm->arch.css_support ||
+   (vcpu->run->s.regs.gprs[1] != 3))
+   return -EOPNOTSUPP;
+
+   /* subchannel id is in gpr 2, queue in gpr 3 */
+   tmp = vcpu->run->s.regs.gprs[2] & 0x;
+   memcpy(&data.virtio_ccw_vq.schid, &tmp,
+  sizeof(data.virtio_ccw_vq.schid));
+   data.virtio_ccw_vq.vq = vcpu->run->s.regs.gprs[3];
+   data.type = KVM_S390_IOEVENTFD_VIRTIO_CCW_NOTIFY;
+
+   /* If signalling via eventfd fails, we want to drop to userspace. */
+   return kvm_s390_ioeventfd_signal(vcpu->kvm, &data) ? -EOPNOTSUPP : 0;
+}
+
 int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
 {
int code = (vcpu->arch.sie_block->ipb & 0xfff) >> 16;
@@ -118,6 +139,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
return __diag_time_slice_end_directed(vcpu);
case 0x308:
return __diag_ipl_functions(vcpu);
+   case 0x500:
+   return __diag_virtio_hypercall(vcpu);
default:
return -EOPNOTSUPP;
}
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 58a5f03..cd9eb0e 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -15,6 +15,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -143,6 +144,7 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_ONE_REG:
case KVM_CAP_ENABLE_CAP:
case KVM_CAP_S390_CSS_SUPPORT:
+   case KVM_CAP_IOEVENTFD:
r = 1;
break;
case KVM_CAP_NR_VCPUS:
@@ -237,6 +239,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
if (!kvm->arch.gmap)
goto out_nogmap;
}
+   INIT_LIST_HEAD(&kvm->arch.sch_fds);
+   init_rwsem(&kvm->arch.

[Qemu-devel] [RFC PATCH 1/2] linux-headers: Update with ioeventfd changes.

2013-02-21 Thread Cornelia Huck
Signed-off-by: Cornelia Huck 
---
 linux-headers/linux/kvm.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 5af9357..a7f92a0 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -448,12 +448,14 @@ enum {
kvm_ioeventfd_flag_nr_datamatch,
kvm_ioeventfd_flag_nr_pio,
kvm_ioeventfd_flag_nr_deassign,
+   kvm_ioeventfd_flag_nr_arch,
kvm_ioeventfd_flag_nr_max,
 };
 
 #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch)
 #define KVM_IOEVENTFD_FLAG_PIO   (1 << kvm_ioeventfd_flag_nr_pio)
 #define KVM_IOEVENTFD_FLAG_DEASSIGN  (1 << kvm_ioeventfd_flag_nr_deassign)
+#define KVM_IOEVENTFD_FLAG_ARCH  (1 << kvm_ioeventfd_flag_nr_arch)
 
 #define KVM_IOEVENTFD_VALID_FLAG_MASK  ((1 << kvm_ioeventfd_flag_nr_max) - 1)
 
@@ -463,7 +465,7 @@ struct kvm_ioeventfd {
__u32 len; /* 1, 2, 4, or 8 bytes*/
__s32 fd;
__u32 flags;
-   __u8  pad[36];
+   __u8  data[36];/* for architecture-specific data */
 };
 
 /* for KVM_ENABLE_CAP */
-- 
1.7.12.4




[Qemu-devel] [RFC PATCH 1/3] KVM: s390: Move out initialization code.

2013-02-21 Thread Cornelia Huck
kvm-s390's module initialization code needs to live in a separate
module (kvm-s390.ko) if we want to include eventfd (which has its
own module init func).

Signed-off-by: Cornelia Huck 
---
 arch/s390/kvm/Makefile   |  4 +++-
 arch/s390/kvm/init.c | 52 
 arch/s390/kvm/kvm-s390.c | 38 ---
 3 files changed, 59 insertions(+), 35 deletions(-)
 create mode 100644 arch/s390/kvm/init.c

diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile
index 3975722..2441ffd 100644
--- a/arch/s390/kvm/Makefile
+++ b/arch/s390/kvm/Makefile
@@ -11,4 +11,6 @@ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o)
 ccflags-y := -Ivirt/kvm -Iarch/s390/kvm
 
 kvm-objs := $(common-objs) kvm-s390.o intercept.o interrupt.o priv.o sigp.o 
diag.o
-obj-$(CONFIG_KVM) += kvm.o
+kvm_s390-objs := init.o
+
+obj-$(CONFIG_KVM) += kvm.o kvm_s390.o
diff --git a/arch/s390/kvm/init.c b/arch/s390/kvm/init.c
new file mode 100644
index 000..dc4028a
--- /dev/null
+++ b/arch/s390/kvm/init.c
@@ -0,0 +1,52 @@
+/*
+ * kvm on s390 module initialization
+ *
+ * Copyright IBM Corp. 2013
+ *
+ * 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): Cornelia Huck 
+ */
+
+#include 
+#include 
+#include 
+#include "kvm-s390.h"
+
+extern unsigned long long *facilities;
+
+static int __init kvm_s390_init(void)
+{
+   int ret;
+   ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
+   if (ret)
+   return ret;
+
+   /*
+* guests can ask for up to 255+1 double words, we need a full page
+* to hold the maximum amount of facilities. On the other hand, we
+* only set facilities that are known to work in KVM.
+*/
+   facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
+   if (!facilities) {
+   kvm_exit();
+   return -ENOMEM;
+   }
+   memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
+   facilities[0] &= 0xff00fff3f47cULL;
+   facilities[1] &= 0x001cULL;
+   return 0;
+}
+
+static void __exit kvm_s390_exit(void)
+{
+   free_page((unsigned long) facilities);
+   kvm_exit();
+}
+
+module_init(kvm_s390_init);
+module_exit(kvm_s390_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index f822d36..58a5f03 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -36,6 +36,9 @@
 #include "trace.h"
 #include "trace-s390.h"
 
+unsigned long long *facilities;
+EXPORT_SYMBOL_GPL(facilities);
+
 #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
 
 struct kvm_stats_debugfs_item debugfs_entries[] = {
@@ -83,8 +86,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ NULL }
 };
 
-static unsigned long long *facilities;
-
 /* Section: not file related */
 int kvm_arch_hardware_enable(void *garbage)
 {
@@ -823,6 +824,7 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, 
unsigned long addr)
return -EFAULT;
return 0;
 }
+EXPORT_SYMBOL_GPL(kvm_s390_vcpu_store_status);
 
 static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
 struct kvm_enable_cap *cap)
@@ -1026,35 +1028,3 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
   struct kvm_memory_slot *slot)
 {
 }
-
-static int __init kvm_s390_init(void)
-{
-   int ret;
-   ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
-   if (ret)
-   return ret;
-
-   /*
-* guests can ask for up to 255+1 double words, we need a full page
-* to hold the maximum amount of facilities. On the other hand, we
-* only set facilities that are known to work in KVM.
-*/
-   facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
-   if (!facilities) {
-   kvm_exit();
-   return -ENOMEM;
-   }
-   memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
-   facilities[0] &= 0xff00fff3f47cULL;
-   facilities[1] &= 0x001cULL;
-   return 0;
-}
-
-static void __exit kvm_s390_exit(void)
-{
-   free_page((unsigned long) facilities);
-   kvm_exit();
-}
-
-module_init(kvm_s390_init);
-module_exit(kvm_s390_exit);
-- 
1.7.12.4




[Qemu-devel] [RFC PATCH 0/2] qemu: ioeventfd for virtio-ccw.

2013-02-21 Thread Cornelia Huck
This patch series makes use of the s390 ioeventfd implementation
to speed up virtio-ccw a bit.

We hook up virtio notifications via diagnose 500 as ioeventfds,
specifying a subchannel id and virtqueue index combination.

ioeventfds are used by default for all virtio devices; there's
an ioeventfd property that can be used to turn ioeventfd usage
off for a device (similar to virtio-pci).

A simple dd on a virtio-blk device
   dd if=/dev/vda of=/dev/null iflag=direct bs=4k count=1
is now twice as fast :)

(Patches are against master.)

Cornelia Huck (2):
  linux-headers: Update with ioeventfd changes.
  virtio-ccw: Wire up ioeventfd.

 hw/s390x/css.c|   2 +-
 hw/s390x/css.h|   1 +
 hw/s390x/virtio-ccw.c | 114 ++
 hw/s390x/virtio-ccw.h |   7 +++
 linux-headers/linux/kvm.h |   4 +-
 target-s390x/cpu.h|  16 +++
 target-s390x/kvm.c|  27 +++
 7 files changed, 169 insertions(+), 2 deletions(-)

-- 
1.7.12.4




[Qemu-devel] [RFC PATCH 2/2] virtio-ccw: Wire up ioeventfd.

2013-02-21 Thread Cornelia Huck
On hosts that support ioeventfd, make use of it for host-to-guest
notifications via diagnose 500.

Signed-off-by: Cornelia Huck 
---
 hw/s390x/css.c|   2 +-
 hw/s390x/css.h|   1 +
 hw/s390x/virtio-ccw.c | 114 ++
 hw/s390x/virtio-ccw.h |   7 
 target-s390x/cpu.h|  16 +++
 target-s390x/kvm.c|  27 
 6 files changed, 166 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 85f6f22..82e6746 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -68,7 +68,7 @@ int css_create_css_image(uint8_t cssid, bool default_image)
 return 0;
 }
 
-static uint16_t css_build_subchannel_id(SubchDev *sch)
+uint16_t css_build_subchannel_id(SubchDev *sch)
 {
 if (channel_subsys->max_cssid > 0) {
 return (sch->cssid << 8) | (1 << 3) | (sch->ssid << 1) | 1;
diff --git a/hw/s390x/css.h b/hw/s390x/css.h
index 85ed05d..b536ab5 100644
--- a/hw/s390x/css.h
+++ b/hw/s390x/css.h
@@ -90,6 +90,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);
+uint16_t css_build_subchannel_id(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);
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index d92e427..23b8092 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -63,6 +63,84 @@ VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
 return vdev;
 }
 
+static int virtio_ccw_set_guest2host_notifier(VirtioCcwDevice *dev, int n,
+  bool assign, bool set_handler)
+{
+VirtQueue *vq = virtio_get_queue(dev->vdev, n);
+EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
+int r = 0;
+SubchDev *sch = dev->sch;
+uint32_t sch_id = (css_build_subchannel_id(sch) << 16) | sch->schid;
+
+if (assign) {
+r = event_notifier_init(notifier, 1);
+if (r < 0) {
+error_report("%s: unable to init event notifier: %d", __func__, r);
+return r;
+}
+virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
+s390_assign_subch_ioeventfd(event_notifier_get_fd(notifier), sch_id,
+n, assign);
+} else {
+virtio_queue_set_host_notifier_fd_handler(vq, false, false);
+s390_assign_subch_ioeventfd(event_notifier_get_fd(notifier), sch_id,
+n, assign);
+event_notifier_cleanup(notifier);
+}
+return r;
+}
+
+static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
+{
+int n, r;
+
+if (!(dev->flags & VIRTIO_CCW_FLAG_USE_IOEVENTFD) ||
+dev->ioeventfd_started) {
+return;
+}
+for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
+if (!virtio_queue_get_num(dev->vdev, n)) {
+continue;
+}
+r = virtio_ccw_set_guest2host_notifier(dev, n, true, true);
+if (r < 0) {
+goto assign_error;
+}
+}
+dev->ioeventfd_started = true;
+return;
+
+  assign_error:
+while (--n >= 0) {
+if (!virtio_queue_get_num(dev->vdev, n)) {
+continue;
+}
+r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
+assert(r >= 0);
+}
+dev->ioeventfd_started = false;
+/* Disable ioeventfd for this device. */
+dev->flags &= ~VIRTIO_CCW_FLAG_USE_IOEVENTFD;
+error_report("%s: failed. Fallback to userspace (slower).", __func__);
+}
+
+static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev)
+{
+int n, r;
+
+if (!dev->ioeventfd_started) {
+return;
+}
+for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
+if (!virtio_queue_get_num(dev->vdev, n)) {
+continue;
+}
+r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
+assert(r >= 0);
+}
+dev->ioeventfd_started = false;
+}
+
 VirtualCssBus *virtual_css_bus_init(void)
 {
 VirtualCssBus *cbus;
@@ -187,6 +265,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
 }
 break;
 case CCW_CMD_VDEV_RESET:
+virtio_ccw_stop_ioeventfd(dev);
 virtio_reset(dev->vdev);
 ret = 0;
 break;
@@ -313,10 +392,16 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
 ret = -EFAULT;
 } else {
 status = ldub_phys(ccw.cda);
+if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
+virtio_ccw_stop_ioeventfd(dev);
+}
 virtio_set_status(dev->vdev, status);
 if (

[Qemu-devel] [RFC PATCH 2/3] KVM: Generalize ioeventfds.

2013-02-21 Thread Cornelia Huck
Currently, ioeventfds are designed to work on architectures that
can trap I/O memory writes. This won't work for architectures like
s390, however; therefore provide a way for architectures to override
this with an architecture-specific implementation.

Signed-off-by: Cornelia Huck 
---
 Documentation/virtual/kvm/api.txt |   5 +-
 include/linux/kvm_host.h  |  13 +++
 include/uapi/linux/kvm.h  |   4 +-
 virt/kvm/eventfd.c| 181 ++
 4 files changed, 146 insertions(+), 57 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index c2534c3..13c038c 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1465,7 +1465,7 @@ struct kvm_ioeventfd {
__u32 len; /* 1, 2, 4, or 8 bytes*/
__s32 fd;
__u32 flags;
-   __u8  pad[36];
+   __u8  data[36];/* for architecture-specific data */
 };
 
 The following flags are defined:
@@ -1473,10 +1473,13 @@ The following flags are defined:
 #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch)
 #define KVM_IOEVENTFD_FLAG_PIO   (1 << kvm_ioeventfd_flag_nr_pio)
 #define KVM_IOEVENTFD_FLAG_DEASSIGN  (1 << kvm_ioeventfd_flag_nr_deassign)
+#define KVM_IOEVENTFD_FLAG_ARCH  (1 << kvm_ioeventfd_flag_nr_arch)
 
 If datamatch flag is set, the event will be signaled only if the written value
 to the registered address is equal to datamatch in struct kvm_ioeventfd.
 
+If the arch flag is set, the eventfd will use the data field. If the arch flag
+is not set, the data field is not valid.
 
 4.60 KVM_DIRTY_TLB
 
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 722cae7..d7965fb 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -905,8 +905,21 @@ static inline void kvm_free_irq_routing(struct kvm *kvm) {}
 
 #ifdef CONFIG_HAVE_KVM_EVENTFD
 
+struct kvm_arch_ioeventfd;
 void kvm_eventfd_init(struct kvm *kvm);
 int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args);
+struct eventfd_ctx *kvm_ioeventfd_get_eventfd(struct kvm_arch_ioeventfd *arch);
+int kvm_arch_ioeventfd_check(struct kvm_ioeventfd *args);
+void kvm_arch_ioeventfd_init(struct kvm_arch_ioeventfd *arch,
+struct kvm_ioeventfd *args);
+int kvm_arch_ioeventfd_activate(struct kvm *kvm,
+   struct kvm_arch_ioeventfd *arch,
+   struct kvm_ioeventfd *args);
+bool kvm_arch_ioeventfd_match(struct kvm_arch_ioeventfd *arch,
+ struct kvm_arch_ioeventfd *to_match);
+bool kvm_arch_ioeventfd_match_and_release(struct kvm *kvm,
+ struct kvm_arch_ioeventfd *arch,
+ struct kvm_ioeventfd *args);
 
 #ifdef CONFIG_HAVE_KVM_IRQCHIP
 int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args);
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 9a2db57..dfd444b 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -448,12 +448,14 @@ enum {
kvm_ioeventfd_flag_nr_datamatch,
kvm_ioeventfd_flag_nr_pio,
kvm_ioeventfd_flag_nr_deassign,
+   kvm_ioeventfd_flag_nr_arch,
kvm_ioeventfd_flag_nr_max,
 };
 
 #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch)
 #define KVM_IOEVENTFD_FLAG_PIO   (1 << kvm_ioeventfd_flag_nr_pio)
 #define KVM_IOEVENTFD_FLAG_DEASSIGN  (1 << kvm_ioeventfd_flag_nr_deassign)
+#define KVM_IOEVENTFD_FLAG_ARCH  (1 << kvm_ioeventfd_flag_nr_arch)
 
 #define KVM_IOEVENTFD_VALID_FLAG_MASK  ((1 << kvm_ioeventfd_flag_nr_max) - 1)
 
@@ -463,7 +465,7 @@ struct kvm_ioeventfd {
__u32 len; /* 1, 2, 4, or 8 bytes*/
__s32 fd;
__u32 flags;
-   __u8  pad[36];
+   __u8  data[36];/* for architecture-specific data */
 };
 
 /* for KVM_ENABLE_CAP */
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index b6eea5c..63fe454 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -568,23 +568,37 @@ module_exit(irqfd_module_exit);
  *
  * userspace can register a PIO/MMIO address with an eventfd for receiving
  * notification when the memory has been touched.
+ *
+ * Architectures that use a notification mechanism different from memory
+ * writes may override this with architecture-specific callbacks.
  * 
  */
-
-struct _ioeventfd {
-   struct list_head list;
+#ifndef __KVM_HAVE_ARCH_IOEVENTFD
+struct kvm_arch_ioeventfd {
u64  addr;
int  length;
-   struct eventfd_ctx  *eventfd;
u64  datamatch;
struct kvm_io_device dev;
bool wildcard;
 };
+#endif
+
+struct _ioeventfd {
+   struct list_head list;
+   struct ev

[Qemu-devel] [RFC PATCH 0/3] kvm: Make ioeventfd usable on s390.

2013-02-21 Thread Cornelia Huck
This patch series aims at making ioeventfds usable on s390.

For "normal" architectures, ioeventfds work by registering
notifications that trap on write operations on memory, making
it possible to handle those writes in the kernel. This won't
work on s390, however.

We want a mechanism that enables trapping of operations equivalent
to the memory writes on other architectures - for the use case
we care about, the diagnose 500 hypercall that performs
virtio notifications. (There's room for other types as well.)

Patch 1 is a preparation patch for kvm/s390.

Patch 2 tries to split out the parts of the ioeventfd mechanism
that need to be implemented differently on special architectures
(i. e. s390). If __KVM_HAVE_ARCH_IOEVENTFD is set, the architecture
will provide a set of kvm_arch_ioeventfd_* functions to be used
instead of the kvm_arch_ioeventfd_* functions implementing the
generic mechanism. Extra payload for the KVM_IOEVENTFD ioctl
can be provided in the existing data fields (renamed to data).
A new flag, KVM_IOEVENTFD_FLAG_ARCH, is used to indicate that an
architecture-specific implementation is used that makes use of
the extra data fields.

Patch 3 implements the kvm_arch_ioeventfd_* functions for s390
and hooks up ioeventfds with diagnose 500.

There's also a companion qemu patch series that makes use of this
for virtio-ccw.

(Patches are against kvm-next.)

Cornelia Huck (3):
  KVM: s390: Move out initialization code.
  KVM: Generalize ioeventfds.
  KVM: s390: Hook up ioeventfds.

 Documentation/virtual/kvm/api.txt |   5 +-
 arch/s390/include/asm/kvm_host.h  |  23 +
 arch/s390/kvm/Kconfig |   1 +
 arch/s390/kvm/Makefile|   6 +-
 arch/s390/kvm/diag.c  |  23 +
 arch/s390/kvm/init.c  |  52 +++
 arch/s390/kvm/kvm-s390.c  | 181 +-
 arch/s390/kvm/kvm-s390.h  |   3 +
 include/linux/kvm_host.h  |  13 +++
 include/uapi/linux/kvm.h  |   4 +-
 virt/kvm/eventfd.c| 181 ++
 11 files changed, 410 insertions(+), 82 deletions(-)
 create mode 100644 arch/s390/kvm/init.c

-- 
1.7.12.4




Re: [Qemu-devel] [RFC PATCH 1/3] KVM: s390: Move out initialization code.

2013-02-21 Thread Cornelia Huck
On Thu, 21 Feb 2013 15:43:55 +0200
"Michael S. Tsirkin"  wrote:

> On Thu, Feb 21, 2013 at 02:12:58PM +0100, Cornelia Huck wrote:
> > kvm-s390's module initialization code needs to live in a separate
> > module (kvm-s390.ko) if we want to include eventfd (which has its
> > own module init func).
> > 
> > Signed-off-by: Cornelia Huck 
> 
> I don't get this explanation.
> What's the problem this solves?
> Could you clarify please?

On s390, we currently build a single 'kvm' module, with a module_init
function. eventfd has its own module_init function, and we can't have
two of them in the same module. I just moved our specific module
initialization into a new 'kvm_s390' module.

> 
> > ---
> >  arch/s390/kvm/Makefile   |  4 +++-
> >  arch/s390/kvm/init.c | 52 
> > 
> >  arch/s390/kvm/kvm-s390.c | 38 ---
> >  3 files changed, 59 insertions(+), 35 deletions(-)
> >  create mode 100644 arch/s390/kvm/init.c
> > 
> > diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile
> > index 3975722..2441ffd 100644
> > --- a/arch/s390/kvm/Makefile
> > +++ b/arch/s390/kvm/Makefile
> > @@ -11,4 +11,6 @@ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o)
> >  ccflags-y := -Ivirt/kvm -Iarch/s390/kvm
> >  
> >  kvm-objs := $(common-objs) kvm-s390.o intercept.o interrupt.o priv.o 
> > sigp.o diag.o
> > -obj-$(CONFIG_KVM) += kvm.o
> > +kvm_s390-objs := init.o
> > +
> > +obj-$(CONFIG_KVM) += kvm.o kvm_s390.o
> > diff --git a/arch/s390/kvm/init.c b/arch/s390/kvm/init.c
> > new file mode 100644
> > index 000..dc4028a
> > --- /dev/null
> > +++ b/arch/s390/kvm/init.c
> > @@ -0,0 +1,52 @@
> > +/*
> > + * kvm on s390 module initialization
> > + *
> > + * Copyright IBM Corp. 2013
> > + *
> > + * 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): Cornelia Huck 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include "kvm-s390.h"
> > +
> > +extern unsigned long long *facilities;
> > +
> > +static int __init kvm_s390_init(void)
> > +{
> > +   int ret;
> > +   ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
> > +   if (ret)
> > +   return ret;
> > +
> > +   /*
> > +* guests can ask for up to 255+1 double words, we need a full page
> > +* to hold the maximum amount of facilities. On the other hand, we
> > +* only set facilities that are known to work in KVM.
> > +*/
> > +   facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
> > +   if (!facilities) {
> > +   kvm_exit();
> > +   return -ENOMEM;
> > +   }
> > +   memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
> > +   facilities[0] &= 0xff00fff3f47cULL;
> > +   facilities[1] &= 0x001cULL;
> > +   return 0;
> > +}
> > +
> > +static void __exit kvm_s390_exit(void)
> > +{
> > +   free_page((unsigned long) facilities);
> > +   kvm_exit();
> > +}
> > +
> > +module_init(kvm_s390_init);
> > +module_exit(kvm_s390_exit);
> > +
> > +MODULE_LICENSE("GPL");
> 
> GPL v2?
> 
> > diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> > index f822d36..58a5f03 100644
> > --- a/arch/s390/kvm/kvm-s390.c
> > +++ b/arch/s390/kvm/kvm-s390.c
> > @@ -36,6 +36,9 @@
> >  #include "trace.h"
> >  #include "trace-s390.h"
> >  
> > +unsigned long long *facilities;
> > +EXPORT_SYMBOL_GPL(facilities);
> > +
> >  #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
> >  
> >  struct kvm_stats_debugfs_item debugfs_entries[] = {
> > @@ -83,8 +86,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
> > { NULL }
> >  };
> >  
> > -static unsigned long long *facilities;
> > -
> >  /* Section: not file related */
> >  int kvm_arch_hardware_enable(void *garbage)
> >  {
> > @@ -823,6 +824,7 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, 
> > unsigned long addr)
> > return -EFAULT;
> > return 0;
> >  }
> > +EXPORT_SYMBOL_GPL(kvm_s390_vcpu_store_status);
> >  
> >  sta

Re: [Qemu-devel] [RFC PATCH 1/3] KVM: s390: Move out initialization code.

2013-02-21 Thread Cornelia Huck
On Thu, 21 Feb 2013 16:18:34 +0200
"Michael S. Tsirkin"  wrote:

> On Thu, Feb 21, 2013 at 03:07:32PM +0100, Cornelia Huck wrote:
> > On Thu, 21 Feb 2013 15:43:55 +0200
> > "Michael S. Tsirkin"  wrote:
> > 
> > > On Thu, Feb 21, 2013 at 02:12:58PM +0100, Cornelia Huck wrote:
> > > > kvm-s390's module initialization code needs to live in a separate
> > > > module (kvm-s390.ko) if we want to include eventfd (which has its
> > > > own module init func).
> > > > 
> > > > Signed-off-by: Cornelia Huck 
> > > 
> > > I don't get this explanation.
> > > What's the problem this solves?
> > > Could you clarify please?
> > 
> > On s390, we currently build a single 'kvm' module, with a module_init
> > function. eventfd has its own module_init function, and we can't have
> > two of them in the same module. I just moved our specific module
> > initialization into a new 'kvm_s390' module.
> 
> 
> You mean this?
> 
> virt/kvm/eventfd.c:static int __init irqfd_module_init(void)
> virt/kvm/eventfd.c:module_init(irqfd_module_init);
> 
> I see. Won't it be easier to just call irqfd_module_init
> from kvm_init?
> 
It does make it clearer what happens, and eliminates the need for a new
module on s390. I'll do that in the next round:

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index d7965fb..55a6de1 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -423,6 +423,19 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu);
 int __must_check vcpu_load(struct kvm_vcpu *vcpu);
 void vcpu_put(struct kvm_vcpu *vcpu);
 
+#ifdef __KVM_HAVE_IOAPIC
+int kvm_irqfd_init(void);
+void kvm_irqfd_exit(void);
+#else
+static inline int kvm_irqfd_init(void)
+{
+   return 0;
+}
+
+static inline void kvm_irqfd_exit(void)
+{
+}
+#endif
 int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
  struct module *module);
 void kvm_exit(void);
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 63fe454..c631c4b 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -544,7 +544,7 @@ void kvm_irq_routing_update(struct kvm *kvm,
  * aggregated from all vm* instances. We need our own isolated single-thread
  * queue to prevent deadlock against flushing the normal work-queue.
  */
-static int __init irqfd_module_init(void)
+int kvm_irqfd_init(void)
 {
irqfd_cleanup_wq = create_singlethread_workqueue("kvm-irqfd-cleanup");
if (!irqfd_cleanup_wq)
@@ -553,13 +553,10 @@ static int __init irqfd_module_init(void)
return 0;
 }
 
-static void __exit irqfd_module_exit(void)
+void kvm_irqfd_exit(void)
 {
destroy_workqueue(irqfd_cleanup_wq);
 }
-
-module_init(irqfd_module_init);
-module_exit(irqfd_module_exit);
 #endif
 
 /*
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index adc68fe..7c188a3 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2920,6 +2920,9 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned 
vcpu_align,
int r;
int cpu;
 
+   r = kvm_irqfd_init();
+   if (r)
+   goto out_irqfd;
r = kvm_arch_init(opaque);
if (r)
goto out_fail;
@@ -3000,6 +3003,8 @@ out_free_0a:
 out_free_0:
kvm_arch_exit();
 out_fail:
+   kvm_irqfd_exit();
+out_irqfd:
return r;
 }
 EXPORT_SYMBOL_GPL(kvm_init);
@@ -3016,6 +3021,7 @@ void kvm_exit(void)
on_each_cpu(hardware_disable_nolock, NULL, 1);
kvm_arch_hardware_unsetup();
kvm_arch_exit();
+   kvm_irqfd_exit();
free_cpumask_var(cpus_hardware_enabled);
 }
 EXPORT_SYMBOL_GPL(kvm_exit);




Re: [Qemu-devel] [RFC PATCH 3/3] KVM: s390: Hook up ioeventfds.

2013-02-21 Thread Cornelia Huck
On Thu, 21 Feb 2013 16:39:05 +0200
"Michael S. Tsirkin"  wrote:

> On Thu, Feb 21, 2013 at 02:13:00PM +0100, Cornelia Huck wrote:
> > As s390 doesn't use memory writes for virtio notifcations, create
> > a special kind of ioeventfd instead that hooks up into diagnose
> > 0x500 (kvm hypercall) with function code 3 (virtio-ccw notification).
> > 
> > Signed-off-by: Cornelia Huck 
> 
> Do we really have to put virtio specific stuff into kvm?
> How about we add generic functionality to match GPRs
> on a hypercall and signal an eventfd?

Worth a try implementing that.

> 
> Also, it's a bit unfortunate that this doesn't use
> the io bus datastructure, long term the linked list handling
> might become a bottleneck, using shared code this could maybe
> benefit from performance optimizations there.

The linked list stuff was more like an initial implementation that
could be improved later.

> io bus data structure currently has the ability to match on
> two 64 bit fields (addr/datamatch) and a signed 32 bit one (length).
> Isn't this sufficient for your purposes?
> How about sticking subchannel id in address, vq in data match
> and using io bus?

I can give that a try. (I must admit that I didn't look at the iobus
stuff in detail.)

> 
> BTW maybe we could do this for the user interface too,
> while I'm not 100% sure it's the cleanest thing to do
> (or will work), it would certainly minimize the patchset.

You mean integrating with the generic interface and dropping the new
ARCH flag?

> 
> > ---
> >  arch/s390/include/asm/kvm_host.h |  23 ++
> >  arch/s390/kvm/Kconfig|   1 +
> >  arch/s390/kvm/Makefile   |   2 +-
> >  arch/s390/kvm/diag.c |  23 ++
> >  arch/s390/kvm/kvm-s390.c | 165 
> > +++
> >  arch/s390/kvm/kvm-s390.h |   3 +
> >  6 files changed, 216 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/s390/include/asm/kvm_host.h 
> > b/arch/s390/include/asm/kvm_host.h
> > index 16bd5d1..8dad9dc 100644
> > --- a/arch/s390/include/asm/kvm_host.h
> > +++ b/arch/s390/include/asm/kvm_host.h
> > @@ -18,6 +18,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  
> >  #define KVM_MAX_VCPUS 64
> >  #define KVM_USER_MEM_SLOTS 32
> > @@ -262,8 +263,30 @@ struct kvm_arch{
> > debug_info_t *dbf;
> > struct kvm_s390_float_interrupt float_int;
> > struct gmap *gmap;
> > +   struct list_head sch_fds;
> > +   struct rw_semaphore sch_fds_sem;
> 
> Why sch_? Related to subchannel somehow?

Yes.

> Also you mean _ioeventfds really?

Probably, I don't have the irqfd stuff figured out yet.

> Might be a good idea to document locking here.

OK.

> 
> > int css_support;
> >  };
> >  
> >  extern int sie64a(struct kvm_s390_sie_block *, u64 *);
> > +#define __KVM_HAVE_ARCH_IOEVENTFD
> > +
> > +#define KVM_S390_IOEVENTFD_VIRTIO_CCW_NOTIFY 1
> > +
> > +struct kvm_s390_ioeventfd_data {
> > +   __u8 type;
> > +   union {
> > +   /* VIRTIO_CCW_NOTIFY */
> > +   struct {
> > +   __u64 vq;
> > +   struct subchannel_id schid;
> > +   } virtio_ccw_vq;
> > +   char padding[35];
> > +   };
> > +} __packed;
> > +
> 
> Do you expect userspace to use this structure?
> If yes this is the wrong header. If not why is it packed?

Indeed, userspace is supposed to use this.

> 
> > +struct kvm_arch_ioeventfd {
> > +   struct list_head entry;
> > +   struct kvm_s390_ioeventfd_data data;
> 
> Let's not waste memory keeping padding in kernel datastructures.
> 
> > +};
> >  #endif
> > diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
> > index b58dd86..3c43e30 100644
> > --- a/arch/s390/kvm/Kconfig
> > +++ b/arch/s390/kvm/Kconfig
> > @@ -22,6 +22,7 @@ config KVM
> > select PREEMPT_NOTIFIERS
> > select ANON_INODES
> > select HAVE_KVM_CPU_RELAX_INTERCEPT
> > +   select HAVE_KVM_EVENTFD
> > ---help---
> >   Support hosting paravirtualized guest machines using the SIE
> >   virtualization capability on the mainframe. This should work
> > diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile
> > index 2441ffd..dbd8cc9 100644
> > --- a/arch/s390/kvm/Makefile
> > +++ b/arch/s390/kvm/Makefile
> > @@ -6,7 +6,7 @@
> >  # it under the terms of the GNU General Public License (version 2 only)
> >  # as published by the Free Softwa

Re: [Qemu-devel] [RFC PATCH 3/3] KVM: s390: Hook up ioeventfds.

2013-02-21 Thread Cornelia Huck
On Thu, 21 Feb 2013 18:34:59 +0200
"Michael S. Tsirkin"  wrote:

> On Thu, Feb 21, 2013 at 04:21:43PM +0100, Cornelia Huck wrote:
> > On Thu, 21 Feb 2013 16:39:05 +0200
> > "Michael S. Tsirkin"  wrote:
> > 
> > > On Thu, Feb 21, 2013 at 02:13:00PM +0100, Cornelia Huck wrote:
> > > > As s390 doesn't use memory writes for virtio notifcations, create
> > > > a special kind of ioeventfd instead that hooks up into diagnose
> > > > 0x500 (kvm hypercall) with function code 3 (virtio-ccw notification).
> > > > 
> > > > Signed-off-by: Cornelia Huck 
> > > 
> > > Do we really have to put virtio specific stuff into kvm?
> > > How about we add generic functionality to match GPRs
> > > on a hypercall and signal an eventfd?
> > 
> > Worth a try implementing that.
> > 
> > > 
> > > Also, it's a bit unfortunate that this doesn't use
> > > the io bus datastructure, long term the linked list handling
> > > might become a bottleneck, using shared code this could maybe
> > > benefit from performance optimizations there.
> > 
> > The linked list stuff was more like an initial implementation that
> > could be improved later.
> > 
> > > io bus data structure currently has the ability to match on
> > > two 64 bit fields (addr/datamatch) and a signed 32 bit one (length).
> > > Isn't this sufficient for your purposes?
> > > How about sticking subchannel id in address, vq in data match
> > > and using io bus?
> > 
> > I can give that a try. (I must admit that I didn't look at the iobus
> > stuff in detail.)
> > 
> > > 
> > > BTW maybe we could do this for the user interface too,
> > > while I'm not 100% sure it's the cleanest thing to do
> > > (or will work), it would certainly minimize the patchset.
> > 
> > You mean integrating with the generic interface and dropping the new
> > ARCH flag?
> 
> Not sure about the flag but we could use the general structure
> without an arch-specific format, if that's a good fit.
> 
So I have something that seems to do what I want. I'll see if I can
morph it into something presentable tomorrow.

diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index b58dd86..3c43e30 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -22,6 +22,7 @@ config KVM
select PREEMPT_NOTIFIERS
select ANON_INODES
select HAVE_KVM_CPU_RELAX_INTERCEPT
+   select HAVE_KVM_EVENTFD
---help---
  Support hosting paravirtualized guest machines using the SIE
  virtualization capability on the mainframe. This should work
diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile
index 3975722..8fe9d65 100644
--- a/arch/s390/kvm/Makefile
+++ b/arch/s390/kvm/Makefile
@@ -6,7 +6,7 @@
 # it under the terms of the GNU General Public License (version 2 only)
 # as published by the Free Software Foundation.
 
-common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o)
+common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o eventfd.o)
 
 ccflags-y := -Ivirt/kvm -Iarch/s390/kvm
 
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index a390687..7fc195e 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -104,6 +104,20 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
return -EREMOTE;
 }
 
+static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)
+{
+   int ret, idx;
+   u64 vq = vcpu->run->s.regs.gprs[3];
+
+   idx = srcu_read_lock(&vcpu->kvm->srcu);
+   ret = kvm_io_bus_write(vcpu->kvm, KVM_CSS_BUS,
+   vcpu->run->s.regs.gprs[2],
+   vcpu->run->s.regs.gprs[1],
+   &vq);
+   srcu_read_unlock(&vcpu->kvm->srcu, idx);
+   return ret;
+}
+
 int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
 {
int code = (vcpu->arch.sie_block->ipb & 0xfff) >> 16;
@@ -118,6 +132,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
return __diag_time_slice_end_directed(vcpu);
case 0x308:
return __diag_ipl_functions(vcpu);
+   case 0x500:
+   return __diag_virtio_hypercall(vcpu);
default:
return -EOPNOTSUPP;
}
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index f822d36..04d2454 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -142,6 +142,7 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_ONE_REG:
case KVM_CAP_ENABLE_CAP:
case KVM_CAP_S390_CSS_SUPPORT:
+   case KVM_CAP_IOEVENTFD:
r = 1;
 

  1   2   3   4   5   6   7   8   9   10   >