Re: [Qemu-devel] [PATCH 2/2 RFC] s390x/pci: rework pci infrastructure modeling

2015-03-17 Thread Frank Blaschka
On Tue, Mar 17, 2015 at 08:11:14AM +0100, Alexander Graf wrote:
 
 
 On 12.03.15 16:22, Michael S. Tsirkin wrote:
  On Thu, Mar 12, 2015 at 09:59:59AM -0500, Alexander Graf wrote:
 
 
  On 12.03.15 08:16, Frank Blaschka wrote:
  On Thu, Mar 12, 2015 at 11:50:02AM +0100, Frank Blaschka wrote:
  On Thu, Mar 12, 2015 at 11:03:50AM +0100, Michael S. Tsirkin wrote:
  On Thu, Mar 12, 2015 at 10:54:24AM +0100, Frank Blaschka wrote:
  On Wed, Mar 11, 2015 at 06:42:34PM +0100, Michael S. Tsirkin wrote:
  On Wed, Mar 11, 2015 at 03:38:44PM +0100, Frank Blaschka wrote:
  On Tue, Mar 10, 2015 at 03:26:23PM +0100, Michael S. Tsirkin wrote:
  On Tue, Mar 10, 2015 at 02:03:34PM +0100, Frank Blaschka wrote:
  This patch changes the modeling of the s390 qemu pci 
  infrastructure to
  better match the actual pci architecture defined by the real 
  hardware.
 
  A pci host bridge like device (s390-pcihost) models the abstract 
  view
  of the bare pci function. It provides s390 specific configuration
  attributes (fid and uid) for the attached pci device. The host 
  bridge
  restrict the pci bus to just hold one single pci device. Also we 
  have
  to make the s390 pci host bridge hot plugable.
 
  This requirement is really because of the 1 device per bus
  limitation, isn't it?
  If you supported many devices per bus, you could use
  hotplug there and there won't be need to support hotplug
  of the host bridge.
 
  Absolutely yes. Have you seen my first proposal?
  It basically exploits the normal pci bridge/bus/slot mechanism but 
  need
  a place to store s390 specific configuration attributes.
 
  The idea of a host bridge having this attributes and limit the bus
  to one slot was an alternate design approach suggested by Alex.
 
  I like Alex's idea because:
  1) It reflects pretty well the actual nature of the pci system in 
  real s390 hw
  2) It does not create an somehow artifical pci topology
 
 
  I'll have to re-read but here's a thought: use your patch but
  remove host bridge hotplug support code.
  Stick a standard bridge with shpc support in the single slot
  behind your host bridge (existing pci-bridge-dev should do the trick,
  though not many people use it, so you might
  run into bugs, but fixing them is a good idea anyway).
  You can instanciate it automatically like Marcel's patches do
  for PXB.
  Still don't undertsand so I try to summarize in my words please 
  corrent me
  if I got something wrong
 
  - create a standard host bridge
  - change the s390-pcihost to be a pci 2 pci bridge
 
  Actually I suggested simply adding a pci 2 pci bridge behind
  s390-pcihost.
 
  - now we can hotplug the s390-pcihost + hotplug a pci device to this
s390-pcihost using standard pci hotplug mechanism
 
  My idea was to just hotplug a pci device behind the standard pci 2 pci
  bridge. don't support hotplugging bridge itself or s390-pcihost itself.
 
  - we keep the 1 slot limit on the s390-pcihost. We need a place to
store fid and uid information (see mail thread from my 1 proposal)
 
  Yes.
 
  - If we need more than 32 pci functions we have to extend the primary 
  pci bus
via standart pci 2 pci bridges or add another standart host bridge
 
  Is this your suggestion?
 
  Almost, clarifications above.
 
  OK, got your idea. Have to think about it and may do some prototyping. 
  THX!
 
 
  hm, after thinking more about this I realized this is not working for us.
  Remember we need a place to store the fid and uid attributes. This place
  must be:
  1) uid/fid per pci device
  2) uid/fid in a hotplugable device
 
  I have the feeling we are at the beginning again. Although I liked Alex's
  idea (host bridge containing uid/fid and having only 1 slot on the bus), 
  it
  looks like we end up at my first proposal. This does not require any
  modification in base pci/bus code.
 
  Thx to all of you for the discussion and suggestions.
 
  I disagree with the assessment. The reason mst was opposed to do the
  one-phb-per-device implementation (which is the closest we can get to
  model things like real hardware FWIW) was that hotplug would work on the
  s390 level rather than pci. I don't see how your first proposal fixes that.
 
  Also Michael, PCI on s390 is very very special.
  
  Yes, I'm trying to wrap my head around it all.
  And is there hotplug support there on real hardware?
 
 I quite frankly don't know. Frank?

yes there is, but it might be different than you expect from traditional
PCI :-)
 
  You can't plug in
  anything that does not come from IBM. There are no PCIe connectors -
  instead you have IBM proprietary slots that only work with IBM approved
  devices. So things like we can plug in a PCI bridge simply don't work
  as well in that world.
 
 
  Alex
  
  But interestingly, the usage example that Frank gave actually shows
  e1000 and other non-IBM cards apparently working?
  This kind of confuses me.
Sorry, I just use e1000 to give an example everybody can follow. Here is
the actual

Re: [Qemu-devel] [PATCH 2/2 RFC] s390x/pci: rework pci infrastructure modeling

2015-03-12 Thread Frank Blaschka
On Wed, Mar 11, 2015 at 03:57:05PM +0100, Michael S. Tsirkin wrote:
 On Wed, Mar 11, 2015 at 03:38:44PM +0100, Frank Blaschka wrote:
  I like Alex's idea because:
  1) It reflects pretty well the actual nature of the pci system in real s390 
  hw
 
 why do you say this? does real hw has this
 one device per bridge limit?
 
Actually we don't know. HW does not expose this information. All we know is each
pci function is completely separated. So it is a good assumption to have a 
separate
bridge/bus for each pci function. By the way the Linux kernel for s390 makes the
same assumption by creating a new pci domain for each function. You may want
to read the cover letter again to get more technical details on this.




Re: [Qemu-devel] [PATCH 2/2 RFC] s390x/pci: rework pci infrastructure modeling

2015-03-12 Thread Frank Blaschka
On Thu, Mar 12, 2015 at 11:03:50AM +0100, Michael S. Tsirkin wrote:
 On Thu, Mar 12, 2015 at 10:54:24AM +0100, Frank Blaschka wrote:
  On Wed, Mar 11, 2015 at 06:42:34PM +0100, Michael S. Tsirkin wrote:
   On Wed, Mar 11, 2015 at 03:38:44PM +0100, Frank Blaschka wrote:
On Tue, Mar 10, 2015 at 03:26:23PM +0100, Michael S. Tsirkin wrote:
 On Tue, Mar 10, 2015 at 02:03:34PM +0100, Frank Blaschka wrote:
  This patch changes the modeling of the s390 qemu pci infrastructure 
  to
  better match the actual pci architecture defined by the real 
  hardware.
  
  A pci host bridge like device (s390-pcihost) models the abstract 
  view
  of the bare pci function. It provides s390 specific configuration
  attributes (fid and uid) for the attached pci device. The host 
  bridge
  restrict the pci bus to just hold one single pci device. Also we 
  have
  to make the s390 pci host bridge hot plugable.
 
 This requirement is really because of the 1 device per bus
 limitation, isn't it?
 If you supported many devices per bus, you could use
 hotplug there and there won't be need to support hotplug
 of the host bridge.

Absolutely yes. Have you seen my first proposal?
It basically exploits the normal pci bridge/bus/slot mechanism but need
a place to store s390 specific configuration attributes.
   
The idea of a host bridge having this attributes and limit the bus
to one slot was an alternate design approach suggested by Alex.

I like Alex's idea because:
1) It reflects pretty well the actual nature of the pci system in real 
s390 hw
2) It does not create an somehow artifical pci topology

   
   I'll have to re-read but here's a thought: use your patch but
   remove host bridge hotplug support code.
   Stick a standard bridge with shpc support in the single slot
   behind your host bridge (existing pci-bridge-dev should do the trick,
   though not many people use it, so you might
   run into bugs, but fixing them is a good idea anyway).
   You can instanciate it automatically like Marcel's patches do
   for PXB.
  Still don't undertsand so I try to summarize in my words please corrent me
  if I got something wrong
  
  - create a standard host bridge
  - change the s390-pcihost to be a pci 2 pci bridge
 
 Actually I suggested simply adding a pci 2 pci bridge behind
 s390-pcihost.
 
  - now we can hotplug the s390-pcihost + hotplug a pci device to this
s390-pcihost using standard pci hotplug mechanism
 
 My idea was to just hotplug a pci device behind the standard pci 2 pci
 bridge. don't support hotplugging bridge itself or s390-pcihost itself.
 
  - we keep the 1 slot limit on the s390-pcihost. We need a place to
store fid and uid information (see mail thread from my 1 proposal)
 
 Yes.
 
  - If we need more than 32 pci functions we have to extend the primary pci 
  bus
via standart pci 2 pci bridges or add another standart host bridge
  
  Is this your suggestion?
 
 Almost, clarifications above.

OK, got your idea. Have to think about it and may do some prototyping. THX!
 
   
   You get hotplug + multiple devices for free.
   
   And the resulting topology is clearly something that *can* exist
   on bare-metal, since no one can prevent users sticking
   a pci bridge device in a pci slot.
  
  Again on bar s390 metal we do not have bridge bus slot at all.
  OS does not have any knowledge about it. So anything we try to model
  is somehow artificial.
 
 So I wonder: what does guest see if you do it like the above in QEMU?
 Do s390 guests even have ability to enumerate pci to pci bridges?
I think the answer is no. All a s390 guest can do is call a s390 
instruction to get a list of pci functions. There is no further
information about the function. The fact there might be a bridge/bus/slot
is completely abstracted in hw and not exposed to the OS.

I think the fact, the hw guaranties a pci function is completetly
independent, made the kernel folks to decide to enumarate the domain.
Looking at a pci address on the guest (or in general on s390 kernel)
you will never see a bus or slot != 0 (:00:00.0)

Anyhow what we are doing do model pci in qemu, the guest will only see
a list of pci functions and enumerate the domain to create a pci
address and that's it 

 
   
   Why do I prefer pci hotplug to s390 hotplug?
   s390 hotplug is really surprise removal. There's no way
  
  Don't understand this neither. s390 linux kernel is well prepared
  to receive s390 specific events to signal a pci function is
  going away. Anyhow we end up I can generate this events
  
   to get ack from guest. Linux isn't very well equipped to
   handle that, we might be able to fix it with time but current
   virtio drivers aren't very happy.
   
 
  This is done by
  implementing a s390 specific bus to attach this new host bridge like
  devices.
  
  Sample qemu configuration

Re: [Qemu-devel] [PATCH 2/2 RFC] s390x/pci: rework pci infrastructure modeling

2015-03-12 Thread Frank Blaschka
On Wed, Mar 11, 2015 at 06:42:34PM +0100, Michael S. Tsirkin wrote:
 On Wed, Mar 11, 2015 at 03:38:44PM +0100, Frank Blaschka wrote:
  On Tue, Mar 10, 2015 at 03:26:23PM +0100, Michael S. Tsirkin wrote:
   On Tue, Mar 10, 2015 at 02:03:34PM +0100, Frank Blaschka wrote:
This patch changes the modeling of the s390 qemu pci infrastructure to
better match the actual pci architecture defined by the real hardware.

A pci host bridge like device (s390-pcihost) models the abstract view
of the bare pci function. It provides s390 specific configuration
attributes (fid and uid) for the attached pci device. The host bridge
restrict the pci bus to just hold one single pci device. Also we have
to make the s390 pci host bridge hot plugable.
   
   This requirement is really because of the 1 device per bus
   limitation, isn't it?
   If you supported many devices per bus, you could use
   hotplug there and there won't be need to support hotplug
   of the host bridge.
  
  Absolutely yes. Have you seen my first proposal?
  It basically exploits the normal pci bridge/bus/slot mechanism but need
  a place to store s390 specific configuration attributes.
 
  The idea of a host bridge having this attributes and limit the bus
  to one slot was an alternate design approach suggested by Alex.
  
  I like Alex's idea because:
  1) It reflects pretty well the actual nature of the pci system in real s390 
  hw
  2) It does not create an somehow artifical pci topology
  
 
 I'll have to re-read but here's a thought: use your patch but
 remove host bridge hotplug support code.
 Stick a standard bridge with shpc support in the single slot
 behind your host bridge (existing pci-bridge-dev should do the trick,
 though not many people use it, so you might
 run into bugs, but fixing them is a good idea anyway).
 You can instanciate it automatically like Marcel's patches do
 for PXB.
Still don't undertsand so I try to summarize in my words please corrent me
if I got something wrong

- create a standard host bridge
- change the s390-pcihost to be a pci 2 pci bridge
- now we can hotplug the s390-pcihost + hotplug a pci device to this
  s390-pcihost using standard pci hotplug mechanism
- we keep the 1 slot limit on the s390-pcihost. We need a place to
  store fid and uid information (see mail thread from my 1 proposal)
- If we need more than 32 pci functions we have to extend the primary pci bus
  via standart pci 2 pci bridges or add another standart host bridge

Is this your suggestion?

 
 You get hotplug + multiple devices for free.
 
 And the resulting topology is clearly something that *can* exist
 on bare-metal, since no one can prevent users sticking
 a pci bridge device in a pci slot.

Again on bar s390 metal we do not have bridge bus slot at all.
OS does not have any knowledge about it. So anything we try to model
is somehow artificial.

 
 Why do I prefer pci hotplug to s390 hotplug?
 s390 hotplug is really surprise removal. There's no way

Don't understand this neither. s390 linux kernel is well prepared
to receive s390 specific events to signal a pci function is
going away. Anyhow we end up I can generate this events

 to get ack from guest. Linux isn't very well equipped to
 handle that, we might be able to fix it with time but current
 virtio drivers aren't very happy.
 
   
This is done by
implementing a s390 specific bus to attach this new host bridge like
devices.

Sample qemu configuration:
-device s390-pcihost,fid=16,uid=2216
-device e1000,bus=pci.0
-device s390-pcihost,fid=17,uid=2217,id=mydev
-device ne2k_pci,bus=mydev.0,addr=0

A pci device references the corresponding host bridge via pci bus name
(as usual). The pci device must be attached to slot 0 of the bus.
   
The fid and uid must be unique for the qemu instance. The design
allows to define (static and hotplug) multiple host bridges and support
a large number of pci devices.
   
   How about sticking a pci to pci bridge behind the host bridge?
   You could also support hotplug using shpc, all
   this without writing code.
   
  Hm, I don't understand this in detail, can you elaborate a little bit more
  on this?
  
  For me it looks like this has the same issues like my first proposal. We
  build a complete artifical pci topology in qemu, which has nothing to do 
  with
  the real hw. If we include pci 2 pci bridges this makes configuration even
  more a nightmare for users.
  
  Do you think detangle pci bus from bridge breaks some fundamental design?
  If so, I would rather go with my first proposal than adding even more
  complexity to implementation and configuration.
  
  Thx, Frank
   
Signed-off-by: Frank Blaschka blasc...@linux.vnet.ibm.com
---
 hw/s390x/s390-pci-bus.c| 174 
++---
 hw/s390x/s390-pci-bus.h|  24 ++-
 hw/s390x/s390-pci-inst.c   |   2 +-
 hw/s390x/s390-virtio-ccw.c |   4

Re: [Qemu-devel] [PATCH 2/2 RFC] s390x/pci: rework pci infrastructure modeling

2015-03-12 Thread Frank Blaschka
On Thu, Mar 12, 2015 at 11:50:02AM +0100, Frank Blaschka wrote:
 On Thu, Mar 12, 2015 at 11:03:50AM +0100, Michael S. Tsirkin wrote:
  On Thu, Mar 12, 2015 at 10:54:24AM +0100, Frank Blaschka wrote:
   On Wed, Mar 11, 2015 at 06:42:34PM +0100, Michael S. Tsirkin wrote:
On Wed, Mar 11, 2015 at 03:38:44PM +0100, Frank Blaschka wrote:
 On Tue, Mar 10, 2015 at 03:26:23PM +0100, Michael S. Tsirkin wrote:
  On Tue, Mar 10, 2015 at 02:03:34PM +0100, Frank Blaschka wrote:
   This patch changes the modeling of the s390 qemu pci 
   infrastructure to
   better match the actual pci architecture defined by the real 
   hardware.
   
   A pci host bridge like device (s390-pcihost) models the abstract 
   view
   of the bare pci function. It provides s390 specific configuration
   attributes (fid and uid) for the attached pci device. The host 
   bridge
   restrict the pci bus to just hold one single pci device. Also we 
   have
   to make the s390 pci host bridge hot plugable.
  
  This requirement is really because of the 1 device per bus
  limitation, isn't it?
  If you supported many devices per bus, you could use
  hotplug there and there won't be need to support hotplug
  of the host bridge.
 
 Absolutely yes. Have you seen my first proposal?
 It basically exploits the normal pci bridge/bus/slot mechanism but 
 need
 a place to store s390 specific configuration attributes.

 The idea of a host bridge having this attributes and limit the bus
 to one slot was an alternate design approach suggested by Alex.
 
 I like Alex's idea because:
 1) It reflects pretty well the actual nature of the pci system in 
 real s390 hw
 2) It does not create an somehow artifical pci topology
 

I'll have to re-read but here's a thought: use your patch but
remove host bridge hotplug support code.
Stick a standard bridge with shpc support in the single slot
behind your host bridge (existing pci-bridge-dev should do the trick,
though not many people use it, so you might
run into bugs, but fixing them is a good idea anyway).
You can instanciate it automatically like Marcel's patches do
for PXB.
   Still don't undertsand so I try to summarize in my words please corrent me
   if I got something wrong
   
   - create a standard host bridge
   - change the s390-pcihost to be a pci 2 pci bridge
  
  Actually I suggested simply adding a pci 2 pci bridge behind
  s390-pcihost.
  
   - now we can hotplug the s390-pcihost + hotplug a pci device to this
 s390-pcihost using standard pci hotplug mechanism
  
  My idea was to just hotplug a pci device behind the standard pci 2 pci
  bridge. don't support hotplugging bridge itself or s390-pcihost itself.
  
   - we keep the 1 slot limit on the s390-pcihost. We need a place to
 store fid and uid information (see mail thread from my 1 proposal)
  
  Yes.
  
   - If we need more than 32 pci functions we have to extend the primary pci 
   bus
 via standart pci 2 pci bridges or add another standart host bridge
   
   Is this your suggestion?
  
  Almost, clarifications above.
 
 OK, got your idea. Have to think about it and may do some prototyping. THX!


hm, after thinking more about this I realized this is not working for us.
Remember we need a place to store the fid and uid attributes. This place
must be:
1) uid/fid per pci device
2) uid/fid in a hotplugable device

I have the feeling we are at the beginning again. Although I liked Alex's
idea (host bridge containing uid/fid and having only 1 slot on the bus), it
looks like we end up at my first proposal. This does not require any
modification in base pci/bus code.

Thx to all of you for the discussion and suggestions.


You get hotplug + multiple devices for free.

And the resulting topology is clearly something that *can* exist
on bare-metal, since no one can prevent users sticking
a pci bridge device in a pci slot.
   
   Again on bar s390 metal we do not have bridge bus slot at all.
   OS does not have any knowledge about it. So anything we try to model
   is somehow artificial.
  
  So I wonder: what does guest see if you do it like the above in QEMU?
  Do s390 guests even have ability to enumerate pci to pci bridges?
 I think the answer is no. All a s390 guest can do is call a s390 
 instruction to get a list of pci functions. There is no further
 information about the function. The fact there might be a bridge/bus/slot
 is completely abstracted in hw and not exposed to the OS.
 
 I think the fact, the hw guaranties a pci function is completetly
 independent, made the kernel folks to decide to enumarate the domain.
 Looking at a pci address on the guest (or in general on s390 kernel)
 you will never see a bus or slot != 0 (:00:00.0)
 
 Anyhow what we are doing do model pci in qemu, the guest will only see
 a list of pci functions

Re: [Qemu-devel] [PATCH 2/2 RFC] s390x/pci: rework pci infrastructure modeling

2015-03-11 Thread Frank Blaschka
On Tue, Mar 10, 2015 at 03:26:23PM +0100, Michael S. Tsirkin wrote:
 On Tue, Mar 10, 2015 at 02:03:34PM +0100, Frank Blaschka wrote:
  This patch changes the modeling of the s390 qemu pci infrastructure to
  better match the actual pci architecture defined by the real hardware.
  
  A pci host bridge like device (s390-pcihost) models the abstract view
  of the bare pci function. It provides s390 specific configuration
  attributes (fid and uid) for the attached pci device. The host bridge
  restrict the pci bus to just hold one single pci device. Also we have
  to make the s390 pci host bridge hot plugable.
 
 This requirement is really because of the 1 device per bus
 limitation, isn't it?
 If you supported many devices per bus, you could use
 hotplug there and there won't be need to support hotplug
 of the host bridge.

Absolutely yes. Have you seen my first proposal?
It basically exploits the normal pci bridge/bus/slot mechanism but need
a place to store s390 specific configuration attributes.
The idea of a host bridge having this attributes and limit the bus
to one slot was an alternate design approach suggested by Alex.

I like Alex's idea because:
1) It reflects pretty well the actual nature of the pci system in real s390 hw
2) It does not create an somehow artifical pci topology

 
  This is done by
  implementing a s390 specific bus to attach this new host bridge like
  devices.
  
  Sample qemu configuration:
  -device s390-pcihost,fid=16,uid=2216
  -device e1000,bus=pci.0
  -device s390-pcihost,fid=17,uid=2217,id=mydev
  -device ne2k_pci,bus=mydev.0,addr=0
  
  A pci device references the corresponding host bridge via pci bus name
  (as usual). The pci device must be attached to slot 0 of the bus.
 
  The fid and uid must be unique for the qemu instance. The design
  allows to define (static and hotplug) multiple host bridges and support
  a large number of pci devices.
 
 How about sticking a pci to pci bridge behind the host bridge?
 You could also support hotplug using shpc, all
 this without writing code.
 
Hm, I don't understand this in detail, can you elaborate a little bit more
on this?

For me it looks like this has the same issues like my first proposal. We
build a complete artifical pci topology in qemu, which has nothing to do with
the real hw. If we include pci 2 pci bridges this makes configuration even
more a nightmare for users.

Do you think detangle pci bus from bridge breaks some fundamental design?
If so, I would rather go with my first proposal than adding even more
complexity to implementation and configuration.

Thx, Frank
 
  Signed-off-by: Frank Blaschka blasc...@linux.vnet.ibm.com
  ---
   hw/s390x/s390-pci-bus.c| 174 
  ++---
   hw/s390x/s390-pci-bus.h|  24 ++-
   hw/s390x/s390-pci-inst.c   |   2 +-
   hw/s390x/s390-virtio-ccw.c |   4 +-
   4 files changed, 128 insertions(+), 76 deletions(-)
  
  diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
  index dc455a2..6ad80d9 100644
  --- a/hw/s390x/s390-pci-bus.c
  +++ b/hw/s390x/s390-pci-bus.c
  @@ -32,12 +32,8 @@ int chsc_sei_nt2_get_event(void *res)
   PciCcdfErr *eccdf;
   int rc = 1;
   SeiContainer *sei_cont;
  -S390pciState *s = S390_PCI_HOST_BRIDGE(
  -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
  -
  -if (!s) {
  -return rc;
  -}
  +PCIFacility *s = PCI_FACILITY(
  +object_resolve_path(TYPE_PCI_FACILITY, NULL));
   
   sei_cont = QTAILQ_FIRST(s-pending_sei);
   if (sei_cont) {
  @@ -71,31 +67,23 @@ int chsc_sei_nt2_get_event(void *res)
   
   int chsc_sei_nt2_have_event(void)
   {
  -S390pciState *s = S390_PCI_HOST_BRIDGE(
  -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
  -
  -if (!s) {
  -return 0;
  -}
  +PCIFacility *s = PCI_FACILITY(
  +object_resolve_path(TYPE_PCI_FACILITY, NULL));
   
   return !QTAILQ_EMPTY(s-pending_sei);
   }
   
   S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid)
   {
  -S390PCIBusDevice *pbdev;
  -int i;
  -S390pciState *s = S390_PCI_HOST_BRIDGE(
  -object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
  +BusChild *kid;
  +S390pciState *state;
  +PCIFacility *s = PCI_FACILITY(
  +object_resolve_path(TYPE_PCI_FACILITY, NULL));
   
  -if (!s) {
  -return NULL;
  -}
  -
  -for (i = 0; i  PCI_SLOT_MAX; i++) {
  -pbdev = s-pbdev[i];
  -if ((pbdev-fh != 0)  (pbdev-fid == fid)) {
  -return pbdev;
  +QTAILQ_FOREACH(kid, s-sbus.qbus.children, sibling) {
  +state = (S390pciState *)kid-child;
  +if ((state-pbdev[0].fh != 0)  (state-pbdev[0].fid == fid)) {
  +return state-pbdev[0];
   }
   }
   
  @@ -125,37 +113,23 @@ void s390_pci_sclp_configure(int configure, SCCB 
  *sccb)
   return;
   }
   
  -static uint32_t s390_pci_get_pfid(PCIDevice *pdev)
  -{
  -return

[Qemu-devel] [PATCH 2/2 RFC] s390x/pci: rework pci infrastructure modeling

2015-03-10 Thread Frank Blaschka
This patch changes the modeling of the s390 qemu pci infrastructure to
better match the actual pci architecture defined by the real hardware.

A pci host bridge like device (s390-pcihost) models the abstract view
of the bare pci function. It provides s390 specific configuration
attributes (fid and uid) for the attached pci device. The host bridge
restrict the pci bus to just hold one single pci device. Also we have
to make the s390 pci host bridge hot plugable. This is done by
implementing a s390 specific bus to attach this new host bridge like
devices.

Sample qemu configuration:
-device s390-pcihost,fid=16,uid=2216
-device e1000,bus=pci.0
-device s390-pcihost,fid=17,uid=2217,id=mydev
-device ne2k_pci,bus=mydev.0,addr=0

A pci device references the corresponding host bridge via pci bus name
(as usual). The pci device must be attached to slot 0 of the bus.
The fid and uid must be unique for the qemu instance. The design
allows to define (static and hotplug) multiple host bridges and support
a large number of pci devices.

Signed-off-by: Frank Blaschka blasc...@linux.vnet.ibm.com
---
 hw/s390x/s390-pci-bus.c| 174 ++---
 hw/s390x/s390-pci-bus.h|  24 ++-
 hw/s390x/s390-pci-inst.c   |   2 +-
 hw/s390x/s390-virtio-ccw.c |   4 +-
 4 files changed, 128 insertions(+), 76 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index dc455a2..6ad80d9 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -32,12 +32,8 @@ int chsc_sei_nt2_get_event(void *res)
 PciCcdfErr *eccdf;
 int rc = 1;
 SeiContainer *sei_cont;
-S390pciState *s = S390_PCI_HOST_BRIDGE(
-object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
-
-if (!s) {
-return rc;
-}
+PCIFacility *s = PCI_FACILITY(
+object_resolve_path(TYPE_PCI_FACILITY, NULL));
 
 sei_cont = QTAILQ_FIRST(s-pending_sei);
 if (sei_cont) {
@@ -71,31 +67,23 @@ int chsc_sei_nt2_get_event(void *res)
 
 int chsc_sei_nt2_have_event(void)
 {
-S390pciState *s = S390_PCI_HOST_BRIDGE(
-object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
-
-if (!s) {
-return 0;
-}
+PCIFacility *s = PCI_FACILITY(
+object_resolve_path(TYPE_PCI_FACILITY, NULL));
 
 return !QTAILQ_EMPTY(s-pending_sei);
 }
 
 S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid)
 {
-S390PCIBusDevice *pbdev;
-int i;
-S390pciState *s = S390_PCI_HOST_BRIDGE(
-object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
+BusChild *kid;
+S390pciState *state;
+PCIFacility *s = PCI_FACILITY(
+object_resolve_path(TYPE_PCI_FACILITY, NULL));
 
-if (!s) {
-return NULL;
-}
-
-for (i = 0; i  PCI_SLOT_MAX; i++) {
-pbdev = s-pbdev[i];
-if ((pbdev-fh != 0)  (pbdev-fid == fid)) {
-return pbdev;
+QTAILQ_FOREACH(kid, s-sbus.qbus.children, sibling) {
+state = (S390pciState *)kid-child;
+if ((state-pbdev[0].fh != 0)  (state-pbdev[0].fid == fid)) {
+return state-pbdev[0];
 }
 }
 
@@ -125,37 +113,23 @@ void s390_pci_sclp_configure(int configure, SCCB *sccb)
 return;
 }
 
-static uint32_t s390_pci_get_pfid(PCIDevice *pdev)
-{
-return PCI_SLOT(pdev-devfn);
-}
-
-static uint32_t s390_pci_get_pfh(PCIDevice *pdev)
-{
-return PCI_SLOT(pdev-devfn) | FH_VIRT;
-}
-
 S390PCIBusDevice *s390_pci_find_dev_by_idx(uint32_t idx)
 {
-S390PCIBusDevice *pbdev;
-int i;
+BusChild *kid;
 int j = 0;
-S390pciState *s = S390_PCI_HOST_BRIDGE(
-object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
-
-if (!s) {
-return NULL;
-}
+S390pciState *state;
+PCIFacility *s = PCI_FACILITY(
+object_resolve_path(TYPE_PCI_FACILITY, NULL));
 
-for (i = 0; i  PCI_SLOT_MAX; i++) {
-pbdev = s-pbdev[i];
+QTAILQ_FOREACH(kid, s-sbus.qbus.children, sibling) {
+state = (S390pciState *)kid-child;
 
-if (pbdev-fh == 0) {
+if (state-pbdev[0].fh == 0) {
 continue;
 }
 
 if (j == idx) {
-return pbdev;
+return state-pbdev[0];
 }
 j++;
 }
@@ -165,19 +139,19 @@ S390PCIBusDevice *s390_pci_find_dev_by_idx(uint32_t idx)
 
 S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh)
 {
-S390PCIBusDevice *pbdev;
-int i;
-S390pciState *s = S390_PCI_HOST_BRIDGE(
-object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
+BusChild *kid;
+S390pciState *state;
+PCIFacility *s = PCI_FACILITY(
+object_resolve_path(TYPE_PCI_FACILITY, NULL));
 
-if (!s || !fh) {
+if (!fh) {
 return NULL;
 }
 
-for (i = 0; i  PCI_SLOT_MAX; i++) {
-pbdev = s-pbdev[i];
-if (pbdev-fh == fh) {
-return pbdev;
+QTAILQ_FOREACH(kid, s-sbus.qbus.children, sibling) {
+state = (S390pciState *)kid-child;
+if (state-pbdev[0].fh == fh

[Qemu-devel] [PATCH 1/2 RFC] pci: detangle Sysbus PCI bridge from PCIBus

2015-03-10 Thread Frank Blaschka
This patch detangle Sysbus PCI bridge from PCIBus. The pci host
bridge is derived from sysbus device and therefore it is not possible
to hotplug a host bridge. This change makes it possible to develop
hotplugable devices creating a pci bus on the fly.

Signed-off-by: Frank Blaschka blasc...@linux.vnet.ibm.com
---
 hw/pci/pci.c | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index cc5d946..553a130 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -253,9 +253,11 @@ static void pcibus_reset(BusState *qbus)
 
 static void pci_host_bus_register(PCIBus *bus, DeviceState *parent)
 {
-PCIHostState *host_bridge = PCI_HOST_BRIDGE(parent);
-
-QLIST_INSERT_HEAD(pci_host_bridges, host_bridge, next);
+PCIHostState *host_bridge = (PCIHostState *)object_dynamic_cast(
+OBJECT(parent), TYPE_PCI_HOST_BRIDGE);
+if (host_bridge) {
+QLIST_INSERT_HEAD(pci_host_bridges, host_bridge, next);
+}
 }
 
 PCIBus *pci_find_primary_bus(void)
@@ -288,14 +290,20 @@ PCIBus *pci_device_root_bus(const PCIDevice *d)
 const char *pci_root_bus_path(PCIDevice *dev)
 {
 PCIBus *rootbus = pci_device_root_bus(dev);
-PCIHostState *host_bridge = PCI_HOST_BRIDGE(rootbus-qbus.parent);
-PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_GET_CLASS(host_bridge);
+PCIHostState *host_bridge;
+PCIHostBridgeClass *hc;
+
+host_bridge = (PCIHostState *)object_dynamic_cast(
+  OBJECT(rootbus-qbus.parent), TYPE_PCI_HOST_BRIDGE);
 
 assert(!rootbus-parent_dev);
-assert(host_bridge-bus == rootbus);
 
-if (hc-root_bus_path) {
-return (*hc-root_bus_path)(host_bridge, rootbus);
+if (host_bridge) {
+assert(host_bridge-bus == rootbus);
+hc = PCI_HOST_BRIDGE_GET_CLASS(host_bridge);
+if (hc-root_bus_path) {
+return (*hc-root_bus_path)(host_bridge, rootbus);
+}
 }
 
 return rootbus-qbus.name;
-- 
2.1.4




[Qemu-devel] [PATCH 0/2 RFC] Extend s390 pci representation in qemu V2

2015-03-10 Thread Frank Blaschka
For a better understanding of the following patch here is
some general information about how PCI is implemented on the s390
platform. The physical structure of the pci system (bridge, bus, slot)
is not shown to the OS. Instead a firmware and I/O configuration
layer abstracts each PCI card to a bare PCI function.

In essence, the fw layer provides a simple enumeration of the
individual devices, which the s390 pci implementation in the Linux
kernel translates into individual pci domains.

HW layer  |   FW layer   |   Linux kernel
  |  |
(opaque)  |   function 1 |   0001:00:00.0
  |   function 2 |   0002:00:00.0
  |   function 3 |   0003:00:00.0

In qemu we have following problems:

(1) We have to represent this s390 specific topology information,
respectively the lack thereof
(2) We have/want to use common qemu PCI infrastructure

The initial implementation did not honor (1) much and tried to derive s390
specific configuration attributes from attributes of qemu pci devices. It
turns out that this is not flexible enough and is not sufficient to support
s390 specific configurations.

Here is some nice characterization about the nature of the s390 host bridge
(by Alexander Graf).

Conceptually your PCI bridge is not a sysbus device, since it doesn't
live on a flat MMIO + legacy IRQ routing bus. Instead, it lives on its
own thing that handles MMIO and IRQs via special backdoor interfaces.

The proposed solution is an outcome of a previous discussion here on the
qemu-devel mailing list.

The s390 patch tries to better model the pci infrastructure by
extending the s390 pci host bridge. Major changes are:

1) add configuration attributes (in reality provided by firmware layer) to
   the host bridge.
2) restrict pci bus of the bridge to just one slot
3) make a s390 host bridge hot plugable

Frank Blaschka (2):
  pci: detangle Sysbus PCI bridge from PCIBus
  s390x/pci: rework pci infrastructure modeling

 hw/pci/pci.c   |  24 ---
 hw/s390x/s390-pci-bus.c| 174 ++---
 hw/s390x/s390-pci-bus.h|  24 ++-
 hw/s390x/s390-pci-inst.c   |   2 +-
 hw/s390x/s390-virtio-ccw.c |   4 +-
 5 files changed, 144 insertions(+), 84 deletions(-)

-- 
2.1.4




Re: [Qemu-devel] [PATCH RFC 1/1] s390x/pci: Extend pci representation by new zpci device

2015-03-06 Thread Frank Blaschka
On Wed, Mar 04, 2015 at 04:58:25PM +0100, Frank Blaschka wrote:
 On Wed, Mar 04, 2015 at 04:25:07PM +0100, Alexander Graf wrote:
  
  
  On 04.03.15 16:07, Frank Blaschka wrote:
   On Wed, Mar 04, 2015 at 03:49:15PM +0100, Alexander Graf wrote:
  
  
   On 04.03.15 14:44, Frank Blaschka wrote:
   On Tue, Mar 03, 2015 at 09:38:37PM +0100, Alexander Graf wrote:
  
  
   On 03.03.15 14:25, Frank Blaschka wrote:
   On Tue, Mar 03, 2015 at 10:33:05AM +0100, Alexander Graf wrote:
  
  
  
   Am 03.03.2015 um 09:06 schrieb Frank Blaschka 
   blasc...@linux.vnet.ibm.com:
  
   On Thu, Feb 26, 2015 at 04:34:06PM +0100, Alexander Graf wrote:
  
  
   On 26.02.15 16:27, Frank Blaschka wrote:
   On Thu, Feb 26, 2015 at 03:39:15PM +0100, Alexander Graf wrote:
  
  
   On 26.02.15 12:59, Frank Blaschka wrote:
   This patch extends the current s390 pci implementation to
   provide more flexibility in configuration of s390 specific
   device handling. For this we had to introduce a new facility
   (and bus) to hold devices representing information actually
   provided by s390 firmware and I/O configuration.
  
   On s390 the physical structure of the pci system (bridge, bus, 
   slot)
   in not shown to the OS. For this the pci bridge and bus created
   in qemu can also not be shown to the guest. The new zpci device 
   class
   represents this abstract view on the bare pci function and 
   allows to
   provide s390 specific configuration attributes for it.
  
   Sample qemu configuration:
   -device e1000,id=zpci1
   -device ne2k_pci,id=zpci2
   -device zpci,fid=2,uid=1248,pci_id=zpci1
   -device zpci,fid=17,uid=2244,pci_id=zpci2
  
   A zpci device references the corresponding PCI device via 
   device id.
   The new design allows to define multiple host bridges and 
   support more
   pci devices.
  
   Isn't this reverse? Shouldn't it rather be
  
-device zpci,...,id=zpci1
-device e1000,bus=zpci1.0
  
   with a limit on each virtual zpci bus to only support one device?
  
   Do you mean something like having multiple host bridges 
   (providing a pci bus
   each) and limit the bus to just one device?
  
   -device s390-pcihost,fid=16,uid=1234
   -device s390-pcihost,fid=17,uid=5678
   -device e1000,bus=pci.0
   -device ne2k_pci,bus=pci.1
  
   We also discussed this option but we don't like the idea to put 
   attributes
   belong to the pci device to the host bridge.
  
   I guess I'm not grasping something obvious here :). What exactly 
   are the
   attributes again?
   Sorry for the late response, I was on vacation the last couple days.
  
   The fid and uid values are provided by microcode/io layer on the 
   real hardware.
  
   So they are arbitrary numbers? What uniqueness constraints do we 
   have on them?
   fid and uid must be unique within the same qemu. At a first look the 
   numbers are
   arbitrary but our configuration folks want explicitly define a 
   particular fid and uid
   to better support migration and pass-through scenarios.
  
   Well, at the end of the day you want to make sure they're identical on
   both sides, yes.
  
   IIUC you can only have a single pcie device behind a virtual bus 
   anyway, so what if we just calculate uid and fid from the bus id?
   I think this similar to the current implementation. We use the slot 
   (idea for the future was
   bus + slot) to generate uid and fid. But this is not flexible enough. 
   As I said, our
   configuration folks want to be able to specify fid and uid for the 
   device.
  
   I don't see how this is different from what PPC does with its LIOBN
   which is a property of the PHB.
  
  
   Alex
  
  
   I played arround with the idea of having multiple host bridges and this 
   worked well
   at least for static (non hotplug) configuration. In case I want to 
   hotplug a host
   bridge I got following error:
  
   (qemu) device_add s390-pcihost,fid=8,uid=9
   Bus 'main-system-bus' does not support hotplugging
  
   Is there anything I have to enable to support this?
  
   I have: has_dynamic_sysbus = 1 and 
   cannot_instantiate_with_device_add_yet = false
   but this seems not to help for the hotplug case.
  
   Having s390 devices reside on sysbus is probably a bad idea. Instead,
   they should be on an s390 specific bus which then can implement hotplug
   easily.
  
  
   Alex
  
   
   Hm now I get lost ...
   
   Do you suggest we should implement a s390 specific device (which is not 
   derived from
   TYPE_PCI_HOST_BRIDGE) but implements a pci bus so we can attach a pci 
   device to this
   device?  
  
  Ugh, PCI_HOST_BRIDGE is a sysbus device. Awesome.
  
  Conceptually your PCI bridge is not a sysbus device, since it doesn't
  live on a flat MMIO + legacy IRQ routing bus. Instead, it lives on its
  own thing that handles MMIO and IRQs via special backdoor interfaces.
 
 well spoken :-)
 
  How much of the PCI_HOST_BRIDGE device are you actually using? Would it
  be a lot of effort to have another s390 specific device

Re: [Qemu-devel] [PATCH RFC 1/1] s390x/pci: Extend pci representation by new zpci device

2015-03-04 Thread Frank Blaschka
On Wed, Mar 04, 2015 at 04:25:07PM +0100, Alexander Graf wrote:
 
 
 On 04.03.15 16:07, Frank Blaschka wrote:
  On Wed, Mar 04, 2015 at 03:49:15PM +0100, Alexander Graf wrote:
 
 
  On 04.03.15 14:44, Frank Blaschka wrote:
  On Tue, Mar 03, 2015 at 09:38:37PM +0100, Alexander Graf wrote:
 
 
  On 03.03.15 14:25, Frank Blaschka wrote:
  On Tue, Mar 03, 2015 at 10:33:05AM +0100, Alexander Graf wrote:
 
 
 
  Am 03.03.2015 um 09:06 schrieb Frank Blaschka 
  blasc...@linux.vnet.ibm.com:
 
  On Thu, Feb 26, 2015 at 04:34:06PM +0100, Alexander Graf wrote:
 
 
  On 26.02.15 16:27, Frank Blaschka wrote:
  On Thu, Feb 26, 2015 at 03:39:15PM +0100, Alexander Graf wrote:
 
 
  On 26.02.15 12:59, Frank Blaschka wrote:
  This patch extends the current s390 pci implementation to
  provide more flexibility in configuration of s390 specific
  device handling. For this we had to introduce a new facility
  (and bus) to hold devices representing information actually
  provided by s390 firmware and I/O configuration.
 
  On s390 the physical structure of the pci system (bridge, bus, 
  slot)
  in not shown to the OS. For this the pci bridge and bus created
  in qemu can also not be shown to the guest. The new zpci device 
  class
  represents this abstract view on the bare pci function and allows 
  to
  provide s390 specific configuration attributes for it.
 
  Sample qemu configuration:
  -device e1000,id=zpci1
  -device ne2k_pci,id=zpci2
  -device zpci,fid=2,uid=1248,pci_id=zpci1
  -device zpci,fid=17,uid=2244,pci_id=zpci2
 
  A zpci device references the corresponding PCI device via device 
  id.
  The new design allows to define multiple host bridges and support 
  more
  pci devices.
 
  Isn't this reverse? Shouldn't it rather be
 
   -device zpci,...,id=zpci1
   -device e1000,bus=zpci1.0
 
  with a limit on each virtual zpci bus to only support one device?
 
  Do you mean something like having multiple host bridges (providing 
  a pci bus
  each) and limit the bus to just one device?
 
  -device s390-pcihost,fid=16,uid=1234
  -device s390-pcihost,fid=17,uid=5678
  -device e1000,bus=pci.0
  -device ne2k_pci,bus=pci.1
 
  We also discussed this option but we don't like the idea to put 
  attributes
  belong to the pci device to the host bridge.
 
  I guess I'm not grasping something obvious here :). What exactly are 
  the
  attributes again?
  Sorry for the late response, I was on vacation the last couple days.
 
  The fid and uid values are provided by microcode/io layer on the real 
  hardware.
 
  So they are arbitrary numbers? What uniqueness constraints do we have 
  on them?
  fid and uid must be unique within the same qemu. At a first look the 
  numbers are
  arbitrary but our configuration folks want explicitly define a 
  particular fid and uid
  to better support migration and pass-through scenarios.
 
  Well, at the end of the day you want to make sure they're identical on
  both sides, yes.
 
  IIUC you can only have a single pcie device behind a virtual bus 
  anyway, so what if we just calculate uid and fid from the bus id?
  I think this similar to the current implementation. We use the slot 
  (idea for the future was
  bus + slot) to generate uid and fid. But this is not flexible enough. 
  As I said, our
  configuration folks want to be able to specify fid and uid for the 
  device.
 
  I don't see how this is different from what PPC does with its LIOBN
  which is a property of the PHB.
 
 
  Alex
 
 
  I played arround with the idea of having multiple host bridges and this 
  worked well
  at least for static (non hotplug) configuration. In case I want to 
  hotplug a host
  bridge I got following error:
 
  (qemu) device_add s390-pcihost,fid=8,uid=9
  Bus 'main-system-bus' does not support hotplugging
 
  Is there anything I have to enable to support this?
 
  I have: has_dynamic_sysbus = 1 and cannot_instantiate_with_device_add_yet 
  = false
  but this seems not to help for the hotplug case.
 
  Having s390 devices reside on sysbus is probably a bad idea. Instead,
  they should be on an s390 specific bus which then can implement hotplug
  easily.
 
 
  Alex
 
  
  Hm now I get lost ...
  
  Do you suggest we should implement a s390 specific device (which is not 
  derived from
  TYPE_PCI_HOST_BRIDGE) but implements a pci bus so we can attach a pci 
  device to this
  device?  
 
 Ugh, PCI_HOST_BRIDGE is a sysbus device. Awesome.
 
 Conceptually your PCI bridge is not a sysbus device, since it doesn't
 live on a flat MMIO + legacy IRQ routing bus. Instead, it lives on its
 own thing that handles MMIO and IRQs via special backdoor interfaces.

well spoken :-)

 How much of the PCI_HOST_BRIDGE device are you actually using? Would it
 be a lot of effort to have another s390 specific device that exposes a
 PCIBus, but is not of type PCI_HOST_BRIDGE (and thus sysbus)?
 
I do not use much functionality of the PCI_HOST_BRIDGE but I was not able
to put a pci bus on a device != PCI_HOST_BRIDGE. If I recall

Re: [Qemu-devel] [PATCH RFC 1/1] s390x/pci: Extend pci representation by new zpci device

2015-03-04 Thread Frank Blaschka
On Tue, Mar 03, 2015 at 09:38:37PM +0100, Alexander Graf wrote:
 
 
 On 03.03.15 14:25, Frank Blaschka wrote:
  On Tue, Mar 03, 2015 at 10:33:05AM +0100, Alexander Graf wrote:
 
 
 
  Am 03.03.2015 um 09:06 schrieb Frank Blaschka 
  blasc...@linux.vnet.ibm.com:
 
  On Thu, Feb 26, 2015 at 04:34:06PM +0100, Alexander Graf wrote:
 
 
  On 26.02.15 16:27, Frank Blaschka wrote:
  On Thu, Feb 26, 2015 at 03:39:15PM +0100, Alexander Graf wrote:
 
 
  On 26.02.15 12:59, Frank Blaschka wrote:
  This patch extends the current s390 pci implementation to
  provide more flexibility in configuration of s390 specific
  device handling. For this we had to introduce a new facility
  (and bus) to hold devices representing information actually
  provided by s390 firmware and I/O configuration.
 
  On s390 the physical structure of the pci system (bridge, bus, slot)
  in not shown to the OS. For this the pci bridge and bus created
  in qemu can also not be shown to the guest. The new zpci device class
  represents this abstract view on the bare pci function and allows to
  provide s390 specific configuration attributes for it.
 
  Sample qemu configuration:
  -device e1000,id=zpci1
  -device ne2k_pci,id=zpci2
  -device zpci,fid=2,uid=1248,pci_id=zpci1
  -device zpci,fid=17,uid=2244,pci_id=zpci2
 
  A zpci device references the corresponding PCI device via device id.
  The new design allows to define multiple host bridges and support more
  pci devices.
 
  Isn't this reverse? Shouldn't it rather be
 
   -device zpci,...,id=zpci1
   -device e1000,bus=zpci1.0
 
  with a limit on each virtual zpci bus to only support one device?
 
  Do you mean something like having multiple host bridges (providing a 
  pci bus
  each) and limit the bus to just one device?
 
  -device s390-pcihost,fid=16,uid=1234
  -device s390-pcihost,fid=17,uid=5678
  -device e1000,bus=pci.0
  -device ne2k_pci,bus=pci.1
 
  We also discussed this option but we don't like the idea to put 
  attributes
  belong to the pci device to the host bridge.
 
  I guess I'm not grasping something obvious here :). What exactly are the
  attributes again?
  Sorry for the late response, I was on vacation the last couple days.
 
  The fid and uid values are provided by microcode/io layer on the real 
  hardware.
 
  So they are arbitrary numbers? What uniqueness constraints do we have on 
  them?
  fid and uid must be unique within the same qemu. At a first look the 
  numbers are
  arbitrary but our configuration folks want explicitly define a particular 
  fid and uid
  to better support migration and pass-through scenarios.
 
 Well, at the end of the day you want to make sure they're identical on
 both sides, yes.
 
  IIUC you can only have a single pcie device behind a virtual bus anyway, 
  so what if we just calculate uid and fid from the bus id?
  I think this similar to the current implementation. We use the slot (idea 
  for the future was
  bus + slot) to generate uid and fid. But this is not flexible enough. As I 
  said, our
  configuration folks want to be able to specify fid and uid for the device.
 
 I don't see how this is different from what PPC does with its LIOBN
 which is a property of the PHB.
 
 
 Alex
 

I played arround with the idea of having multiple host bridges and this worked 
well
at least for static (non hotplug) configuration. In case I want to hotplug a 
host
bridge I got following error:

(qemu) device_add s390-pcihost,fid=8,uid=9
Bus 'main-system-bus' does not support hotplugging

Is there anything I have to enable to support this?

I have: has_dynamic_sysbus = 1 and cannot_instantiate_with_device_add_yet = 
false
but this seems not to help for the hotplug case.

Frank




Re: [Qemu-devel] [PATCH RFC 1/1] s390x/pci: Extend pci representation by new zpci device

2015-03-04 Thread Frank Blaschka
On Wed, Mar 04, 2015 at 03:49:15PM +0100, Alexander Graf wrote:
 
 
 On 04.03.15 14:44, Frank Blaschka wrote:
  On Tue, Mar 03, 2015 at 09:38:37PM +0100, Alexander Graf wrote:
 
 
  On 03.03.15 14:25, Frank Blaschka wrote:
  On Tue, Mar 03, 2015 at 10:33:05AM +0100, Alexander Graf wrote:
 
 
 
  Am 03.03.2015 um 09:06 schrieb Frank Blaschka 
  blasc...@linux.vnet.ibm.com:
 
  On Thu, Feb 26, 2015 at 04:34:06PM +0100, Alexander Graf wrote:
 
 
  On 26.02.15 16:27, Frank Blaschka wrote:
  On Thu, Feb 26, 2015 at 03:39:15PM +0100, Alexander Graf wrote:
 
 
  On 26.02.15 12:59, Frank Blaschka wrote:
  This patch extends the current s390 pci implementation to
  provide more flexibility in configuration of s390 specific
  device handling. For this we had to introduce a new facility
  (and bus) to hold devices representing information actually
  provided by s390 firmware and I/O configuration.
 
  On s390 the physical structure of the pci system (bridge, bus, slot)
  in not shown to the OS. For this the pci bridge and bus created
  in qemu can also not be shown to the guest. The new zpci device 
  class
  represents this abstract view on the bare pci function and allows to
  provide s390 specific configuration attributes for it.
 
  Sample qemu configuration:
  -device e1000,id=zpci1
  -device ne2k_pci,id=zpci2
  -device zpci,fid=2,uid=1248,pci_id=zpci1
  -device zpci,fid=17,uid=2244,pci_id=zpci2
 
  A zpci device references the corresponding PCI device via device id.
  The new design allows to define multiple host bridges and support 
  more
  pci devices.
 
  Isn't this reverse? Shouldn't it rather be
 
   -device zpci,...,id=zpci1
   -device e1000,bus=zpci1.0
 
  with a limit on each virtual zpci bus to only support one device?
 
  Do you mean something like having multiple host bridges (providing a 
  pci bus
  each) and limit the bus to just one device?
 
  -device s390-pcihost,fid=16,uid=1234
  -device s390-pcihost,fid=17,uid=5678
  -device e1000,bus=pci.0
  -device ne2k_pci,bus=pci.1
 
  We also discussed this option but we don't like the idea to put 
  attributes
  belong to the pci device to the host bridge.
 
  I guess I'm not grasping something obvious here :). What exactly are 
  the
  attributes again?
  Sorry for the late response, I was on vacation the last couple days.
 
  The fid and uid values are provided by microcode/io layer on the real 
  hardware.
 
  So they are arbitrary numbers? What uniqueness constraints do we have on 
  them?
  fid and uid must be unique within the same qemu. At a first look the 
  numbers are
  arbitrary but our configuration folks want explicitly define a particular 
  fid and uid
  to better support migration and pass-through scenarios.
 
  Well, at the end of the day you want to make sure they're identical on
  both sides, yes.
 
  IIUC you can only have a single pcie device behind a virtual bus 
  anyway, so what if we just calculate uid and fid from the bus id?
  I think this similar to the current implementation. We use the slot (idea 
  for the future was
  bus + slot) to generate uid and fid. But this is not flexible enough. As 
  I said, our
  configuration folks want to be able to specify fid and uid for the device.
 
  I don't see how this is different from what PPC does with its LIOBN
  which is a property of the PHB.
 
 
  Alex
 
  
  I played arround with the idea of having multiple host bridges and this 
  worked well
  at least for static (non hotplug) configuration. In case I want to hotplug 
  a host
  bridge I got following error:
  
  (qemu) device_add s390-pcihost,fid=8,uid=9
  Bus 'main-system-bus' does not support hotplugging
  
  Is there anything I have to enable to support this?
  
  I have: has_dynamic_sysbus = 1 and cannot_instantiate_with_device_add_yet = 
  false
  but this seems not to help for the hotplug case.
 
 Having s390 devices reside on sysbus is probably a bad idea. Instead,
 they should be on an s390 specific bus which then can implement hotplug
 easily.
 
 
 Alex


Hm now I get lost ...

Do you suggest we should implement a s390 specific device (which is not derived 
from
TYPE_PCI_HOST_BRIDGE) but implements a pci bus so we can attach a pci device to 
this
device?  




Re: [Qemu-devel] [PATCH RFC 1/1] s390x/pci: Extend pci representation by new zpci device

2015-03-03 Thread Frank Blaschka
On Thu, Feb 26, 2015 at 04:34:06PM +0100, Alexander Graf wrote:
 
 
 On 26.02.15 16:27, Frank Blaschka wrote:
  On Thu, Feb 26, 2015 at 03:39:15PM +0100, Alexander Graf wrote:
 
 
  On 26.02.15 12:59, Frank Blaschka wrote:
  This patch extends the current s390 pci implementation to
  provide more flexibility in configuration of s390 specific
  device handling. For this we had to introduce a new facility
  (and bus) to hold devices representing information actually
  provided by s390 firmware and I/O configuration.
 
  On s390 the physical structure of the pci system (bridge, bus, slot)
  in not shown to the OS. For this the pci bridge and bus created
  in qemu can also not be shown to the guest. The new zpci device class
  represents this abstract view on the bare pci function and allows to
  provide s390 specific configuration attributes for it.
 
  Sample qemu configuration:
  -device e1000,id=zpci1
  -device ne2k_pci,id=zpci2
  -device zpci,fid=2,uid=1248,pci_id=zpci1
  -device zpci,fid=17,uid=2244,pci_id=zpci2
 
  A zpci device references the corresponding PCI device via device id.
  The new design allows to define multiple host bridges and support more
  pci devices.
 
  Isn't this reverse? Shouldn't it rather be
 
-device zpci,...,id=zpci1
-device e1000,bus=zpci1.0
 
  with a limit on each virtual zpci bus to only support one device?
  
  Do you mean something like having multiple host bridges (providing a pci bus
  each) and limit the bus to just one device?
  
  -device s390-pcihost,fid=16,uid=1234
  -device s390-pcihost,fid=17,uid=5678
  -device e1000,bus=pci.0
  -device ne2k_pci,bus=pci.1
  
  We also discussed this option but we don't like the idea to put attributes
  belong to the pci device to the host bridge.
 
 I guess I'm not grasping something obvious here :). What exactly are the
 attributes again?

Sorry for the late response, I was on vacation the last couple days.

The fid and uid values are provided by microcode/io layer on the real hardware.
You can read them out via s390 specific device attributes e.g.

# cat /sys/bus/pci/devices/\:00\:00.0/function_id
0x0016
# cat /sys/bus/pci/devices/\:00\:00.0/uid
0x25

Since there is no regular pci address (as explained earlier) I think this is a
mechanism to unique identify a pci function.

We discussed both options how to model this in qemu, but maybe you have another
even better idea how to bring this additional attributes to a qemu pci device.

Thx for any help and new ideas ...

Frank 
 
 Alex
 




Re: [Qemu-devel] [PATCH RFC 1/1] s390x/pci: Extend pci representation by new zpci device

2015-03-03 Thread Frank Blaschka
On Tue, Mar 03, 2015 at 10:33:05AM +0100, Alexander Graf wrote:
 
 
 
  Am 03.03.2015 um 09:06 schrieb Frank Blaschka blasc...@linux.vnet.ibm.com:
  
  On Thu, Feb 26, 2015 at 04:34:06PM +0100, Alexander Graf wrote:
  
  
  On 26.02.15 16:27, Frank Blaschka wrote:
  On Thu, Feb 26, 2015 at 03:39:15PM +0100, Alexander Graf wrote:
  
  
  On 26.02.15 12:59, Frank Blaschka wrote:
  This patch extends the current s390 pci implementation to
  provide more flexibility in configuration of s390 specific
  device handling. For this we had to introduce a new facility
  (and bus) to hold devices representing information actually
  provided by s390 firmware and I/O configuration.
  
  On s390 the physical structure of the pci system (bridge, bus, slot)
  in not shown to the OS. For this the pci bridge and bus created
  in qemu can also not be shown to the guest. The new zpci device class
  represents this abstract view on the bare pci function and allows to
  provide s390 specific configuration attributes for it.
  
  Sample qemu configuration:
  -device e1000,id=zpci1
  -device ne2k_pci,id=zpci2
  -device zpci,fid=2,uid=1248,pci_id=zpci1
  -device zpci,fid=17,uid=2244,pci_id=zpci2
  
  A zpci device references the corresponding PCI device via device id.
  The new design allows to define multiple host bridges and support more
  pci devices.
  
  Isn't this reverse? Shouldn't it rather be
  
   -device zpci,...,id=zpci1
   -device e1000,bus=zpci1.0
  
  with a limit on each virtual zpci bus to only support one device?
  
  Do you mean something like having multiple host bridges (providing a pci 
  bus
  each) and limit the bus to just one device?
  
  -device s390-pcihost,fid=16,uid=1234
  -device s390-pcihost,fid=17,uid=5678
  -device e1000,bus=pci.0
  -device ne2k_pci,bus=pci.1
  
  We also discussed this option but we don't like the idea to put attributes
  belong to the pci device to the host bridge.
  
  I guess I'm not grasping something obvious here :). What exactly are the
  attributes again?
  Sorry for the late response, I was on vacation the last couple days.
  
  The fid and uid values are provided by microcode/io layer on the real 
  hardware.
 
 So they are arbitrary numbers? What uniqueness constraints do we have on them?
fid and uid must be unique within the same qemu. At a first look the numbers are
arbitrary but our configuration folks want explicitly define a particular fid 
and uid
to better support migration and pass-through scenarios.
 
 IIUC you can only have a single pcie device behind a virtual bus anyway, so 
 what if we just calculate uid and fid from the bus id?
I think this similar to the current implementation. We use the slot (idea for 
the future was
bus + slot) to generate uid and fid. But this is not flexible enough. As I 
said, our
configuration folks want to be able to specify fid and uid for the device.

 
 Alex
 
  You can read them out via s390 specific device attributes e.g.
  
  # cat /sys/bus/pci/devices/\:00\:00.0/function_id
  0x0016
  # cat /sys/bus/pci/devices/\:00\:00.0/uid
  0x25
  
  Since there is no regular pci address (as explained earlier) I think this 
  is a
  mechanism to unique identify a pci function.
  
  We discussed both options how to model this in qemu, but maybe you have 
  another
  even better idea how to bring this additional attributes to a qemu pci 
  device.
  
  Thx for any help and new ideas ...
  
  Frank 
  
  Alex
  
 




[Qemu-devel] [PATCH RFC 0/1] Extend s390 pci representation in qemu

2015-02-26 Thread Frank Blaschka
For a better understanding of the following patch here is
some general information about how PCI is implemented on the s390
platform. The physical structure of the pci system (bridge, bus, slot)
is not shown to the OS. Instead a firmware and I/O configuration
layer abstracts each PCI card to a bare PCI function.

In essence, the fw layer provides a simple enumeration of the
individual devices, which the s390 pci implementation in the Linux
kernel translates into individual pci domains.

HW layer  |   FW layer   |   Linux kernel
  |  |
(opaque)  |   function 1 |   0001:00:00.0
  |   function 2 |   0002:00:00.0
  |   function 3 |   0003:00:00.0

In qemu we have following problems:

(1) We have to represent this s390 specific topology information,
respectively the lack thereof
(2) We have/want to use common qemu PCI infrastructure

The initial implementation did not honor (1) much and tried to derive s390
specific configuration attributes from attributes of qemu pci devices. It
turns out that this is not flexible enough and is not sufficient to support
s390 specific configurations.

The following patch introduces a new zPCI device that kind of represents the
fw layer on real hardware and provides the s390 specific information needed
by guest operating systems. We keep the pci devices the same as in the
general case and just hook them up with the corresponding zPCI device.

Frank Blaschka (1):
  s390x/pci: Extend pci representation by new zpci device

 hw/s390x/s390-pci-bus.c| 253 -
 hw/s390x/s390-pci-bus.h|  38 ++-
 hw/s390x/s390-pci-inst.c   |   2 +-
 hw/s390x/s390-virtio-ccw.c |   8 +-
 4 files changed, 227 insertions(+), 74 deletions(-)

-- 
2.1.4




[Qemu-devel] [PATCH V2] s390x/pci: avoid sign extension in stpcifc

2015-01-21 Thread Frank Blaschka
this patch avoids sign extension and fixes a data conversion
bug in stpcifc. Both issues where found by Coverity.

Signed-off-by: Frank Blaschka blasc...@linux.vnet.ibm.com
---
 hw/s390x/s390-pci-inst.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 5ea13e5..c269184 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -784,10 +784,10 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, 
uint64_t fiba)
 stq_p(fib.aisb, pbdev-routes.adapter.summary_addr);
 stq_p(fib.fmb_addr, pbdev-fmb_addr);
 
-data = (pbdev-isc  28) | (pbdev-noi  16) |
-   (pbdev-routes.adapter.ind_offset  8) | (pbdev-sum  7) |
-   pbdev-routes.adapter.summary_offset;
-stw_p(fib.data, data);
+data = ((uint32_t)pbdev-isc  28) | ((uint32_t)pbdev-noi  16) |
+   ((uint32_t)pbdev-routes.adapter.ind_offset  8) |
+   ((uint32_t)pbdev-sum  7) | pbdev-routes.adapter.summary_offset;
+stl_p(fib.data, data);
 
 if (pbdev-fh  ENABLE_BIT_OFFSET) {
 fib.fc |= 0x80;
-- 
2.1.4




[Qemu-devel] [PATCH] s390x/pci: avoid sign extension in stpcifc

2015-01-21 Thread Frank Blaschka
this patch avoids sign extension and fixes a data conversion
bug in stpcifc. Both issues where found by Coverity.

Signed-off-by: Frank Blaschka blasc...@linux.vnet.ibm.com
---
 hw/s390x/s390-pci-inst.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 5ea13e5..4d4015c 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -785,9 +785,9 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t 
fiba)
 stq_p(fib.fmb_addr, pbdev-fmb_addr);
 
 data = (pbdev-isc  28) | (pbdev-noi  16) |
-   (pbdev-routes.adapter.ind_offset  8) | (pbdev-sum  7) |
-   pbdev-routes.adapter.summary_offset;
-stw_p(fib.data, data);
+   ((uint32_t)pbdev-routes.adapter.ind_offset  8) |
+   (pbdev-sum  7) | pbdev-routes.adapter.summary_offset;
+stl_p(fib.data, data);
 
 if (pbdev-fh  ENABLE_BIT_OFFSET) {
 fib.fc |= 0x80;
-- 
2.1.4




Re: [Qemu-devel] [PATCH 2/3 V3] s390: implement pci instructions

2015-01-20 Thread Frank Blaschka
On Tue, Jan 20, 2015 at 01:56:09PM +0100, Markus Armbruster wrote:
 Markus Armbruster arm...@redhat.com writes:
 
  Cornelia Huck cornelia.h...@de.ibm.com writes:
 
  On Tue, 20 Jan 2015 10:45:41 +0100
  Markus Armbruster arm...@redhat.com wrote:
 
  This patch makes Coverity unhappy:
  
  *** CID 1264326:  Unintended sign extension  (SIGN_EXTENSION)
  /hw/s390x/s390-pci-inst.c: 787 in stpcifc_service_call()
  781 stq_p(fib.pal, pbdev-pal);
  782 stq_p(fib.iota, pbdev-g_iota);
  783 stq_p(fib.aibv, pbdev-routes.adapter.ind_addr);
  784 stq_p(fib.aisb, pbdev-routes.adapter.summary_addr);
  785 stq_p(fib.fmb_addr, pbdev-fmb_addr);
  786 
   CID 1264326:  Unintended sign extension  (SIGN_EXTENSION)
   Suspicious implicit sign extension: pbdev-isc with type
   unsigned char (8 bits, unsigned) is promoted in (pbdev-isc 
   28) | (pbdev-noi  16) to type int (32 bits, signed), then
   sign-extended to type unsigned long (64 bits, unsigned).  If
   (pbdev-isc  28) | (pbdev-noi  16) is greater than
   0x7FFF, the upper bits of the result will all be 1.
  787 data = (pbdev-isc  28) | (pbdev-noi  16) |
  788 (pbdev-routes.adapter.ind_offset  8) | (pbdev-sum  7) |
  789pbdev-routes.adapter.summary_offset;
  790 stw_p(fib.data, data);
  791 
  792 if (pbdev-fh  ENABLE_BIT_OFFSET) {
 
  There's a fix for this (and the memory leak):
 
  http://marc.info/?l=qemu-develm=142124886620078w=2
 
  The patch is sitting in my queue, will send with the next pile of s390x
  updates.
 
  I can't see how
 
  @@ -787,7 +787,7 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, 
  uint64_t fiba)
   data = (pbdev-isc  28) | (pbdev-noi  16) |
  (pbdev-routes.adapter.ind_offset  8) | (pbdev-sum  7) |
  pbdev-routes.adapter.summary_offset;
  -stw_p(fib.data, data);
  +stl_p(fib.data, data);
   
   if (pbdev-fh  ENABLE_BIT_OFFSET) {
   fib.fc |= 0x80;
 
  fixes the implicit sign extension within the assignment preceding it.
  Let me explain it again real slow:
 
  1. pbdev-isc gets promoted from uint8_t to int as operand of binary 
 (usual arithmetic conversions ISO/IEC 9899:1999 6.3.1.8)
 
  2. The int result is shifted left 28 bits.  This can set the MSB.
 
  3. Likewise: pbdev-noi gets promoted from uint64_t to int, and shifted
 left 16 bits.
uint16_t to int

 
  4. The two shift results stay int and get ored.
 
  5. pbdev-routes.adapter.ind_offset stays uint64_t, and is shifted left
 8 bits.
 
  6. The next or's left operand is the int result of 4 and the right
 operant is the uint64_t result of 5.  Therefore, the left operand is
 *sign-extended* from int to uint64_t.  This copies bit#7 of
 pbdev-isc to bits#31..63.  Whoops.
 
 I neglected to say: we don't currently use the upper 32 bits, and as
 long as we do that, the sign extension is harmless.  I'd recommend to
 avoid it all the same, for robustness, and to hush up Coverity.


Hi Markus,

thx for your explanation. I did not see a problem since ISC is not bigger
than 0x7 so MSB is never set. But the time I wrote the code I was not aware of
ind_offset is uint64_t since zpci defines only a 6 bit field for this value.

How can I avoid the sign extension and make Coverity happy?

  Regarding the leak, I prefer my patch, because it avoids the free on
  error.  But you're the maintainer.

This is fine for me as well ...

Thx,

Frank
 




[Qemu-devel] [PATCH] s390x/pci: fix 2 bugs found by coverity

2015-01-14 Thread Frank Blaschka
Signed-off-by: Frank Blaschka blasc...@linux.vnet.ibm.com
---
 hw/s390x/s390-pci-bus.c  | 1 +
 hw/s390x/s390-pci-inst.c | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 1201b8d..546dcf1 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -192,6 +192,7 @@ static void s390_pci_generate_event(uint8_t cc, uint16_t 
pec, uint32_t fh,
 object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
 
 if (!s) {
+g_free(sei_cont);
 return;
 }
 
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 5ea13e5..5596679 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -787,7 +787,7 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t 
fiba)
 data = (pbdev-isc  28) | (pbdev-noi  16) |
(pbdev-routes.adapter.ind_offset  8) | (pbdev-sum  7) |
pbdev-routes.adapter.summary_offset;
-stw_p(fib.data, data);
+stl_p(fib.data, data);
 
 if (pbdev-fh  ENABLE_BIT_OFFSET) {
 fib.fc |= 0x80;
-- 
2.1.4




[Qemu-devel] [PATCH 2/3 V3] s390: implement pci instructions

2015-01-09 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements the s390 pci instructions in qemu. It allows
to access and drive pci devices attached to the s390 pci bus.
Because of platform constrains devices using IO BARs are not
supported. Also a device has to support MSI/MSI-X to run on s390.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 hw/s390x/Makefile.objs   |   2 +-
 hw/s390x/s390-pci-inst.c | 811 +++
 hw/s390x/s390-pci-inst.h | 288 +
 target-s390x/kvm.c   | 153 +
 4 files changed, 1253 insertions(+), 1 deletion(-)
 create mode 100644 hw/s390x/s390-pci-inst.c
 create mode 100644 hw/s390x/s390-pci-inst.h

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 428d957..27cd75a 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -8,4 +8,4 @@ obj-y += ipl.o
 obj-y += css.o
 obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
-obj-y += s390-pci-bus.o
+obj-y += s390-pci-bus.o s390-pci-inst.o
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
new file mode 100644
index 000..d486cbb
--- /dev/null
+++ b/hw/s390x/s390-pci-inst.c
@@ -0,0 +1,811 @@
+/*
+ * s390 PCI instructions
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include s390-pci-inst.h
+#include s390-pci-bus.h
+#include exec/memory-internal.h
+#include qemu/error-report.h
+
+/* #define DEBUG_S390PCI_INST */
+#ifdef DEBUG_S390PCI_INST
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, s390pci-inst:  fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+static void s390_set_status_code(CPUS390XState *env,
+ uint8_t r, uint64_t status_code)
+{
+env-regs[r] = ~0xff00ULL;
+env-regs[r] |= (status_code  0xff)  24;
+}
+
+static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc)
+{
+S390PCIBusDevice *pbdev;
+uint32_t res_code, initial_l2, g_l2, finish;
+int rc, idx;
+uint64_t resume_token;
+
+rc = 0;
+if (lduw_p(rrb-request.hdr.len) != 32) {
+res_code = CLP_RC_LEN;
+rc = -EINVAL;
+goto out;
+}
+
+if ((ldl_p(rrb-request.fmt)  CLP_MASK_FMT) != 0) {
+res_code = CLP_RC_FMT;
+rc = -EINVAL;
+goto out;
+}
+
+if ((ldl_p(rrb-request.fmt)  ~CLP_MASK_FMT) != 0 ||
+ldq_p(rrb-request.reserved1) != 0 ||
+ldq_p(rrb-request.reserved2) != 0) {
+res_code = CLP_RC_RESNOT0;
+rc = -EINVAL;
+goto out;
+}
+
+resume_token = ldq_p(rrb-request.resume_token);
+
+if (resume_token) {
+pbdev = s390_pci_find_dev_by_idx(resume_token);
+if (!pbdev) {
+res_code = CLP_RC_LISTPCI_BADRT;
+rc = -EINVAL;
+goto out;
+}
+}
+
+if (lduw_p(rrb-response.hdr.len)  48) {
+res_code = CLP_RC_8K;
+rc = -EINVAL;
+goto out;
+}
+
+initial_l2 = lduw_p(rrb-response.hdr.len);
+if ((initial_l2 - LIST_PCI_HDR_LEN) % sizeof(ClpFhListEntry)
+!= 0) {
+res_code = CLP_RC_LEN;
+rc = -EINVAL;
+*cc = 3;
+goto out;
+}
+
+stl_p(rrb-response.fmt, 0);
+stq_p(rrb-response.reserved1, 0);
+stq_p(rrb-response.reserved2, 0);
+stl_p(rrb-response.mdd, FH_VIRT);
+stw_p(rrb-response.max_fn, PCI_MAX_FUNCTIONS);
+rrb-response.entry_size = sizeof(ClpFhListEntry);
+finish = 0;
+idx = resume_token;
+g_l2 = LIST_PCI_HDR_LEN;
+do {
+pbdev = s390_pci_find_dev_by_idx(idx);
+if (!pbdev) {
+finish = 1;
+break;
+}
+stw_p(rrb-response.fh_list[idx - resume_token].device_id,
+pci_get_word(pbdev-pdev-config + PCI_DEVICE_ID));
+stw_p(rrb-response.fh_list[idx - resume_token].vendor_id,
+pci_get_word(pbdev-pdev-config + PCI_VENDOR_ID));
+stl_p(rrb-response.fh_list[idx - resume_token].config, 0x8000);
+stl_p(rrb-response.fh_list[idx - resume_token].fid, pbdev-fid);
+stl_p(rrb-response.fh_list[idx - resume_token].fh, pbdev-fh);
+
+g_l2 += sizeof(ClpFhListEntry);
+/* Add endian check for DPRINTF? */
+DPRINTF(g_l2 %d vendor id 0x%x device id 0x%x fid 0x%x fh 0x%x\n,
+g_l2,
+lduw_p(rrb-response.fh_list[idx - resume_token].vendor_id),
+lduw_p(rrb-response.fh_list[idx - resume_token].device_id),
+ldl_p(rrb-response.fh_list[idx - resume_token].fid),
+ldl_p(rrb-response.fh_list[idx - resume_token].fh));
+idx++;
+} while (g_l2  initial_l2);
+
+if (finish == 1) {
+resume_token = 0

[Qemu-devel] [PATCH 3/3 V3] kvm: extend kvm_irqchip_add_msi_route to work on s390

2015-01-09 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

on s390 MSI-X irqs are presented as thin or adapter interrupts
for this we have to reorganize the routing entry to contain
valid information for the adapter interrupt code on s390.
To minimize impact on existing code we introduce an architecture
function to fixup the routing entry.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 include/sysemu/kvm.h |  4 
 kvm-all.c|  7 +++
 target-arm/kvm.c |  6 ++
 target-i386/kvm.c|  6 ++
 target-mips/kvm.c|  6 ++
 target-ppc/kvm.c |  6 ++
 target-s390x/kvm.c   | 26 ++
 7 files changed, 61 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 104cf35..30cb84d 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -158,6 +158,7 @@ extern bool kvm_readonly_mem_allowed;
 
 struct kvm_run;
 struct kvm_lapic_state;
+struct kvm_irq_routing_entry;
 
 typedef struct KVMCapabilityInfo {
 const char *name;
@@ -270,6 +271,9 @@ int kvm_arch_on_sigbus(int code, void *addr);
 
 void kvm_arch_init_irq_routing(KVMState *s);
 
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data);
+
 int kvm_set_irq(KVMState *s, int irq, int level);
 int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
 
diff --git a/kvm-all.c b/kvm-all.c
index 18cc6b4..2f21a4e 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1225,6 +1225,10 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage 
msg)
 kroute.u.msi.address_lo = (uint32_t)msg.address;
 kroute.u.msi.address_hi = msg.address  32;
 kroute.u.msi.data = le32_to_cpu(msg.data);
+if (kvm_arch_fixup_msi_route(kroute, msg.address, msg.data)) {
+kvm_irqchip_release_virq(s, virq);
+return -EINVAL;
+}
 
 kvm_add_routing_entry(s, kroute);
 kvm_irqchip_commit_routes(s);
@@ -1250,6 +1254,9 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, 
MSIMessage msg)
 kroute.u.msi.address_lo = (uint32_t)msg.address;
 kroute.u.msi.address_hi = msg.address  32;
 kroute.u.msi.data = le32_to_cpu(msg.data);
+if (kvm_arch_fixup_msi_route(kroute, msg.address, msg.data)) {
+return -EINVAL;
+}
 
 return kvm_update_routing_entry(s, kroute);
 }
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 4d81f3d..23cefe9 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -548,3 +548,9 @@ int kvm_arch_irqchip_create(KVMState *s)
 
 return 0;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index f92edfe..54ccb89 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -2733,3 +2733,9 @@ int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id)
 return kvm_deassign_irq_internal(s, dev_id, KVM_DEV_IRQ_GUEST_MSIX |
 KVM_DEV_IRQ_HOST_MSIX);
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index a761ea5..b68191c 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -688,3 +688,9 @@ int kvm_arch_get_registers(CPUState *cs)
 
 return ret;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 6843fa0..04c83cd 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -2388,3 +2388,9 @@ out_close:
 error_out:
 return;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index a6849ab..89cc218 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -41,6 +41,7 @@
 #include trace.h
 #include qapi-event.h
 #include hw/s390x/s390-pci-inst.h
+#include hw/s390x/s390-pci-bus.h
 
 /* #define DEBUG_KVM */
 
@@ -1514,3 +1515,28 @@ int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t 
cpu_state)
 
 return ret;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+  uint64_t address, uint32_t data)
+{
+S390PCIBusDevice *pbdev;
+uint32_t fid = data  ZPCI_MSI_VEC_BITS;
+uint32_t vec = data  ZPCI_MSI_VEC_MASK;
+
+pbdev = s390_pci_find_dev_by_fid(fid);
+if (!pbdev) {
+DPRINTF(add_msi_route no dev\n);
+return -ENODEV;
+}
+
+pbdev-routes.adapter.ind_offset = vec;
+
+route-type = KVM_IRQ_ROUTING_S390_ADAPTER;
+route-flags = 0;
+route-u.adapter.summary_addr = pbdev-routes.adapter.summary_addr;
+route-u.adapter.ind_addr = pbdev-routes.adapter.ind_addr;
+route-u.adapter.summary_offset = pbdev

[Qemu-devel] [PATCH 1/3 V3] s390: Add PCI bus support

2015-01-09 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements a pci bus for s390x together with infrastructure
to generate and handle hotplug events, to configure/unconfigure via
sclp instruction, to do iommu translations and provide s390 support for
MSI/MSI-X notification processing.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 MAINTAINERS   |   2 +
 default-configs/s390x-softmmu.mak |   1 +
 hw/s390x/Makefile.objs|   1 +
 hw/s390x/css.c|   5 +
 hw/s390x/css.h|   1 +
 hw/s390x/s390-pci-bus.c   | 591 ++
 hw/s390x/s390-pci-bus.h   | 251 
 hw/s390x/s390-virtio-ccw.c|   7 +
 hw/s390x/sclp.c   |  10 +-
 include/hw/s390x/sclp.h   |   8 +
 target-s390x/ioinst.c |  52 
 target-s390x/ioinst.h |   1 +
 12 files changed, 929 insertions(+), 1 deletion(-)
 create mode 100644 hw/s390x/s390-pci-bus.c
 create mode 100644 hw/s390x/s390-pci-bus.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 01cfb05..19c274b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -534,6 +534,7 @@ S390 Virtio
 M: Alexander Graf ag...@suse.de
 S: Maintained
 F: hw/s390x/s390-*.c
+X: hw/s390x/*pci*.[hc]
 
 S390 Virtio-ccw
 M: Cornelia Huck cornelia.h...@de.ibm.com
@@ -544,6 +545,7 @@ F: hw/s390x/s390-virtio-ccw.c
 F: hw/s390x/css.[hc]
 F: hw/s390x/sclp*.[hc]
 F: hw/s390x/ipl*.[hc]
+F: hw/s390x/*pci*.[hc]
 F: include/hw/s390x/
 F: pc-bios/s390-ccw/
 T: git git://github.com/cohuck/qemu virtio-ccw-upstr
diff --git a/default-configs/s390x-softmmu.mak 
b/default-configs/s390x-softmmu.mak
index 126d88d..6ee2ff8 100644
--- a/default-configs/s390x-softmmu.mak
+++ b/default-configs/s390x-softmmu.mak
@@ -1,3 +1,4 @@
+include pci.mak
 CONFIG_VIRTIO=y
 CONFIG_SCLPCONSOLE=y
 CONFIG_S390_FLIC=y
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 1ba6c3a..428d957 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -8,3 +8,4 @@ obj-y += ipl.o
 obj-y += css.o
 obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
+obj-y += s390-pci-bus.o
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index b67c039..d0c5dde 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1299,6 +1299,11 @@ void css_generate_chp_crws(uint8_t cssid, uint8_t chpid)
 /* TODO */
 }
 
+void css_generate_css_crws(uint8_t cssid)
+{
+css_queue_crw(CRW_RSC_CSS, 0, 0, cssid);
+}
+
 int css_enable_mcsse(void)
 {
 trace_css_enable_facility(mcsse);
diff --git a/hw/s390x/css.h b/hw/s390x/css.h
index 33104ac..7e53148 100644
--- a/hw/s390x/css.h
+++ b/hw/s390x/css.h
@@ -101,6 +101,7 @@ void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, 
uint16_t rsid);
 void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
int hotplugged, int add);
 void css_generate_chp_crws(uint8_t cssid, uint8_t chpid);
+void css_generate_css_crws(uint8_t cssid);
 void css_adapter_interrupt(uint8_t isc);
 
 #define CSS_IO_ADAPTER_VIRTIO 1
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
new file mode 100644
index 000..5bebe96
--- /dev/null
+++ b/hw/s390x/s390-pci-bus.c
@@ -0,0 +1,591 @@
+/*
+ * s390 PCI BUS
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include s390-pci-bus.h
+#include hw/pci/pci_bus.h
+#include hw/pci/msi.h
+#include qemu/error-report.h
+
+/* #define DEBUG_S390PCI_BUS */
+#ifdef DEBUG_S390PCI_BUS
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, S390pci-bus:  fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+int chsc_sei_nt2_get_event(void *res)
+{
+ChscSeiNt2Res *nt2_res = (ChscSeiNt2Res *)res;
+PciCcdfAvail *accdf;
+PciCcdfErr *eccdf;
+int rc = 1;
+SeiContainer *sei_cont;
+S390pciState *s = S390_PCI_HOST_BRIDGE(
+object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
+
+if (!s) {
+return rc;
+}
+
+sei_cont = QTAILQ_FIRST(s-pending_sei);
+if (sei_cont) {
+QTAILQ_REMOVE(s-pending_sei, sei_cont, link);
+nt2_res-nt = 2;
+nt2_res-cc = sei_cont-cc;
+switch (sei_cont-cc) {
+case 1: /* error event */
+eccdf = (PciCcdfErr *)nt2_res-ccdf;
+eccdf-fid = cpu_to_be32(sei_cont-fid);
+eccdf-fh = cpu_to_be32(sei_cont-fh);
+eccdf-e = cpu_to_be32(sei_cont-e);
+eccdf-faddr = cpu_to_be64(sei_cont-faddr);
+eccdf-pec = cpu_to_be16(sei_cont-pec);
+break;
+case 2: /* availability event */
+accdf = (PciCcdfAvail *)nt2_res-ccdf;
+accdf-fid = cpu_to_be32

[Qemu-devel] [PATCH 0/3 V3] add PCI support for the s390 platform

2015-01-09 Thread Frank Blaschka
This set of patches implemets PCI support for the s390 platform.
Now it is possible to run virtio-net-pci and potentially all
virtual pci devices conforming to s390 platform constrains.

V1 added lot of feedback from Alex Graf
   fixed tons of endian issues

V2 added couple of small improvments and code cleanup
   fixed build on 32-bit and non Linux
   added pci to maintainer file

V3 fix css_generate_css_crws to pass cssid to css_queue_crw
   fix and compile test w32 build
   review #defines for ULL usage

patches apply to latest qemu master
please consider for integration into 2.3

Thanks,

Frank

Frank Blaschka (3):
  s390: Add PCI bus support
  s390: implement pci instructions
  kvm: extend kvm_irqchip_add_msi_route to work on s390

 MAINTAINERS   |   2 +
 default-configs/s390x-softmmu.mak |   1 +
 hw/s390x/Makefile.objs|   1 +
 hw/s390x/css.c|   5 +
 hw/s390x/css.h|   1 +
 hw/s390x/s390-pci-bus.c   | 591 +++
 hw/s390x/s390-pci-bus.h   | 251 
 hw/s390x/s390-pci-inst.c  | 811 ++
 hw/s390x/s390-pci-inst.h  | 288 ++
 hw/s390x/s390-virtio-ccw.c|   7 +
 hw/s390x/sclp.c   |  10 +-
 include/hw/s390x/sclp.h   |   8 +
 include/sysemu/kvm.h  |   4 +
 kvm-all.c |   7 +
 target-arm/kvm.c  |   6 +
 target-i386/kvm.c |   6 +
 target-mips/kvm.c |   6 +
 target-ppc/kvm.c  |   6 +
 target-s390x/ioinst.c |  52 +++
 target-s390x/ioinst.h |   1 +
 target-s390x/kvm.c| 179 +
 21 files changed, 2242 insertions(+), 1 deletion(-)
 create mode 100644 hw/s390x/s390-pci-bus.c
 create mode 100644 hw/s390x/s390-pci-bus.h
 create mode 100644 hw/s390x/s390-pci-inst.c
 create mode 100644 hw/s390x/s390-pci-inst.h

-- 
2.1.4




Re: [Qemu-devel] [PULL v2 0/7] s390x patches for 2.3

2015-01-07 Thread Frank Blaschka
On Wed, Jan 07, 2015 at 04:08:13PM +0100, Cornelia Huck wrote:
 On Sat, 20 Dec 2014 22:03:34 +
 Peter Maydell peter.mayd...@linaro.org wrote:
 
  On 18 December 2014 at 16:34, Cornelia Huck cornelia.h...@de.ibm.com 
  wrote:
   Next try for s390x updates. The previous build failures should be
   fixed now.
  
  Still not building on w32, I'm afraid. I think most of this is run-on
  error from using __uint16_t c rather than uint16_t c.
 
 Sigh. Every time I try to set up a mingw build environment, I get lost
 in some library dependencies and give up.
 
 But yes, the __uint* stuff looks like some copypaste error from the
 respective Linux headers. I'll leave it to Frank to fix that up.


ok, I'm working on a patch to fix this but I hate to go on this way and steel
your time by let you compile test the changes. I do not have a windows
build system available so I'm wondering if there is some kind of public
infrastructure I can use to do a win build?

Thx for any pointers and help ...

  
  You also have a bunch of 64 bit constants like the ZPCI_*_ADDR
  which need a trailing ULL, and also some with a UL which
  should probably be ULL. For instance in
  
  #define ZPCI_STE_FLAG_MASK  0x7ffUL
  #define ZPCI_STE_ADDR_MASK  (~ZPCI_STE_FLAG_MASK)
  
  though ZPCI_STE_FLAG_MASK is OK by itself, when you use it
  in ZPCI_STE_ADDR_MASK you will get the logical-negate done
  at 32 bits before zero-extend to 64 bits, rather than a 64
  bit negate.
  
  (I think that UL is almost never correct in QEMU -- you
  either want at least 32 bits, in which case U is
  sufficient, or you need 64 bits, in which case you need
  ULL.)
 
 That's probably also an artifact of grabbing the constants from Linux
 (where the code is 64 bit only).
 
  
  Some of those suffixes are provoking compiler warnings or
  errors below, but some of them will just be silent wrong
  behaviour, so you should probably eyeball the #defines...
 
 There are also some possibly dodgy places in non-pci code; I'll take a
 look at those as well.
 
 




[Qemu-devel] [PATCH 0/3 V2] add PCI support for the s390 platform

2014-12-18 Thread Frank Blaschka
This set of patches implemets PCI support for the s390 platform.
Now it is possible to run virtio-net-pci and potentially all
virtual pci devices conforming to s390 platform constrains.

V1 added lot of feedback from Alex Graf
   fixed tons of endian issues

V2 added couple of small improvments and code cleanup
   fixed build on 32-bit and non Linux
   added pci to maintainer file

Please consider for integration into 2.3

Thanks,

Frank

Frank Blaschka (3):
  s390: Add PCI bus support
  s390: implement pci instructions
  kvm: extend kvm_irqchip_add_msi_route to work on s390

 MAINTAINERS   |   2 +
 default-configs/s390x-softmmu.mak |   1 +
 hw/s390x/Makefile.objs|   1 +
 hw/s390x/css.c|   5 +
 hw/s390x/css.h|   1 +
 hw/s390x/s390-pci-bus.c   | 591 +++
 hw/s390x/s390-pci-bus.h   | 251 
 hw/s390x/s390-pci-inst.c  | 811 ++
 hw/s390x/s390-pci-inst.h  | 288 ++
 hw/s390x/s390-virtio-ccw.c|   7 +
 hw/s390x/sclp.c   |  10 +-
 include/hw/s390x/sclp.h   |   8 +
 include/sysemu/kvm.h  |   4 +
 kvm-all.c |   7 +
 target-arm/kvm.c  |   6 +
 target-i386/kvm.c |   6 +
 target-mips/kvm.c |   6 +
 target-ppc/kvm.c  |   6 +
 target-s390x/ioinst.c |  52 +++
 target-s390x/ioinst.h |   1 +
 target-s390x/kvm.c| 179 +
 21 files changed, 2242 insertions(+), 1 deletion(-)
 create mode 100644 hw/s390x/s390-pci-bus.c
 create mode 100644 hw/s390x/s390-pci-bus.h
 create mode 100644 hw/s390x/s390-pci-inst.c
 create mode 100644 hw/s390x/s390-pci-inst.h

-- 
1.8.5.5




[Qemu-devel] [PATCH 1/3 V2] s390: Add PCI bus support

2014-12-18 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements a pci bus for s390x together with infrastructure
to generate and handle hotplug events, to configure/unconfigure via
sclp instruction, to do iommu translations and provide s390 support for
MSI/MSI-X notification processing.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 MAINTAINERS   |   2 +
 default-configs/s390x-softmmu.mak |   1 +
 hw/s390x/Makefile.objs|   1 +
 hw/s390x/css.c|   5 +
 hw/s390x/css.h|   1 +
 hw/s390x/s390-pci-bus.c   | 591 ++
 hw/s390x/s390-pci-bus.h   | 251 
 hw/s390x/s390-virtio-ccw.c|   7 +
 hw/s390x/sclp.c   |  10 +-
 include/hw/s390x/sclp.h   |   8 +
 target-s390x/ioinst.c |  52 
 target-s390x/ioinst.h |   1 +
 12 files changed, 929 insertions(+), 1 deletion(-)
 create mode 100644 hw/s390x/s390-pci-bus.c
 create mode 100644 hw/s390x/s390-pci-bus.h

diff --git a/MAINTAINERS b/MAINTAINERS
index d72d6e3..790dfce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -534,6 +534,7 @@ S390 Virtio
 M: Alexander Graf ag...@suse.de
 S: Maintained
 F: hw/s390x/s390-*.c
+X: hw/s390x/*pci*.[hc]
 
 S390 Virtio-ccw
 M: Cornelia Huck cornelia.h...@de.ibm.com
@@ -544,6 +545,7 @@ F: hw/s390x/s390-virtio-ccw.c
 F: hw/s390x/css.[hc]
 F: hw/s390x/sclp*.[hc]
 F: hw/s390x/ipl*.[hc]
+F: hw/s390x/*pci*.[hc]
 F: include/hw/s390x/
 F: pc-bios/s390-ccw/
 T: git git://github.com/cohuck/qemu virtio-ccw-upstr
diff --git a/default-configs/s390x-softmmu.mak 
b/default-configs/s390x-softmmu.mak
index 126d88d..6ee2ff8 100644
--- a/default-configs/s390x-softmmu.mak
+++ b/default-configs/s390x-softmmu.mak
@@ -1,3 +1,4 @@
+include pci.mak
 CONFIG_VIRTIO=y
 CONFIG_SCLPCONSOLE=y
 CONFIG_S390_FLIC=y
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 1ba6c3a..428d957 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -8,3 +8,4 @@ obj-y += ipl.o
 obj-y += css.o
 obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
+obj-y += s390-pci-bus.o
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index b67c039..7553085 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1299,6 +1299,11 @@ void css_generate_chp_crws(uint8_t cssid, uint8_t chpid)
 /* TODO */
 }
 
+void css_generate_css_crws(uint8_t cssid)
+{
+css_queue_crw(CRW_RSC_CSS, 0, 0, 0);
+}
+
 int css_enable_mcsse(void)
 {
 trace_css_enable_facility(mcsse);
diff --git a/hw/s390x/css.h b/hw/s390x/css.h
index 33104ac..7e53148 100644
--- a/hw/s390x/css.h
+++ b/hw/s390x/css.h
@@ -101,6 +101,7 @@ void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, 
uint16_t rsid);
 void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
int hotplugged, int add);
 void css_generate_chp_crws(uint8_t cssid, uint8_t chpid);
+void css_generate_css_crws(uint8_t cssid);
 void css_adapter_interrupt(uint8_t isc);
 
 #define CSS_IO_ADAPTER_VIRTIO 1
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
new file mode 100644
index 000..c9c06e6
--- /dev/null
+++ b/hw/s390x/s390-pci-bus.c
@@ -0,0 +1,591 @@
+/*
+ * s390 PCI BUS
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include s390-pci-bus.h
+#include hw/pci/pci_bus.h
+#include hw/pci/msi.h
+#include qemu/error-report.h
+
+/* #define DEBUG_S390PCI_BUS */
+#ifdef DEBUG_S390PCI_BUS
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, S390pci-bus:  fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+int chsc_sei_nt2_get_event(void *res)
+{
+ChscSeiNt2Res *nt2_res = (ChscSeiNt2Res *)res;
+PciCcdfAvail *accdf;
+PciCcdfErr *eccdf;
+int rc = 1;
+SeiContainer *sei_cont;
+S390pciState *s = S390_PCI_HOST_BRIDGE(
+object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
+
+if (!s) {
+return rc;
+}
+
+sei_cont = QTAILQ_FIRST(s-pending_sei);
+if (sei_cont) {
+QTAILQ_REMOVE(s-pending_sei, sei_cont, link);
+nt2_res-nt = 2;
+nt2_res-cc = sei_cont-cc;
+switch (sei_cont-cc) {
+case 1: /* error event */
+eccdf = (PciCcdfErr *)nt2_res-ccdf;
+eccdf-fid = cpu_to_be32(sei_cont-fid);
+eccdf-fh = cpu_to_be32(sei_cont-fh);
+eccdf-e = cpu_to_be32(sei_cont-e);
+eccdf-faddr = cpu_to_be64(sei_cont-faddr);
+eccdf-pec = cpu_to_be16(sei_cont-pec);
+break;
+case 2: /* availability event */
+accdf = (PciCcdfAvail *)nt2_res-ccdf;
+accdf-fid = cpu_to_be32(sei_cont

[Qemu-devel] [PATCH 2/3 V2] s390: implement pci instructions

2014-12-18 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements the s390 pci instructions in qemu. It allows
to access and drive pci devices attached to the s390 pci bus.
Because of platform constrains devices using IO BARs are not
supported. Also a device has to support MSI/MSI-X to run on s390.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 hw/s390x/Makefile.objs   |   2 +-
 hw/s390x/s390-pci-inst.c | 811 +++
 hw/s390x/s390-pci-inst.h | 288 +
 target-s390x/kvm.c   | 153 +
 4 files changed, 1253 insertions(+), 1 deletion(-)
 create mode 100644 hw/s390x/s390-pci-inst.c
 create mode 100644 hw/s390x/s390-pci-inst.h

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 428d957..27cd75a 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -8,4 +8,4 @@ obj-y += ipl.o
 obj-y += css.o
 obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
-obj-y += s390-pci-bus.o
+obj-y += s390-pci-bus.o s390-pci-inst.o
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
new file mode 100644
index 000..d486cbb
--- /dev/null
+++ b/hw/s390x/s390-pci-inst.c
@@ -0,0 +1,811 @@
+/*
+ * s390 PCI instructions
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include s390-pci-inst.h
+#include s390-pci-bus.h
+#include exec/memory-internal.h
+#include qemu/error-report.h
+
+/* #define DEBUG_S390PCI_INST */
+#ifdef DEBUG_S390PCI_INST
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, s390pci-inst:  fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+static void s390_set_status_code(CPUS390XState *env,
+ uint8_t r, uint64_t status_code)
+{
+env-regs[r] = ~0xff00ULL;
+env-regs[r] |= (status_code  0xff)  24;
+}
+
+static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc)
+{
+S390PCIBusDevice *pbdev;
+uint32_t res_code, initial_l2, g_l2, finish;
+int rc, idx;
+uint64_t resume_token;
+
+rc = 0;
+if (lduw_p(rrb-request.hdr.len) != 32) {
+res_code = CLP_RC_LEN;
+rc = -EINVAL;
+goto out;
+}
+
+if ((ldl_p(rrb-request.fmt)  CLP_MASK_FMT) != 0) {
+res_code = CLP_RC_FMT;
+rc = -EINVAL;
+goto out;
+}
+
+if ((ldl_p(rrb-request.fmt)  ~CLP_MASK_FMT) != 0 ||
+ldq_p(rrb-request.reserved1) != 0 ||
+ldq_p(rrb-request.reserved2) != 0) {
+res_code = CLP_RC_RESNOT0;
+rc = -EINVAL;
+goto out;
+}
+
+resume_token = ldq_p(rrb-request.resume_token);
+
+if (resume_token) {
+pbdev = s390_pci_find_dev_by_idx(resume_token);
+if (!pbdev) {
+res_code = CLP_RC_LISTPCI_BADRT;
+rc = -EINVAL;
+goto out;
+}
+}
+
+if (lduw_p(rrb-response.hdr.len)  48) {
+res_code = CLP_RC_8K;
+rc = -EINVAL;
+goto out;
+}
+
+initial_l2 = lduw_p(rrb-response.hdr.len);
+if ((initial_l2 - LIST_PCI_HDR_LEN) % sizeof(ClpFhListEntry)
+!= 0) {
+res_code = CLP_RC_LEN;
+rc = -EINVAL;
+*cc = 3;
+goto out;
+}
+
+stl_p(rrb-response.fmt, 0);
+stq_p(rrb-response.reserved1, 0);
+stq_p(rrb-response.reserved2, 0);
+stl_p(rrb-response.mdd, FH_VIRT);
+stw_p(rrb-response.max_fn, PCI_MAX_FUNCTIONS);
+rrb-response.entry_size = sizeof(ClpFhListEntry);
+finish = 0;
+idx = resume_token;
+g_l2 = LIST_PCI_HDR_LEN;
+do {
+pbdev = s390_pci_find_dev_by_idx(idx);
+if (!pbdev) {
+finish = 1;
+break;
+}
+stw_p(rrb-response.fh_list[idx - resume_token].device_id,
+pci_get_word(pbdev-pdev-config + PCI_DEVICE_ID));
+stw_p(rrb-response.fh_list[idx - resume_token].vendor_id,
+pci_get_word(pbdev-pdev-config + PCI_VENDOR_ID));
+stl_p(rrb-response.fh_list[idx - resume_token].config, 0x8000);
+stl_p(rrb-response.fh_list[idx - resume_token].fid, pbdev-fid);
+stl_p(rrb-response.fh_list[idx - resume_token].fh, pbdev-fh);
+
+g_l2 += sizeof(ClpFhListEntry);
+/* Add endian check for DPRINTF? */
+DPRINTF(g_l2 %d vendor id 0x%x device id 0x%x fid 0x%x fh 0x%x\n,
+g_l2,
+lduw_p(rrb-response.fh_list[idx - resume_token].vendor_id),
+lduw_p(rrb-response.fh_list[idx - resume_token].device_id),
+ldl_p(rrb-response.fh_list[idx - resume_token].fid),
+ldl_p(rrb-response.fh_list[idx - resume_token].fh));
+idx++;
+} while (g_l2  initial_l2);
+
+if (finish == 1) {
+resume_token = 0

[Qemu-devel] [PATCH 3/3 V2] kvm: extend kvm_irqchip_add_msi_route to work on s390

2014-12-18 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

on s390 MSI-X irqs are presented as thin or adapter interrupts
for this we have to reorganize the routing entry to contain
valid information for the adapter interrupt code on s390.
To minimize impact on existing code we introduce an architecture
function to fixup the routing entry.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 include/sysemu/kvm.h |  4 
 kvm-all.c|  7 +++
 target-arm/kvm.c |  6 ++
 target-i386/kvm.c|  6 ++
 target-mips/kvm.c|  6 ++
 target-ppc/kvm.c |  6 ++
 target-s390x/kvm.c   | 26 ++
 7 files changed, 61 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 104cf35..30cb84d 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -158,6 +158,7 @@ extern bool kvm_readonly_mem_allowed;
 
 struct kvm_run;
 struct kvm_lapic_state;
+struct kvm_irq_routing_entry;
 
 typedef struct KVMCapabilityInfo {
 const char *name;
@@ -270,6 +271,9 @@ int kvm_arch_on_sigbus(int code, void *addr);
 
 void kvm_arch_init_irq_routing(KVMState *s);
 
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data);
+
 int kvm_set_irq(KVMState *s, int irq, int level);
 int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
 
diff --git a/kvm-all.c b/kvm-all.c
index 18cc6b4..2f21a4e 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1225,6 +1225,10 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage 
msg)
 kroute.u.msi.address_lo = (uint32_t)msg.address;
 kroute.u.msi.address_hi = msg.address  32;
 kroute.u.msi.data = le32_to_cpu(msg.data);
+if (kvm_arch_fixup_msi_route(kroute, msg.address, msg.data)) {
+kvm_irqchip_release_virq(s, virq);
+return -EINVAL;
+}
 
 kvm_add_routing_entry(s, kroute);
 kvm_irqchip_commit_routes(s);
@@ -1250,6 +1254,9 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, 
MSIMessage msg)
 kroute.u.msi.address_lo = (uint32_t)msg.address;
 kroute.u.msi.address_hi = msg.address  32;
 kroute.u.msi.data = le32_to_cpu(msg.data);
+if (kvm_arch_fixup_msi_route(kroute, msg.address, msg.data)) {
+return -EINVAL;
+}
 
 return kvm_update_routing_entry(s, kroute);
 }
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 4d81f3d..23cefe9 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -548,3 +548,9 @@ int kvm_arch_irqchip_create(KVMState *s)
 
 return 0;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index f92edfe..54ccb89 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -2733,3 +2733,9 @@ int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id)
 return kvm_deassign_irq_internal(s, dev_id, KVM_DEV_IRQ_GUEST_MSIX |
 KVM_DEV_IRQ_HOST_MSIX);
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index a761ea5..b68191c 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -688,3 +688,9 @@ int kvm_arch_get_registers(CPUState *cs)
 
 return ret;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 6843fa0..04c83cd 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -2388,3 +2388,9 @@ out_close:
 error_out:
 return;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index a6849ab..89cc218 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -41,6 +41,7 @@
 #include trace.h
 #include qapi-event.h
 #include hw/s390x/s390-pci-inst.h
+#include hw/s390x/s390-pci-bus.h
 
 /* #define DEBUG_KVM */
 
@@ -1514,3 +1515,28 @@ int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t 
cpu_state)
 
 return ret;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+  uint64_t address, uint32_t data)
+{
+S390PCIBusDevice *pbdev;
+uint32_t fid = data  ZPCI_MSI_VEC_BITS;
+uint32_t vec = data  ZPCI_MSI_VEC_MASK;
+
+pbdev = s390_pci_find_dev_by_fid(fid);
+if (!pbdev) {
+DPRINTF(add_msi_route no dev\n);
+return -ENODEV;
+}
+
+pbdev-routes.adapter.ind_offset = vec;
+
+route-type = KVM_IRQ_ROUTING_S390_ADAPTER;
+route-flags = 0;
+route-u.adapter.summary_addr = pbdev-routes.adapter.summary_addr;
+route-u.adapter.ind_addr = pbdev-routes.adapter.ind_addr;
+route-u.adapter.summary_offset = pbdev

[Qemu-devel] [PATCH] s390/pci: fix build on 32-bit and non linux

2014-12-16 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

Remove unnecessary and wrong includes. Fix get_rt_sto and
get_st_pto to build on 32-bit.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 hw/s390x/s390-pci-bus.c  | 25 +++--
 hw/s390x/s390-pci-inst.c | 30 +++---
 2 files changed, 14 insertions(+), 41 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index c1b57d0..c9c06e6 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -11,13 +11,10 @@
  * directory.
  */
 
-#include hw/pci/pci.h
+#include s390-pci-bus.h
 #include hw/pci/pci_bus.h
-#include hw/s390x/css.h
-#include hw/s390x/sclp.h
 #include hw/pci/msi.h
-#include qemu/error-report.h
-#include s390-pci-bus.h
+#include qemu/error-report.h
 
 /* #define DEBUG_S390PCI_BUS */
 #ifdef DEBUG_S390PCI_BUS
@@ -253,18 +250,18 @@ static unsigned int calc_px(dma_addr_t ptr)
 return ((unsigned long) ptr  PAGE_SHIFT)  ZPCI_PT_MASK;
 }
 
-static unsigned long *get_rt_sto(unsigned long entry)
+static uint64_t get_rt_sto(uint64_t entry)
 {
 return ((entry  ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_RTX)
-? (unsigned long *) (entry  ZPCI_RTE_ADDR_MASK)
-: NULL;
+? (entry  ZPCI_RTE_ADDR_MASK)
+: 0;
 }
 
-static unsigned long *get_st_pto(unsigned long entry)
+static uint64_t get_st_pto(uint64_t entry)
 {
 return ((entry  ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_SX)
-? (unsigned long *) (entry  ZPCI_STE_ADDR_MASK)
-: NULL;
+? (entry  ZPCI_STE_ADDR_MASK)
+: 0;
 }
 
 static uint64_t s390_guest_io_table_walk(uint64_t guest_iota,
@@ -280,7 +277,7 @@ static uint64_t s390_guest_io_table_walk(uint64_t 
guest_iota,
 
 sto_a = guest_iota + rtx * sizeof(uint64_t);
 sto = ldq_phys(address_space_memory, sto_a);
-sto = (uint64_t)get_rt_sto(sto);
+sto = get_rt_sto(sto);
 if (!sto) {
 pte = 0;
 goto out;
@@ -288,7 +285,7 @@ static uint64_t s390_guest_io_table_walk(uint64_t 
guest_iota,
 
 pto_a = sto + sx * sizeof(uint64_t);
 pto = ldq_phys(address_space_memory, pto_a);
-pto = (uint64_t)get_st_pto(pto);
+pto = get_st_pto(pto);
 if (!pto) {
 pte = 0;
 goto out;
@@ -322,7 +319,7 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion 
*iommu, hwaddr addr,
 /* s390 does not have an APIC maped to main storage so we use
  * a separate AddressSpace only for msix notifications
  */
-if (addr == ZPCI_MSI_ADDR) {
+if (((uint64_t)addr) == ZPCI_MSI_ADDR) {
 ret.target_as = s-msix_notify_as;
 ret.iova = addr;
 ret.translated_addr = addr;
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 83ab60f..d486cbb 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -11,34 +11,10 @@
  * directory.
  */
 
-#include sys/types.h
-#include sys/ioctl.h
-#include sys/mman.h
-
-#include linux/kvm.h
-#include asm/ptrace.h
-#include hw/pci/pci.h
-#include hw/pci/pci_host.h
-#include net/net.h
-
-#include qemu-common.h
-#include qemu/timer.h
-#include migration/qemu-file.h
-#include sysemu/sysemu.h
-#include sysemu/kvm.h
-#include cpu.h
-#include sysemu/device_tree.h
-#include monitor/monitor.h
 #include s390-pci-inst.h
-
-#include hw/hw.h
-#include hw/pci/pci.h
-#include hw/pci/pci_bridge.h
-#include hw/pci/pci_bus.h
-#include hw/pci/pci_host.h
-#include hw/s390x/s390-pci-bus.h
-#include exec/exec-all.h
-#include exec/memory-internal.h
+#include s390-pci-bus.h
+#include exec/memory-internal.h
+#include qemu/error-report.h
 
 /* #define DEBUG_S390PCI_INST */
 #ifdef DEBUG_S390PCI_INST
-- 
1.8.5.5




Re: [Qemu-devel] [PATCH] s390/pci: fix build on 32-bit and non linux

2014-12-16 Thread Frank Blaschka
On Tue, Dec 16, 2014 at 11:35:19AM +0100, Alexander Graf wrote:
 
 
 
  Am 16.12.2014 um 10:28 schrieb Frank Blaschka blasc...@linux.vnet.ibm.com:
  
  From: Frank Blaschka frank.blasc...@de.ibm.com
  
  Remove unnecessary and wrong includes. Fix get_rt_sto and
  get_st_pto to build on 32-bit.
  
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
 
 Could you please roll the fixes into the offending patches and repost the 
 set? Otherwise we break bisectability on 32bit hosts.


Sure, but since this is an initial drop and I have to touch the patches anyhow 
can I merge all
add-ons and fixes to the initial patch set?

I would like to end up finally with just 3 patches:

  s390: Add PCI bus support
  s390: implement pci instructions
  kvm: extend kvm_irqchip_add_msi_route to work on s390

If so I would post V2 of the initial patch set including all changes.

Frank
 
 Alex
 




Re: [Qemu-devel] [PATCH] s390/pci: fix build on 32-bit and non linux

2014-12-16 Thread Frank Blaschka
On Tue, Dec 16, 2014 at 12:56:58PM +0100, Alexander Graf wrote:
 
 
 On 16.12.14 12:46, Frank Blaschka wrote:
  On Tue, Dec 16, 2014 at 11:35:19AM +0100, Alexander Graf wrote:
 
 
 
  Am 16.12.2014 um 10:28 schrieb Frank Blaschka 
  blasc...@linux.vnet.ibm.com:
 
  From: Frank Blaschka frank.blasc...@de.ibm.com
 
  Remove unnecessary and wrong includes. Fix get_rt_sto and
  get_st_pto to build on 32-bit.
 
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
 
  Could you please roll the fixes into the offending patches and repost the 
  set? Otherwise we break bisectability on 32bit hosts.
 
  
  Sure, but since this is an initial drop and I have to touch the patches 
  anyhow can I merge all
  add-ons and fixes to the initial patch set?
  
  I would like to end up finally with just 3 patches:
  
s390: Add PCI bus support
s390: implement pci instructions
kvm: extend kvm_irqchip_add_msi_route to work on s390
  
  If so I would post V2 of the initial patch set including all changes.
 
 Cornelia is the maintainer here, so you'll need to ask her :). Anything
 that doesn't break bisectability is certainly better than code that
 breaks it.


OK. Coni what do you prefere?
 
 By squashing all those patches together you'll make bisecting harder for
 s390 - if you can live with it so can I.
 
 
 Alex
 




Re: [Qemu-devel] [PATCH 2/2] s390/pci: implement stpcifc instruction

2014-12-08 Thread Frank Blaschka
On Fri, Dec 05, 2014 at 02:15:07PM +0100, Thomas Huth wrote:
 
  Hi Frank,
 
 On Fri,  5 Dec 2014 10:19:59 +0100
 Frank Blaschka blasc...@linux.vnet.ibm.com wrote:
 
  From: Frank Blaschka frank.blasc...@de.ibm.com
  
  This patch implements the last remaining s390 pci instruction
  to query the function information block.
  
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
  ---
   hw/s390x/s390-pci-bus.h  |  1 +
   hw/s390x/s390-pci-inst.c | 64 
  
   hw/s390x/s390-pci-inst.h |  1 +
   target-s390x/kvm.c   |  9 +--
   4 files changed, 73 insertions(+), 2 deletions(-)
  
  diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
  index 2a9f735..35f4da5 100644
  --- a/hw/s390x/s390-pci-bus.h
  +++ b/hw/s390x/s390-pci-bus.h
  @@ -223,6 +223,7 @@ typedef struct S390PCIBusDevice {
   uint64_t g_iota;
   uint64_t pba;
   uint64_t pal;
  +uint64_t fmb_addr;
   uint8_t isc;
   uint16_t noi;
   uint8_t sum;
  diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
  index 8648594..f503665 100644
  --- a/hw/s390x/s390-pci-inst.c
  +++ b/hw/s390x/s390-pci-inst.c
  @@ -766,6 +766,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, 
  uint64_t fiba)
   pbdev-lgstg_blocked = false;
   break;
   case ZPCI_MOD_FC_SET_MEASURE:
  +pbdev-fmb_addr = ldq_p(fib.fmb_addr);
   break;
   default:
   program_interrupt(cpu-env, PGM_OPERAND, 6);
  @@ -775,3 +776,66 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, 
  uint64_t fiba)
   setcc(cpu, cc);
   return 0;
   }
  +
  +int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
  +{
  +CPUS390XState *env = cpu-env;
  +uint32_t fh;
  +ZpciFib fib;
  +S390PCIBusDevice *pbdev;
  +uint32_t data;
  +uint64_t cc = ZPCI_PCI_LS_OK;
  +
  +cpu_synchronize_state(CPU(cpu));
 
 You're calling cpu_synchronize_state twice, one time in
 kvm_stpcifc_service_call() already and one time here. So I think
 you could remove the call here.


Hi Thomas,

looks like this is not the only duplicate cpu_synchronize_state.
Will create an add on patch to remove all unnecessary calls to
cpu_synchronize_state. Thx for the finding.

Frank

  +if (env-psw.mask  PSW_MASK_PSTATE) {
  +program_interrupt(env, PGM_PRIVILEGED, 6);
  +return 0;
  +}
  +
  +fh = env-regs[r1]  32;
  +
  +if (fiba  0x7) {
  +program_interrupt(env, PGM_SPECIFICATION, 6);
  +return 0;
  +}
  +
  +pbdev = s390_pci_find_dev_by_fh(fh);
  +if (!pbdev) {
  +setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
  +return 0;
  +}
  +
  +memset(fib, 0, sizeof(fib));
  +stq_p(fib.pba, pbdev-pba);
  +stq_p(fib.pal, pbdev-pal);
  +stq_p(fib.iota, pbdev-g_iota);
  +stq_p(fib.aibv, pbdev-routes.adapter.ind_addr);
  +stq_p(fib.aisb, pbdev-routes.adapter.summary_addr);
  +stq_p(fib.fmb_addr, pbdev-fmb_addr);
  +
  +data = (pbdev-isc  28) | (pbdev-noi  16) |
  +   (pbdev-routes.adapter.ind_offset  8) | (pbdev-sum  7) |
  +   pbdev-routes.adapter.summary_offset;
  +stw_p(fib.data, data);
  +
  +if (pbdev-fh  ENABLE_BIT_OFFSET) {
  +fib.fc |= 0x80;
  +}
  +
  +if (pbdev-error_state) {
  +fib.fc |= 0x40;
  +}
  +
  +if (pbdev-lgstg_blocked) {
  +fib.fc |= 0x20;
  +}
  +
  +if (pbdev-g_iota) {
  +fib.fc |= 0x10;
  +}
  +
  +cpu_physical_memory_write(fiba, (uint8_t *)fib, sizeof(fib));
  +setcc(cpu, cc);
  +return 0;
  +}
  diff --git a/hw/s390x/s390-pci-inst.h b/hw/s390x/s390-pci-inst.h
  index 609e3e0..1c2f458 100644
  --- a/hw/s390x/s390-pci-inst.h
  +++ b/hw/s390x/s390-pci-inst.h
  @@ -283,5 +283,6 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, 
  uint8_t r2);
   int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
   int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t 
  gaddr);
   int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
  +int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
  
   #endif
  diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
  index 32af46b..b70d482 100644
  --- a/target-s390x/kvm.c
  +++ b/target-s390x/kvm.c
  @@ -876,8 +876,13 @@ static int kvm_pcistg_service_call(S390CPU *cpu, 
  struct kvm_run *run)
  
   static int kvm_stpcifc_service_call(S390CPU *cpu, struct kvm_run *run)
   {
  -qemu_log_mask(LOG_UNIMP, STPCIFC missing\n);
  -return 0;
  +uint8_t r1 = (run-s390_sieic.ipa  0x00f0)  4;
  +uint64_t fiba;
  +
  +cpu_synchronize_state(CPU(cpu));
  +fiba = get_base_disp_rxy(cpu, run);
  +
  +return stpcifc_service_call(cpu, r1, fiba);
   }
  
   static int kvm_sic_service_call(S390CPU *cpu, struct kvm_run *run)
 




[Qemu-devel] [PATCH] s390/pci: remove unnecessary cpu_synchronize_state

2014-12-08 Thread Frank Blaschka
Remove all unnecessary calls to cpu_synchronize_state

Signed-off-by: Frank Blaschka blasc...@linux.vnet.ibm.com
---
 hw/s390x/s390-pci-inst.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index f503665..83ab60f 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -564,8 +564,6 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr)
 uint8_t pcias;
 uint8_t len;
 
-cpu_synchronize_state(CPU(cpu));
-
 if (env-psw.mask  PSW_MASK_PSTATE) {
 program_interrupt(env, PGM_PRIVILEGED, 6);
 return 0;
@@ -711,8 +709,6 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t 
fiba)
 S390PCIBusDevice *pbdev;
 uint64_t cc = ZPCI_PCI_LS_OK;
 
-cpu_synchronize_state(CPU(cpu));
-
 if (env-psw.mask  PSW_MASK_PSTATE) {
 program_interrupt(env, PGM_PRIVILEGED, 6);
 return 0;
@@ -786,8 +782,6 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t 
fiba)
 uint32_t data;
 uint64_t cc = ZPCI_PCI_LS_OK;
 
-cpu_synchronize_state(CPU(cpu));
-
 if (env-psw.mask  PSW_MASK_PSTATE) {
 program_interrupt(env, PGM_PRIVILEGED, 6);
 return 0;
-- 
1.8.5.5




[Qemu-devel] [PATCH 0/2] s390/pci: add 2 more features

2014-12-05 Thread Frank Blaschka
Coni, Alex, Christian,

here are 2 more s390/pci features on top of the base pci support.
Thx!

Frank

Frank Blaschka (2):
  s390/pci: add error event support
  s390/pci: implement stpcifc instruction

 hw/s390x/s390-pci-bus.c  |  50 ++--
 hw/s390x/s390-pci-bus.h  |  36 +++-
 hw/s390x/s390-pci-inst.c | 148 ---
 hw/s390x/s390-pci-inst.h |   1 +
 target-s390x/kvm.c   |   9 ++-
 5 files changed, 227 insertions(+), 17 deletions(-)

-- 
1.8.5.5




[Qemu-devel] [PATCH 1/2] s390/pci: add error event support

2014-12-05 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch adds support to generate s390 pci error events

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 hw/s390x/s390-pci-bus.c  | 50 +---
 hw/s390x/s390-pci-bus.h  | 35 +++-
 hw/s390x/s390-pci-inst.c | 86 ++--
 3 files changed, 155 insertions(+), 16 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 06d153a..c1b57d0 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -52,6 +52,9 @@ int chsc_sei_nt2_get_event(void *res)
 eccdf = (PciCcdfErr *)nt2_res-ccdf;
 eccdf-fid = cpu_to_be32(sei_cont-fid);
 eccdf-fh = cpu_to_be32(sei_cont-fh);
+eccdf-e = cpu_to_be32(sei_cont-e);
+eccdf-faddr = cpu_to_be64(sei_cont-faddr);
+eccdf-pec = cpu_to_be16(sei_cont-pec);
 break;
 case 2: /* availability event */
 accdf = (PciCcdfAvail *)nt2_res-ccdf;
@@ -184,8 +187,8 @@ S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh)
 return NULL;
 }
 
-static void s390_pci_generate_plug_event(uint16_t pec, uint32_t fh,
- uint32_t fid)
+static void s390_pci_generate_event(uint8_t cc, uint16_t pec, uint32_t fh,
+uint32_t fid, uint64_t faddr, uint32_t e)
 {
 SeiContainer *sei_cont = g_malloc0(sizeof(SeiContainer));
 S390pciState *s = S390_PCI_HOST_BRIDGE(
@@ -197,13 +200,28 @@ static void s390_pci_generate_plug_event(uint16_t pec, 
uint32_t fh,
 
 sei_cont-fh = fh;
 sei_cont-fid = fid;
-sei_cont-cc = 2;
+sei_cont-cc = cc;
 sei_cont-pec = pec;
+sei_cont-faddr = faddr;
+sei_cont-e = e;
 
 QTAILQ_INSERT_TAIL(s-pending_sei, sei_cont, link);
 css_generate_css_crws(0);
 }
 
+static void s390_pci_generate_plug_event(uint16_t pec, uint32_t fh,
+ uint32_t fid)
+{
+s390_pci_generate_event(2, pec, fh, fid, 0, 0);
+}
+
+static void s390_pci_generate_error_event(uint16_t pec, uint32_t fh,
+  uint32_t fid, uint64_t faddr,
+  uint32_t e)
+{
+s390_pci_generate_event(1, pec, fh, fid, faddr, e);
+}
+
 static void s390_pci_set_irq(void *opaque, int irq, int level)
 {
 /* nothing to do */
@@ -313,10 +331,30 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion 
*iommu, hwaddr addr,
 return ret;
 }
 
+if (!pbdev-g_iota) {
+pbdev-error_state = true;
+pbdev-lgstg_blocked = true;
+s390_pci_generate_error_event(ERR_EVENT_INVALAS, pbdev-fh, pbdev-fid,
+  addr, 0);
+return ret;
+}
+
+if (addr  pbdev-pba || addr  pbdev-pal) {
+pbdev-error_state = true;
+pbdev-lgstg_blocked = true;
+s390_pci_generate_error_event(ERR_EVENT_OORANGE, pbdev-fh, pbdev-fid,
+  addr, 0);
+return ret;
+}
+
 pte = s390_guest_io_table_walk(s390_pci_get_table_origin(pbdev-g_iota),
addr);
 
 if (!pte) {
+pbdev-error_state = true;
+pbdev-lgstg_blocked = true;
+s390_pci_generate_error_event(ERR_EVENT_SERR, pbdev-fh, pbdev-fid,
+  addr, ERR_EVENT_Q_BIT);
 return ret;
 }
 
@@ -353,7 +391,7 @@ static uint8_t set_ind_atomic(uint64_t ind_loc, uint8_t 
to_be_set)
 
 ind_addr = cpu_physical_memory_map(ind_loc, len, 1);
 if (!ind_addr) {
-error_report(%s: unable to access indicator, __func__);
+s390_pci_generate_error_event(ERR_EVENT_AIRERR, 0, 0, 0, 0);
 return -1;
 }
 do {
@@ -374,12 +412,14 @@ static void s390_msi_ctrl_write(void *opaque, hwaddr 
addr, uint64_t data,
 uint32_t vec = data  ZPCI_MSI_VEC_MASK;
 uint64_t ind_bit;
 uint32_t sum_bit;
+uint32_t e = 0;
 
 DPRINTF(write_msix data 0x%lx fid %d vec 0x%x\n, data, fid, vec);
 
 pbdev = s390_pci_find_dev_by_fid(fid);
 if (!pbdev) {
-DPRINTF(msix_notify no dev\n);
+e |= (vec  ERR_EVENT_MVN_OFFSET);
+s390_pci_generate_error_event(ERR_EVENT_NOMSI, 0, fid, addr, e);
 return;
 }
 
diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index fc567b7..2a9f735 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -33,6 +33,31 @@
 #define HP_EVENT_CONFIGURED_TO_STBRES 0x0304
 #define HP_EVENT_STANDBY_TO_RESERVED  0x0308
 
+#define ERR_EVENT_INVALAS 0x1
+#define ERR_EVENT_OORANGE 0x2
+#define ERR_EVENT_INVALTF 0x3
+#define ERR_EVENT_TPROTE  0x4
+#define ERR_EVENT_APROTE  0x5
+#define ERR_EVENT_KEYE0x6
+#define ERR_EVENT_INVALTE 0x7
+#define ERR_EVENT_INVALTL 0x8
+#define ERR_EVENT_TT  0x9
+#define ERR_EVENT_INVALMS 0xa
+#define ERR_EVENT_SERR0xb
+#define ERR_EVENT_NOMSI   0x10
+#define

[Qemu-devel] [PATCH 2/2] s390/pci: implement stpcifc instruction

2014-12-05 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements the last remaining s390 pci instruction
to query the function information block.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 hw/s390x/s390-pci-bus.h  |  1 +
 hw/s390x/s390-pci-inst.c | 64 
 hw/s390x/s390-pci-inst.h |  1 +
 target-s390x/kvm.c   |  9 +--
 4 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index 2a9f735..35f4da5 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -223,6 +223,7 @@ typedef struct S390PCIBusDevice {
 uint64_t g_iota;
 uint64_t pba;
 uint64_t pal;
+uint64_t fmb_addr;
 uint8_t isc;
 uint16_t noi;
 uint8_t sum;
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 8648594..f503665 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -766,6 +766,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t 
fiba)
 pbdev-lgstg_blocked = false;
 break;
 case ZPCI_MOD_FC_SET_MEASURE:
+pbdev-fmb_addr = ldq_p(fib.fmb_addr);
 break;
 default:
 program_interrupt(cpu-env, PGM_OPERAND, 6);
@@ -775,3 +776,66 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t 
fiba)
 setcc(cpu, cc);
 return 0;
 }
+
+int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
+{
+CPUS390XState *env = cpu-env;
+uint32_t fh;
+ZpciFib fib;
+S390PCIBusDevice *pbdev;
+uint32_t data;
+uint64_t cc = ZPCI_PCI_LS_OK;
+
+cpu_synchronize_state(CPU(cpu));
+
+if (env-psw.mask  PSW_MASK_PSTATE) {
+program_interrupt(env, PGM_PRIVILEGED, 6);
+return 0;
+}
+
+fh = env-regs[r1]  32;
+
+if (fiba  0x7) {
+program_interrupt(env, PGM_SPECIFICATION, 6);
+return 0;
+}
+
+pbdev = s390_pci_find_dev_by_fh(fh);
+if (!pbdev) {
+setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
+return 0;
+}
+
+memset(fib, 0, sizeof(fib));
+stq_p(fib.pba, pbdev-pba);
+stq_p(fib.pal, pbdev-pal);
+stq_p(fib.iota, pbdev-g_iota);
+stq_p(fib.aibv, pbdev-routes.adapter.ind_addr);
+stq_p(fib.aisb, pbdev-routes.adapter.summary_addr);
+stq_p(fib.fmb_addr, pbdev-fmb_addr);
+
+data = (pbdev-isc  28) | (pbdev-noi  16) |
+   (pbdev-routes.adapter.ind_offset  8) | (pbdev-sum  7) |
+   pbdev-routes.adapter.summary_offset;
+stw_p(fib.data, data);
+
+if (pbdev-fh  ENABLE_BIT_OFFSET) {
+fib.fc |= 0x80;
+}
+
+if (pbdev-error_state) {
+fib.fc |= 0x40;
+}
+
+if (pbdev-lgstg_blocked) {
+fib.fc |= 0x20;
+}
+
+if (pbdev-g_iota) {
+fib.fc |= 0x10;
+}
+
+cpu_physical_memory_write(fiba, (uint8_t *)fib, sizeof(fib));
+setcc(cpu, cc);
+return 0;
+}
diff --git a/hw/s390x/s390-pci-inst.h b/hw/s390x/s390-pci-inst.h
index 609e3e0..1c2f458 100644
--- a/hw/s390x/s390-pci-inst.h
+++ b/hw/s390x/s390-pci-inst.h
@@ -283,5 +283,6 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r2);
 int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
 int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr);
 int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
+int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
 
 #endif
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 32af46b..b70d482 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -876,8 +876,13 @@ static int kvm_pcistg_service_call(S390CPU *cpu, struct 
kvm_run *run)
 
 static int kvm_stpcifc_service_call(S390CPU *cpu, struct kvm_run *run)
 {
-qemu_log_mask(LOG_UNIMP, STPCIFC missing\n);
-return 0;
+uint8_t r1 = (run-s390_sieic.ipa  0x00f0)  4;
+uint64_t fiba;
+
+cpu_synchronize_state(CPU(cpu));
+fiba = get_base_disp_rxy(cpu, run);
+
+return stpcifc_service_call(cpu, r1, fiba);
 }
 
 static int kvm_sic_service_call(S390CPU *cpu, struct kvm_run *run)
-- 
1.8.5.5




[Qemu-devel] [PATCH 3/3 V1] kvm: extend kvm_irqchip_add_msi_route to work on s390

2014-11-26 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

on s390 MSI-X irqs are presented as thin or adapter interrupts
for this we have to reorganize the routing entry to contain
valid information for the adapter interrupt code on s390.
To minimize impact on existing code we introduce an architecture
function to fixup the routing entry.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 include/sysemu/kvm.h |  4 
 kvm-all.c|  7 +++
 target-arm/kvm.c |  6 ++
 target-i386/kvm.c|  6 ++
 target-mips/kvm.c|  6 ++
 target-ppc/kvm.c |  6 ++
 target-s390x/kvm.c   | 26 ++
 7 files changed, 61 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index b0cd657..702dc93 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -148,6 +148,7 @@ extern bool kvm_readonly_mem_allowed;
 
 struct kvm_run;
 struct kvm_lapic_state;
+struct kvm_irq_routing_entry;
 
 typedef struct KVMCapabilityInfo {
 const char *name;
@@ -259,6 +260,9 @@ int kvm_arch_on_sigbus(int code, void *addr);
 
 void kvm_arch_init_irq_routing(KVMState *s);
 
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data);
+
 int kvm_set_irq(KVMState *s, int irq, int level);
 int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
 
diff --git a/kvm-all.c b/kvm-all.c
index 596e7ce..38589b3 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1208,6 +1208,10 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage 
msg)
 kroute.u.msi.address_lo = (uint32_t)msg.address;
 kroute.u.msi.address_hi = msg.address  32;
 kroute.u.msi.data = le32_to_cpu(msg.data);
+if (kvm_arch_fixup_msi_route(kroute, msg.address, msg.data)) {
+kvm_irqchip_release_virq(s, virq);
+return -EINVAL;
+}
 
 kvm_add_routing_entry(s, kroute);
 kvm_irqchip_commit_routes(s);
@@ -1233,6 +1237,9 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, 
MSIMessage msg)
 kroute.u.msi.address_lo = (uint32_t)msg.address;
 kroute.u.msi.address_hi = msg.address  32;
 kroute.u.msi.data = le32_to_cpu(msg.data);
+if (kvm_arch_fixup_msi_route(kroute, msg.address, msg.data)) {
+return -EINVAL;
+}
 
 return kvm_update_routing_entry(s, kroute);
 }
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 319784d..3285f81 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -441,3 +441,9 @@ int kvm_arch_irqchip_create(KVMState *s)
 
 return 0;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index ccf36e8..7bc818c 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -2707,3 +2707,9 @@ int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id)
 return kvm_deassign_irq_internal(s, dev_id, KVM_DEV_IRQ_GUEST_MSIX |
 KVM_DEV_IRQ_HOST_MSIX);
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 97fd51a..c7eb1dc 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -688,3 +688,9 @@ int kvm_arch_get_registers(CPUState *cs)
 
 return ret;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 6843fa0..04c83cd 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -2388,3 +2388,9 @@ out_close:
 error_out:
 return;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 1b62257..32af46b 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -41,6 +41,7 @@
 #include trace.h
 #include qapi-event.h
 #include hw/s390x/s390-pci-inst.h
+#include hw/s390x/s390-pci-bus.h
 
 /* #define DEBUG_KVM */
 
@@ -1510,3 +1511,28 @@ int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t 
cpu_state)
 
 return ret;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+  uint64_t address, uint32_t data)
+{
+S390PCIBusDevice *pbdev;
+uint32_t fid = data  ZPCI_MSI_VEC_BITS;
+uint32_t vec = data  ZPCI_MSI_VEC_MASK;
+
+pbdev = s390_pci_find_dev_by_fid(fid);
+if (!pbdev) {
+DPRINTF(add_msi_route no dev\n);
+return -ENODEV;
+}
+
+pbdev-routes.adapter.ind_offset = vec;
+
+route-type = KVM_IRQ_ROUTING_S390_ADAPTER;
+route-flags = 0;
+route-u.adapter.summary_addr = pbdev-routes.adapter.summary_addr;
+route-u.adapter.ind_addr = pbdev-routes.adapter.ind_addr;
+route-u.adapter.summary_offset = pbdev

[Qemu-devel] [PATCH 0/3 V1] add PCI support for the s390 platform

2014-11-26 Thread Frank Blaschka
This set of patches implemets PCI support for the s390 platform.
Now it is possible to run virtio-net-pci and potentially all
virtual pci devices conforming to s390 platform constrains.

V1 added lot of feedback from Alex Graf
   fixed tons of endian issues

Please review and consider for integration into 2.3

Thanks,

Frank

Frank Blaschka (3):
  s390: Add PCI bus support
  s390: implement pci instructions
  kvm: extend kvm_irqchip_add_msi_route to work on s390

 default-configs/s390x-softmmu.mak |   1 +
 hw/s390x/Makefile.objs|   1 +
 hw/s390x/css.c|   5 +
 hw/s390x/css.h|   1 +
 hw/s390x/s390-pci-bus.c   | 554 +
 hw/s390x/s390-pci-bus.h   | 217 
 hw/s390x/s390-pci-inst.c  | 711 ++
 hw/s390x/s390-pci-inst.h  | 287 +++
 hw/s390x/s390-virtio-ccw.c|   7 +
 hw/s390x/sclp.c   |  10 +-
 include/hw/s390x/sclp.h   |   8 +
 include/sysemu/kvm.h  |   4 +
 kvm-all.c |   7 +
 target-arm/kvm.c  |   6 +
 target-i386/kvm.c |   6 +
 target-mips/kvm.c |   6 +
 target-ppc/kvm.c  |   6 +
 target-s390x/ioinst.c |  52 +++
 target-s390x/ioinst.h |   1 +
 target-s390x/kvm.c| 174 ++
 20 files changed, 2063 insertions(+), 1 deletion(-)
 create mode 100644 hw/s390x/s390-pci-bus.c
 create mode 100644 hw/s390x/s390-pci-bus.h
 create mode 100644 hw/s390x/s390-pci-inst.c
 create mode 100644 hw/s390x/s390-pci-inst.h

-- 
1.8.5.5




[Qemu-devel] [PATCH 1/3 V1] s390: Add PCI bus support

2014-11-26 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements a pci bus for s390x together with infrastructure
to generate and handle hotplug events, to configure/unconfigure via
sclp instruction, to do iommu translations and provide s390 support for
MSI/MSI-X notification processing.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 default-configs/s390x-softmmu.mak |   1 +
 hw/s390x/Makefile.objs|   1 +
 hw/s390x/css.c|   5 +
 hw/s390x/css.h|   1 +
 hw/s390x/s390-pci-bus.c   | 554 ++
 hw/s390x/s390-pci-bus.h   | 217 +++
 hw/s390x/s390-virtio-ccw.c|   7 +
 hw/s390x/sclp.c   |  10 +-
 include/hw/s390x/sclp.h   |   8 +
 target-s390x/ioinst.c |  52 
 target-s390x/ioinst.h |   1 +
 11 files changed, 856 insertions(+), 1 deletion(-)
 create mode 100644 hw/s390x/s390-pci-bus.c
 create mode 100644 hw/s390x/s390-pci-bus.h

diff --git a/default-configs/s390x-softmmu.mak 
b/default-configs/s390x-softmmu.mak
index 126d88d..6ee2ff8 100644
--- a/default-configs/s390x-softmmu.mak
+++ b/default-configs/s390x-softmmu.mak
@@ -1,3 +1,4 @@
+include pci.mak
 CONFIG_VIRTIO=y
 CONFIG_SCLPCONSOLE=y
 CONFIG_S390_FLIC=y
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 1ba6c3a..428d957 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -8,3 +8,4 @@ obj-y += ipl.o
 obj-y += css.o
 obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
+obj-y += s390-pci-bus.o
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index b67c039..7553085 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1299,6 +1299,11 @@ void css_generate_chp_crws(uint8_t cssid, uint8_t chpid)
 /* TODO */
 }
 
+void css_generate_css_crws(uint8_t cssid)
+{
+css_queue_crw(CRW_RSC_CSS, 0, 0, 0);
+}
+
 int css_enable_mcsse(void)
 {
 trace_css_enable_facility(mcsse);
diff --git a/hw/s390x/css.h b/hw/s390x/css.h
index 33104ac..7e53148 100644
--- a/hw/s390x/css.h
+++ b/hw/s390x/css.h
@@ -101,6 +101,7 @@ void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, 
uint16_t rsid);
 void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
int hotplugged, int add);
 void css_generate_chp_crws(uint8_t cssid, uint8_t chpid);
+void css_generate_css_crws(uint8_t cssid);
 void css_adapter_interrupt(uint8_t isc);
 
 #define CSS_IO_ADAPTER_VIRTIO 1
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
new file mode 100644
index 000..06d153a
--- /dev/null
+++ b/hw/s390x/s390-pci-bus.c
@@ -0,0 +1,554 @@
+/*
+ * s390 PCI BUS
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include hw/pci/pci.h
+#include hw/pci/pci_bus.h
+#include hw/s390x/css.h
+#include hw/s390x/sclp.h
+#include hw/pci/msi.h
+#include qemu/error-report.h
+#include s390-pci-bus.h
+
+/* #define DEBUG_S390PCI_BUS */
+#ifdef DEBUG_S390PCI_BUS
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, S390pci-bus:  fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+int chsc_sei_nt2_get_event(void *res)
+{
+ChscSeiNt2Res *nt2_res = (ChscSeiNt2Res *)res;
+PciCcdfAvail *accdf;
+PciCcdfErr *eccdf;
+int rc = 1;
+SeiContainer *sei_cont;
+S390pciState *s = S390_PCI_HOST_BRIDGE(
+object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
+
+if (!s) {
+return rc;
+}
+
+sei_cont = QTAILQ_FIRST(s-pending_sei);
+if (sei_cont) {
+QTAILQ_REMOVE(s-pending_sei, sei_cont, link);
+nt2_res-nt = 2;
+nt2_res-cc = sei_cont-cc;
+switch (sei_cont-cc) {
+case 1: /* error event */
+eccdf = (PciCcdfErr *)nt2_res-ccdf;
+eccdf-fid = cpu_to_be32(sei_cont-fid);
+eccdf-fh = cpu_to_be32(sei_cont-fh);
+break;
+case 2: /* availability event */
+accdf = (PciCcdfAvail *)nt2_res-ccdf;
+accdf-fid = cpu_to_be32(sei_cont-fid);
+accdf-fh = cpu_to_be32(sei_cont-fh);
+accdf-pec = cpu_to_be16(sei_cont-pec);
+break;
+default:
+abort();
+}
+g_free(sei_cont);
+rc = 0;
+}
+
+return rc;
+}
+
+int chsc_sei_nt2_have_event(void)
+{
+S390pciState *s = S390_PCI_HOST_BRIDGE(
+object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
+
+if (!s) {
+return 0;
+}
+
+return !QTAILQ_EMPTY(s-pending_sei);
+}
+
+S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid)
+{
+S390PCIBusDevice *pbdev;
+int i;
+S390pciState *s = S390_PCI_HOST_BRIDGE

[Qemu-devel] [PATCH 2/3 V1] s390: implement pci instructions

2014-11-26 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements the s390 pci instructions in qemu. It allows
to access and drive pci devices attached to the s390 pci bus.
Because of platform constrains devices using IO BARs are not
supported. Also a device has to support MSI/MSI-X to run on s390.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 hw/s390x/Makefile.objs   |   2 +-
 hw/s390x/s390-pci-inst.c | 711 +++
 hw/s390x/s390-pci-inst.h | 287 +++
 target-s390x/kvm.c   | 148 ++
 4 files changed, 1147 insertions(+), 1 deletion(-)
 create mode 100644 hw/s390x/s390-pci-inst.c
 create mode 100644 hw/s390x/s390-pci-inst.h

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 428d957..27cd75a 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -8,4 +8,4 @@ obj-y += ipl.o
 obj-y += css.o
 obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
-obj-y += s390-pci-bus.o
+obj-y += s390-pci-bus.o s390-pci-inst.o
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
new file mode 100644
index 000..e233046
--- /dev/null
+++ b/hw/s390x/s390-pci-inst.c
@@ -0,0 +1,711 @@
+/*
+ * s390 PCI instructions
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include sys/types.h
+#include sys/ioctl.h
+#include sys/mman.h
+
+#include linux/kvm.h
+#include asm/ptrace.h
+#include hw/pci/pci.h
+#include hw/pci/pci_host.h
+#include net/net.h
+
+#include qemu-common.h
+#include qemu/timer.h
+#include migration/qemu-file.h
+#include sysemu/sysemu.h
+#include sysemu/kvm.h
+#include cpu.h
+#include sysemu/device_tree.h
+#include monitor/monitor.h
+#include s390-pci-inst.h
+
+#include hw/hw.h
+#include hw/pci/pci.h
+#include hw/pci/pci_bridge.h
+#include hw/pci/pci_bus.h
+#include hw/pci/pci_host.h
+#include hw/s390x/s390-pci-bus.h
+#include exec/exec-all.h
+#include exec/memory-internal.h
+
+/* #define DEBUG_S390PCI_INST */
+#ifdef DEBUG_S390PCI_INST
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, s390pci-inst:  fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+static void s390_set_status_code(CPUS390XState *env,
+ uint8_t r, uint64_t status_code)
+{
+env-regs[r] = ~0xff00ULL;
+env-regs[r] |= (status_code  0xff)  24;
+}
+
+static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc)
+{
+S390PCIBusDevice *pbdev;
+uint32_t res_code, initial_l2, g_l2, finish;
+int rc, idx;
+uint64_t resume_token;
+
+rc = 0;
+if (lduw_p(rrb-request.hdr.len) != 32) {
+res_code = CLP_RC_LEN;
+rc = -EINVAL;
+goto out;
+}
+
+if ((ldl_p(rrb-request.fmt)  CLP_MASK_FMT) != 0) {
+res_code = CLP_RC_FMT;
+rc = -EINVAL;
+goto out;
+}
+
+if ((ldl_p(rrb-request.fmt)  ~CLP_MASK_FMT) != 0 ||
+ldq_p(rrb-request.reserved1) != 0 ||
+ldq_p(rrb-request.reserved2) != 0) {
+res_code = CLP_RC_RESNOT0;
+rc = -EINVAL;
+goto out;
+}
+
+resume_token = ldq_p(rrb-request.resume_token);
+
+if (resume_token) {
+pbdev = s390_pci_find_dev_by_idx(resume_token);
+if (!pbdev) {
+res_code = CLP_RC_LISTPCI_BADRT;
+rc = -EINVAL;
+goto out;
+}
+}
+
+if (lduw_p(rrb-response.hdr.len)  48) {
+res_code = CLP_RC_8K;
+rc = -EINVAL;
+goto out;
+}
+
+initial_l2 = lduw_p(rrb-response.hdr.len);
+if ((initial_l2 - LIST_PCI_HDR_LEN) % sizeof(ClpFhListEntry)
+!= 0) {
+res_code = CLP_RC_LEN;
+rc = -EINVAL;
+*cc = 3;
+goto out;
+}
+
+stl_p(rrb-response.fmt, 0);
+stq_p(rrb-response.reserved1, 0);
+stq_p(rrb-response.reserved2, 0);
+stl_p(rrb-response.mdd, FH_VIRT);
+stw_p(rrb-response.max_fn, PCI_MAX_FUNCTIONS);
+rrb-response.entry_size = sizeof(ClpFhListEntry);
+finish = 0;
+idx = resume_token;
+g_l2 = LIST_PCI_HDR_LEN;
+do {
+pbdev = s390_pci_find_dev_by_idx(idx);
+if (!pbdev) {
+finish = 1;
+break;
+}
+stw_p(rrb-response.fh_list[idx - resume_token].device_id,
+pci_get_word(pbdev-pdev-config + PCI_DEVICE_ID));
+stw_p(rrb-response.fh_list[idx - resume_token].vendor_id,
+pci_get_word(pbdev-pdev-config + PCI_VENDOR_ID));
+stl_p(rrb-response.fh_list[idx - resume_token].config, 0x8000);
+stl_p(rrb-response.fh_list[idx - resume_token].fid, pbdev-fid);
+stl_p(rrb-response.fh_list[idx - resume_token].fh, pbdev-fh);
+
+g_l2 += sizeof(ClpFhListEntry

Re: [Qemu-devel] [PATCH 1/3] s390: Add PCI bus support

2014-11-25 Thread Frank Blaschka
On Tue, Nov 18, 2014 at 06:00:40PM +0100, Alexander Graf wrote:
 
 
 On 18.11.14 13:50, Frank Blaschka wrote:
  On Mon, Nov 10, 2014 at 04:14:16PM +0100, Alexander Graf wrote:
 
 
  On 10.11.14 15:20, Frank Blaschka wrote:
  From: Frank Blaschka frank.blasc...@de.ibm.com
 
  This patch implements a pci bus for s390x together with infrastructure
  to generate and handle hotplug events, to configure/unconfigure via
  sclp instruction, to do iommu translations and provide s390 support for
  MSI/MSI-X notification processing.
 
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
 
 [...]
 
  diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
  new file mode 100644
  index 000..f2fa6ba
  --- /dev/null
  +++ b/hw/s390x/s390-pci-bus.c
  @@ -0,0 +1,485 @@
  +/*
  + * s390 PCI BUS
  + *
  + * Copyright 2014 IBM Corp.
  + * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
  + *Hong Bo Li lih...@cn.ibm.com
  + *Yi Min Zhao zyi...@cn.ibm.com
  + *
  + * This work is licensed under the terms of the GNU GPL, version 2 or (at
  + * your option) any later version. See the COPYING file in the top-level
  + * directory.
  + */
  +
  +#include hw/pci/pci.h
  +#include hw/pci/pci_bus.h
  +#include hw/s390x/css.h
  +#include hw/s390x/sclp.h
  +#include hw/pci/msi.h
  +#include qemu/error-report.h
  +#include s390-pci-bus.h
  +
  +/* #define DEBUG_S390PCI_BUS */
  +#ifdef DEBUG_S390PCI_BUS
  +#define DPRINTF(fmt, ...) \
  +do { fprintf(stderr, S390pci-bus:  fmt, ## __VA_ARGS__); } while 
  (0)
  +#else
  +#define DPRINTF(fmt, ...) \
  +do { } while (0)
  +#endif
  +
  +static const unsigned long be_to_le = BITS_PER_LONG - 1;
  +static QTAILQ_HEAD(, SeiContainer) pending_sei =
  +QTAILQ_HEAD_INITIALIZER(pending_sei);
  +static QTAILQ_HEAD(, S390PCIBusDevice) device_list =
  +QTAILQ_HEAD_INITIALIZER(device_list);
 
  Please get rid of all statics ;). All state has to live in objects.
 
  
  be_to_le was misleading and unnecesary will remove this one but
  static QTAILQ_HEAD seems to be a common practice for list anchors.
  If you really want me to change this do you have any prefered way,
  or can you point me to some code doing this?
 
 For PCI devices, I don't think you need a list at all. Your PHB device
 should already have a proper qbus that knows about all its child devices.

OK

 
 As for pending_sei, what is this about?


This is a queue to store events (StoreEventInformation) used for hotplug
support. In case a device is pluged/unpluged an event is stored to this queue
and the guest is notified. Then the guest pick up the event information via
chsc instruction.
 
  
  +
  +int chsc_sei_nt2_get_event(void *res)
 
 [...]
 
  +
  +int chsc_sei_nt2_get_event(void *res);
  +int chsc_sei_nt2_have_event(void);
  +void s390_pci_sclp_configure(int configure, SCCB *sccb);
  +S390PCIBusDevice *s390_pci_find_dev_by_idx(uint32_t idx);
  +S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh);
  +S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid);
 
  I think it makes sense to pass the PHB device as parameter on these.
  Don't assume you only have one.
  
  We need to lookup our device mainly in the instruction handlers and there
  we do not have a PHB available.
 
 Then have a way to find your PHB - either put a variable into the
 machine object, or find it by path via QOM tree lookups. Maybe we need
 multiple PHBs, identified by part of the ID? I know too little about the
 way PCI works on s390x to really tell.
 
 Again, are there specs?


Yes there are, but unfortunately they are not public.
 
  Also having one list for our S390PCIBusDevices
  devices does not prevent us from supporting more PHBs.
  
 
  +void s390_pci_bus_init(void);
  +uint64_t s390_pci_get_table_origin(uint64_t iota);
  +uint64_t s390_guest_io_table_walk(uint64_t guest_iota,
  +  uint64_t guest_dma_address);
 
  Why are these exported?
 
  +
  +#endif
  diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
  index bc4dc2a..2e25834 100644
  --- a/hw/s390x/s390-virtio-ccw.c
  +++ b/hw/s390x/s390-virtio-ccw.c
  @@ -18,6 +18,7 @@
   #include css.h
   #include virtio-ccw.h
   #include qemu/config-file.h
  +#include s390-pci-bus.h
   
   #define TYPE_S390_CCW_MACHINE   s390-ccw-machine
   
  @@ -127,6 +128,8 @@ static void ccw_init(MachineState *machine)
 machine-initrd_filename, s390-ccw.img);
   s390_flic_init();
   
  +s390_pci_bus_init();
 
  Please just inline that function here.
 
  
  What do you mean by just inline?
 
 The contents of the s390_pci_bus_init() function should just be standing
 right here. There's no value in creating a public wrapper function for
 initialization. We only did this back in the old days before qdev was
 around, because initialization was difficult back then and some devices
 didn't make the jump to get rid of their public init functions.
 
  
  +
   /* register

Re: [Qemu-devel] [PATCH 1/3] s390: Add PCI bus support

2014-11-25 Thread Frank Blaschka
On Tue, Nov 25, 2014 at 01:14:01PM +0100, Alexander Graf wrote:
 
 
 On 25.11.14 11:11, Frank Blaschka wrote:
  On Tue, Nov 18, 2014 at 06:00:40PM +0100, Alexander Graf wrote:
 
 
  On 18.11.14 13:50, Frank Blaschka wrote:
  On Mon, Nov 10, 2014 at 04:14:16PM +0100, Alexander Graf wrote:
 
 
  On 10.11.14 15:20, Frank Blaschka wrote:
  From: Frank Blaschka frank.blasc...@de.ibm.com
 
  This patch implements a pci bus for s390x together with infrastructure
  to generate and handle hotplug events, to configure/unconfigure via
  sclp instruction, to do iommu translations and provide s390 support for
  MSI/MSI-X notification processing.
 
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
 
  [...]
 
  diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
  new file mode 100644
  index 000..f2fa6ba
  --- /dev/null
  +++ b/hw/s390x/s390-pci-bus.c
  @@ -0,0 +1,485 @@
  +/*
  + * s390 PCI BUS
  + *
  + * Copyright 2014 IBM Corp.
  + * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
  + *Hong Bo Li lih...@cn.ibm.com
  + *Yi Min Zhao zyi...@cn.ibm.com
  + *
  + * This work is licensed under the terms of the GNU GPL, version 2 or 
  (at
  + * your option) any later version. See the COPYING file in the 
  top-level
  + * directory.
  + */
  +
  +#include hw/pci/pci.h
  +#include hw/pci/pci_bus.h
  +#include hw/s390x/css.h
  +#include hw/s390x/sclp.h
  +#include hw/pci/msi.h
  +#include qemu/error-report.h
  +#include s390-pci-bus.h
  +
  +/* #define DEBUG_S390PCI_BUS */
  +#ifdef DEBUG_S390PCI_BUS
  +#define DPRINTF(fmt, ...) \
  +do { fprintf(stderr, S390pci-bus:  fmt, ## __VA_ARGS__); } while 
  (0)
  +#else
  +#define DPRINTF(fmt, ...) \
  +do { } while (0)
  +#endif
  +
  +static const unsigned long be_to_le = BITS_PER_LONG - 1;
  +static QTAILQ_HEAD(, SeiContainer) pending_sei =
  +QTAILQ_HEAD_INITIALIZER(pending_sei);
  +static QTAILQ_HEAD(, S390PCIBusDevice) device_list =
  +QTAILQ_HEAD_INITIALIZER(device_list);
 
  Please get rid of all statics ;). All state has to live in objects.
 
 
  be_to_le was misleading and unnecesary will remove this one but
  static QTAILQ_HEAD seems to be a common practice for list anchors.
  If you really want me to change this do you have any prefered way,
  or can you point me to some code doing this?
 
  For PCI devices, I don't think you need a list at all. Your PHB device
  should already have a proper qbus that knows about all its child devices.
  
  OK
  
 
  As for pending_sei, what is this about?
 
  
  This is a queue to store events (StoreEventInformation) used for hotplug
  support. In case a device is pluged/unpluged an event is stored to this 
  queue
  and the guest is notified. Then the guest pick up the event information via
  chsc instruction.
 
 Is this for overall CCW or only for PCI? Depending on the answer, you
 can put the sei event list into the respective parent device.


An NT2 event is pci specific. So I moved the queue for NT2 events to the PHB as 
well.

 
 Alex
 




Re: [Qemu-devel] [PATCH 1/3] s390: Add PCI bus support

2014-11-18 Thread Frank Blaschka
On Mon, Nov 10, 2014 at 04:14:16PM +0100, Alexander Graf wrote:
 
 
 On 10.11.14 15:20, Frank Blaschka wrote:
  From: Frank Blaschka frank.blasc...@de.ibm.com
  
  This patch implements a pci bus for s390x together with infrastructure
  to generate and handle hotplug events, to configure/unconfigure via
  sclp instruction, to do iommu translations and provide s390 support for
  MSI/MSI-X notification processing.
  
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
  ---
   default-configs/s390x-softmmu.mak |   1 +
   hw/s390x/Makefile.objs|   1 +
   hw/s390x/css.c|   5 +
   hw/s390x/css.h|   1 +
   hw/s390x/s390-pci-bus.c   | 485 
  ++
   hw/s390x/s390-pci-bus.h   | 254 
   hw/s390x/s390-virtio-ccw.c|   3 +
   hw/s390x/sclp.c   |  10 +-
   include/hw/s390x/sclp.h   |   8 +
   target-s390x/ioinst.c |  52 
   target-s390x/ioinst.h |   1 +
   11 files changed, 820 insertions(+), 1 deletion(-)
   create mode 100644 hw/s390x/s390-pci-bus.c
   create mode 100644 hw/s390x/s390-pci-bus.h
  
  diff --git a/default-configs/s390x-softmmu.mak 
  b/default-configs/s390x-softmmu.mak
  index 126d88d..6ee2ff8 100644
  --- a/default-configs/s390x-softmmu.mak
  +++ b/default-configs/s390x-softmmu.mak
  @@ -1,3 +1,4 @@
  +include pci.mak
   CONFIG_VIRTIO=y
   CONFIG_SCLPCONSOLE=y
   CONFIG_S390_FLIC=y
  diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
  index 1ba6c3a..428d957 100644
  --- a/hw/s390x/Makefile.objs
  +++ b/hw/s390x/Makefile.objs
  @@ -8,3 +8,4 @@ obj-y += ipl.o
   obj-y += css.o
   obj-y += s390-virtio-ccw.o
   obj-y += virtio-ccw.o
  +obj-y += s390-pci-bus.o
  diff --git a/hw/s390x/css.c b/hw/s390x/css.c
  index b67c039..7553085 100644
  --- a/hw/s390x/css.c
  +++ b/hw/s390x/css.c
  @@ -1299,6 +1299,11 @@ void css_generate_chp_crws(uint8_t cssid, uint8_t 
  chpid)
   /* TODO */
   }
   
  +void css_generate_css_crws(uint8_t cssid)
  +{
  +css_queue_crw(CRW_RSC_CSS, 0, 0, 0);
  +}
  +
   int css_enable_mcsse(void)
   {
   trace_css_enable_facility(mcsse);
  diff --git a/hw/s390x/css.h b/hw/s390x/css.h
  index 33104ac..7e53148 100644
  --- a/hw/s390x/css.h
  +++ b/hw/s390x/css.h
  @@ -101,6 +101,7 @@ void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, 
  uint16_t rsid);
   void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
  int hotplugged, int add);
   void css_generate_chp_crws(uint8_t cssid, uint8_t chpid);
  +void css_generate_css_crws(uint8_t cssid);
   void css_adapter_interrupt(uint8_t isc);
   
   #define CSS_IO_ADAPTER_VIRTIO 1
  diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
  new file mode 100644
  index 000..f2fa6ba
  --- /dev/null
  +++ b/hw/s390x/s390-pci-bus.c
  @@ -0,0 +1,485 @@
  +/*
  + * s390 PCI BUS
  + *
  + * Copyright 2014 IBM Corp.
  + * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
  + *Hong Bo Li lih...@cn.ibm.com
  + *Yi Min Zhao zyi...@cn.ibm.com
  + *
  + * This work is licensed under the terms of the GNU GPL, version 2 or (at
  + * your option) any later version. See the COPYING file in the top-level
  + * directory.
  + */
  +
  +#include hw/pci/pci.h
  +#include hw/pci/pci_bus.h
  +#include hw/s390x/css.h
  +#include hw/s390x/sclp.h
  +#include hw/pci/msi.h
  +#include qemu/error-report.h
  +#include s390-pci-bus.h
  +
  +/* #define DEBUG_S390PCI_BUS */
  +#ifdef DEBUG_S390PCI_BUS
  +#define DPRINTF(fmt, ...) \
  +do { fprintf(stderr, S390pci-bus:  fmt, ## __VA_ARGS__); } while (0)
  +#else
  +#define DPRINTF(fmt, ...) \
  +do { } while (0)
  +#endif
  +
  +static const unsigned long be_to_le = BITS_PER_LONG - 1;
  +static QTAILQ_HEAD(, SeiContainer) pending_sei =
  +QTAILQ_HEAD_INITIALIZER(pending_sei);
  +static QTAILQ_HEAD(, S390PCIBusDevice) device_list =
  +QTAILQ_HEAD_INITIALIZER(device_list);
 
 Please get rid of all statics ;). All state has to live in objects.


be_to_le was misleading and unnecesary will remove this one but
static QTAILQ_HEAD seems to be a common practice for list anchors.
If you really want me to change this do you have any prefered way,
or can you point me to some code doing this?

  +
  +int chsc_sei_nt2_get_event(void *res)
  +{
  +ChscSeiNt2Res *nt2_res = (ChscSeiNt2Res *)res;
  +PciCcdfAvail *accdf;
  +PciCcdfErr *eccdf;
  +int rc = 1;
  +SeiContainer *sei_cont;
  +
  +sei_cont = QTAILQ_FIRST(pending_sei);
  +if (sei_cont) {
  +QTAILQ_REMOVE(pending_sei, sei_cont, link);
  +nt2_res-nt = 2;
  +nt2_res-cc = sei_cont-cc;
  +switch (sei_cont-cc) {
  +case 1: /* error event */
  +eccdf = (PciCcdfErr *)nt2_res-ccdf;
  +eccdf-fid = cpu_to_be32(sei_cont-fid);
  +eccdf-fh = cpu_to_be32(sei_cont-fh);
  +break

Re: [Qemu-devel] [PATCH 2/3] s390: implement pci instructions

2014-11-12 Thread Frank Blaschka
On Tue, Nov 11, 2014 at 04:24:24PM +0100, Alexander Graf wrote:
 
 
 On 11.11.14 15:08, Frank Blaschka wrote:
  On Tue, Nov 11, 2014 at 01:51:25PM +0100, Alexander Graf wrote:
 
 
 
  Am 11.11.2014 um 13:39 schrieb Frank Blaschka 
  blasc...@linux.vnet.ibm.com:
 
  On Tue, Nov 11, 2014 at 01:16:04PM +0100, Alexander Graf wrote:
 
 
  On 11.11.14 13:10, Frank Blaschka wrote:
  On Mon, Nov 10, 2014 at 04:56:21PM +0100, Alexander Graf wrote:
 
 
  On 10.11.14 15:20, Frank Blaschka wrote:
  From: Frank Blaschka frank.blasc...@de.ibm.com
 
  This patch implements the s390 pci instructions in qemu. It allows
  to access and drive pci devices attached to the s390 pci bus.
  Because of platform constrains devices using IO BARs are not
  supported. Also a device has to support MSI/MSI-X to run on s390.
 
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
  ---
  target-s390x/Makefile.objs |   2 +-
  target-s390x/kvm.c |  52 
  target-s390x/pci_ic.c  | 753 
  +
  target-s390x/pci_ic.h  | 335 
  4 files changed, 1141 insertions(+), 1 deletion(-)
  create mode 100644 target-s390x/pci_ic.c
  create mode 100644 target-s390x/pci_ic.h
 
 
  [...]
 
  +int kvm_pcilg_service_call(S390CPU *cpu, struct kvm_run *run)
  +{
  +CPUS390XState *env = cpu-env;
  +S390PCIBusDevice *pbdev;
  +uint8_t r1 = (run-s390_sieic.ipb  0x00f0)  20;
  +uint8_t r2 = (run-s390_sieic.ipb  0x000f)  16;
  +PciLgStg *rp;
  +uint64_t offset;
  +uint64_t data;
  +uint8_t len;
  +
  +cpu_synchronize_state(CPU(cpu));
  +
  +if (env-psw.mask  PSW_MASK_PSTATE) {
  +program_interrupt(env, PGM_PRIVILEGED, 4);
  +return 0;
  +}
  +
  +if (r2  0x1) {
  +program_interrupt(env, PGM_SPECIFICATION, 4);
  +return 0;
  +}
  +
  +rp = (PciLgStg *)env-regs[r2];
  +offset = env-regs[r2 + 1];
  +
  +pbdev = s390_pci_find_dev_by_fh(rp-fh);
  +if (!pbdev) {
  +DPRINTF(pcilg no pci dev\n);
  +setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
  +return 0;
  +}
  +
  +len = rp-len  0xF;
  +if (rp-pcias  6) {
  +if ((8 - (offset  0x7))  len) {
  +program_interrupt(env, PGM_OPERAND, 4);
  +return 0;
  +}
  +MemoryRegion *mr = pbdev-pdev-io_regions[rp-pcias].memory;
  +io_mem_read(mr, offset, data, len);
  +} else if (rp-pcias == 15) {
  +if ((4 - (offset  0x3))  len) {
  +program_interrupt(env, PGM_OPERAND, 4);
  +return 0;
  +}
  +data =  pci_host_config_read_common(
  +   pbdev-pdev, offset, 
  pci_config_size(pbdev-pdev), len);
  +
  +switch (len) {
  +case 1:
  +break;
  +case 2:
  +data = cpu_to_le16(data);
  +break;
  +case 4:
  +data = cpu_to_le32(data);
  +break;
  +case 8:
  +data = cpu_to_le64(data);
  +break;
 
  Why? Also, this is wrong. cpu_to_le64 convert between host endianness
  and LE. So if you're running this on an LE host, you won't swap the
  value and get a broken result.
 
  If you know that the value is always swapped, use bswapxx().
 
 
  Actually the code is right and required for a big endian host :-)
  pcilg/pcistg provide access to the PCI config space which is defined
  as PCI byte order (little endian). Since pci_host_config_read_common 
  does
  already a le to cpu conversion we have to convert back to PCI byte 
  order.
  Doing an unconditional swap would be a bug on a little endian host.
 
  Why would it be a bug? The value you end up writing is contents of a
  register and thus doesn't have endianness. So if QEMU was an LE process,
 
  No, the s390 guest executing pcilg instruction expects to receive config 
  space data
  in PCI byte order.
 
  the value of data would be identical as on a BE QEMU before your swab.
  After the swab, it would be bswap'ed on BE, but not LE. So LE hosts 
  break.
 
 
  Again on BE endian host we do the swap because of 
  pci_host_config_read_common does
  read the value and do a byte swap for that value, but we need PCI byte 
  order not BE here.
 
  On LE host pci_host_config_read_common does not do a byte swap so we do 
  not have to
  convert back to PCI byte order.
 
  We maintain the PCI config space always in LE byte order in memory, that's 
  why there is a bwap in its read function. The return result of the read 
  function however is always the same, regardless of LE or BE host. If I do 
  a read of size 4, I will always get 0x1, not 0x0100 returned.
 
  So now you need to convert that 0x1 into a 0x0100 manually here 
  because some architect thought that registers have endianness (which they 
  don't). But you need to do it always, even on an LE host, because the pci 
  config space return value is identical on LE and BE.
 
  so you

Re: [Qemu-devel] [PATCH 2/3] s390: implement pci instructions

2014-11-12 Thread Frank Blaschka
On Wed, Nov 12, 2014 at 10:08:19AM +0100, Alexander Graf wrote:
 
 
 On 12.11.14 09:49, Frank Blaschka wrote:
  On Tue, Nov 11, 2014 at 04:24:24PM +0100, Alexander Graf wrote:
 
 
  On 11.11.14 15:08, Frank Blaschka wrote:
  On Tue, Nov 11, 2014 at 01:51:25PM +0100, Alexander Graf wrote:
 
 
 
  Am 11.11.2014 um 13:39 schrieb Frank Blaschka 
  blasc...@linux.vnet.ibm.com:
 
  On Tue, Nov 11, 2014 at 01:16:04PM +0100, Alexander Graf wrote:
 
 
  On 11.11.14 13:10, Frank Blaschka wrote:
  On Mon, Nov 10, 2014 at 04:56:21PM +0100, Alexander Graf wrote:
 
 
  On 10.11.14 15:20, Frank Blaschka wrote:
  From: Frank Blaschka frank.blasc...@de.ibm.com
 
  This patch implements the s390 pci instructions in qemu. It allows
  to access and drive pci devices attached to the s390 pci bus.
  Because of platform constrains devices using IO BARs are not
  supported. Also a device has to support MSI/MSI-X to run on s390.
 
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
  ---
  target-s390x/Makefile.objs |   2 +-
  target-s390x/kvm.c |  52 
  target-s390x/pci_ic.c  | 753 
  +
  target-s390x/pci_ic.h  | 335 
  4 files changed, 1141 insertions(+), 1 deletion(-)
  create mode 100644 target-s390x/pci_ic.c
  create mode 100644 target-s390x/pci_ic.h
 
 
  [...]
 
  +int kvm_pcilg_service_call(S390CPU *cpu, struct kvm_run *run)
  +{
  +CPUS390XState *env = cpu-env;
  +S390PCIBusDevice *pbdev;
  +uint8_t r1 = (run-s390_sieic.ipb  0x00f0)  20;
  +uint8_t r2 = (run-s390_sieic.ipb  0x000f)  16;
  +PciLgStg *rp;
  +uint64_t offset;
  +uint64_t data;
  +uint8_t len;
  +
  +cpu_synchronize_state(CPU(cpu));
  +
  +if (env-psw.mask  PSW_MASK_PSTATE) {
  +program_interrupt(env, PGM_PRIVILEGED, 4);
  +return 0;
  +}
  +
  +if (r2  0x1) {
  +program_interrupt(env, PGM_SPECIFICATION, 4);
  +return 0;
  +}
  +
  +rp = (PciLgStg *)env-regs[r2];
  +offset = env-regs[r2 + 1];
  +
  +pbdev = s390_pci_find_dev_by_fh(rp-fh);
  +if (!pbdev) {
  +DPRINTF(pcilg no pci dev\n);
  +setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
  +return 0;
  +}
  +
  +len = rp-len  0xF;
  +if (rp-pcias  6) {
  +if ((8 - (offset  0x7))  len) {
  +program_interrupt(env, PGM_OPERAND, 4);
  +return 0;
  +}
  +MemoryRegion *mr = 
  pbdev-pdev-io_regions[rp-pcias].memory;
  +io_mem_read(mr, offset, data, len);
  +} else if (rp-pcias == 15) {
  +if ((4 - (offset  0x3))  len) {
  +program_interrupt(env, PGM_OPERAND, 4);
  +return 0;
  +}
  +data =  pci_host_config_read_common(
  +   pbdev-pdev, offset, 
  pci_config_size(pbdev-pdev), len);
  +
  +switch (len) {
  +case 1:
  +break;
  +case 2:
  +data = cpu_to_le16(data);
  +break;
  +case 4:
  +data = cpu_to_le32(data);
  +break;
  +case 8:
  +data = cpu_to_le64(data);
  +break;
 
  Why? Also, this is wrong. cpu_to_le64 convert between host endianness
  and LE. So if you're running this on an LE host, you won't swap the
  value and get a broken result.
 
  If you know that the value is always swapped, use bswapxx().
 
 
  Actually the code is right and required for a big endian host :-)
  pcilg/pcistg provide access to the PCI config space which is defined
  as PCI byte order (little endian). Since pci_host_config_read_common 
  does
  already a le to cpu conversion we have to convert back to PCI byte 
  order.
  Doing an unconditional swap would be a bug on a little endian host.
 
  Why would it be a bug? The value you end up writing is contents of a
  register and thus doesn't have endianness. So if QEMU was an LE 
  process,
 
  No, the s390 guest executing pcilg instruction expects to receive 
  config space data
  in PCI byte order.
 
  the value of data would be identical as on a BE QEMU before your swab.
  After the swab, it would be bswap'ed on BE, but not LE. So LE hosts 
  break.
 
 
  Again on BE endian host we do the swap because of 
  pci_host_config_read_common does
  read the value and do a byte swap for that value, but we need PCI byte 
  order not BE here.
 
  On LE host pci_host_config_read_common does not do a byte swap so we do 
  not have to
  convert back to PCI byte order.
 
  We maintain the PCI config space always in LE byte order in memory, 
  that's why there is a bwap in its read function. The return result of 
  the read function however is always the same, regardless of LE or BE 
  host. If I do a read of size 4, I will always get 0x1, not 0x0100 
  returned.
 
  So now you need to convert that 0x1 into a 0x0100 manually here 
  because some architect thought that registers have endianness (which 
  they don't). But you

Re: [Qemu-devel] [PATCH 2/3] s390: implement pci instructions

2014-11-12 Thread Frank Blaschka
On Wed, Nov 12, 2014 at 10:36:03AM +0100, Paolo Bonzini wrote:
 
 
 On 12/11/2014 10:22, Alexander Graf wrote:
  Absolutely lets make an example for qemu running on BE and LE
 
  byte orderconfig space backing   pci_default_read_config   pcilg 
  (with cpu_to_le)
  BE0x78563412 0x123456780x78563412
  LE0x78563412 0x785634120x78563412
 
  No, pci_default_read_config() always returns 0x12345678 because it
  returns a register, not memory.
 
 
  You mean implementation of pci_default_read_config is broken?
  If it should return a register it should not do return le32_to_cpu(val);
  
  It has to, to convert from memory (after memcpy) to an actual register
  value. Look at the value list in Paolo's email - I really have no idea
  how to explain it any better.
 
 pci_default_read_config is reading from a *device* register, and has
 absolutely zero knowledge of the host CPU endianness.
 
 Another way to explain that the result of pci_default_read_config is
 independent of the host endianness, is that the function is basically
 doing this:
 
 switch (len) {
 case 1: return d-config[address];
 case 2: return ldw_le_p(d-config[address)]);
 case 4: return ldl_le_p(d-config[address)]);
 default: abort();
 }
 
 So if you want to make the outcome big endian, you have to swap
 unconditionally.
 
 Paolo

Hi Paolo, Alex,

thx a lot for all the explanation and patience.
I think I have understand your point now. I will change the code to 
unconditional swap. I feel I had a knowledge gap regarding running guest and
host which different byte orders. Hope this gap is filled now ;)

Frank

 




Re: [Qemu-devel] [PATCH 2/3] s390: implement pci instructions

2014-11-11 Thread Frank Blaschka
On Mon, Nov 10, 2014 at 04:56:21PM +0100, Alexander Graf wrote:
 
 
 On 10.11.14 15:20, Frank Blaschka wrote:
  From: Frank Blaschka frank.blasc...@de.ibm.com
  
  This patch implements the s390 pci instructions in qemu. It allows
  to access and drive pci devices attached to the s390 pci bus.
  Because of platform constrains devices using IO BARs are not
  supported. Also a device has to support MSI/MSI-X to run on s390.
  
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
  ---
   target-s390x/Makefile.objs |   2 +-
   target-s390x/kvm.c |  52 
   target-s390x/pci_ic.c  | 753 
  +
   target-s390x/pci_ic.h  | 335 
   4 files changed, 1141 insertions(+), 1 deletion(-)
   create mode 100644 target-s390x/pci_ic.c
   create mode 100644 target-s390x/pci_ic.h
  
  diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
  index 2c57494..cc71400 100644
  --- a/target-s390x/Makefile.objs
  +++ b/target-s390x/Makefile.objs
  @@ -2,4 +2,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-y += gdbstub.o
   obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o
  -obj-$(CONFIG_KVM) += kvm.o
  +obj-$(CONFIG_KVM) += kvm.o pci_ic.o
  diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
  index 5b10a25..d59e740 100644
  --- a/target-s390x/kvm.c
  +++ b/target-s390x/kvm.c
  @@ -40,6 +40,7 @@
   #include exec/gdbstub.h
   #include trace.h
   #include qapi-event.h
  +#include pci_ic.h
   
   /* #define DEBUG_KVM */
   
  @@ -56,6 +57,7 @@
   #define IPA0_B2 0xb200
   #define IPA0_B9 0xb900
   #define IPA0_EB 0xeb00
  +#define IPA0_E3 0xe300
   
   #define PRIV_B2_SCLP_CALL   0x20
   #define PRIV_B2_CSCH0x30
  @@ -76,8 +78,17 @@
   #define PRIV_B2_XSCH0x76
   
   #define PRIV_EB_SQBS0x8a
  +#define PRIV_EB_PCISTB  0xd0
  +#define PRIV_EB_SIC 0xd1
   
   #define PRIV_B9_EQBS0x9c
  +#define PRIV_B9_CLP 0xa0
  +#define PRIV_B9_PCISTG  0xd0
  +#define PRIV_B9_PCILG   0xd2
  +#define PRIV_B9_RPCIT   0xd3
  +
  +#define PRIV_E3_MPCIFC  0xd0
  +#define PRIV_E3_STPCIFC 0xd4
   
   #define DIAG_IPL0x308
   #define DIAG_KVM_HYPERCALL  0x500
  @@ -814,6 +825,18 @@ static int handle_b9(S390CPU *cpu, struct kvm_run 
  *run, uint8_t ipa1)
   int r = 0;
   
   switch (ipa1) {
  +case PRIV_B9_CLP:
  +r = kvm_clp_service_call(cpu, run);
  +break;
  +case PRIV_B9_PCISTG:
  +r = kvm_pcistg_service_call(cpu, run);
  +break;
  +case PRIV_B9_PCILG:
  +r = kvm_pcilg_service_call(cpu, run);
  +break;
  +case PRIV_B9_RPCIT:
  +r = kvm_rpcit_service_call(cpu, run);
  +break;
   case PRIV_B9_EQBS:
   /* just inject exception */
   r = -1;
  @@ -832,6 +855,12 @@ static int handle_eb(S390CPU *cpu, struct kvm_run 
  *run, uint8_t ipa1)
   int r = 0;
   
   switch (ipa1) {
  +case PRIV_EB_PCISTB:
  +r = kvm_pcistb_service_call(cpu, run);
  +break;
  +case PRIV_EB_SIC:
  +r = kvm_sic_service_call(cpu, run);
  +break;
   case PRIV_EB_SQBS:
   /* just inject exception */
   r = -1;
  @@ -845,6 +874,26 @@ static int handle_eb(S390CPU *cpu, struct kvm_run 
  *run, uint8_t ipa1)
   return r;
   }
   
  +static int handle_e3(S390CPU *cpu, struct kvm_run *run, uint8_t ipbl)
  +{
  +int r = 0;
  +
  +switch (ipbl) {
  +case PRIV_E3_MPCIFC:
  +r = kvm_mpcifc_service_call(cpu, run);
  +break;
  +case PRIV_E3_STPCIFC:
  +r = kvm_stpcifc_service_call(cpu, run);
  +break;
  +default:
  +r = -1;
  +DPRINTF(KVM: unhandled PRIV: 0xe3%x\n, ipbl);
  +break;
  +}
  +
  +return r;
  +}
  +
   static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)
   {
   CPUS390XState *env = cpu-env;
  @@ -1041,6 +1090,9 @@ static int handle_instruction(S390CPU *cpu, struct 
  kvm_run *run)
   case IPA0_EB:
   r = handle_eb(cpu, run, ipa1);
   break;
  +case IPA0_E3:
  +r = handle_e3(cpu, run, run-s390_sieic.ipb  0xff);
  +break;
   case IPA0_DIAG:
   r = handle_diag(cpu, run, run-s390_sieic.ipb);
   break;
  diff --git a/target-s390x/pci_ic.c b/target-s390x/pci_ic.c
  new file mode 100644
  index 000..6c05faf
  --- /dev/null
  +++ b/target-s390x/pci_ic.c
  @@ -0,0 +1,753 @@
  +/*
  + * s390 PCI intercepts
  + *
  + * Copyright 2014 IBM Corp.
  + * Author(s): Frank Blaschka frank.blasc...@de.ibm.com

Re: [Qemu-devel] [PATCH 2/3] s390: implement pci instructions

2014-11-11 Thread Frank Blaschka
On Tue, Nov 11, 2014 at 01:16:04PM +0100, Alexander Graf wrote:
 
 
 On 11.11.14 13:10, Frank Blaschka wrote:
  On Mon, Nov 10, 2014 at 04:56:21PM +0100, Alexander Graf wrote:
 
 
  On 10.11.14 15:20, Frank Blaschka wrote:
  From: Frank Blaschka frank.blasc...@de.ibm.com
 
  This patch implements the s390 pci instructions in qemu. It allows
  to access and drive pci devices attached to the s390 pci bus.
  Because of platform constrains devices using IO BARs are not
  supported. Also a device has to support MSI/MSI-X to run on s390.
 
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
  ---
   target-s390x/Makefile.objs |   2 +-
   target-s390x/kvm.c |  52 
   target-s390x/pci_ic.c  | 753 
  +
   target-s390x/pci_ic.h  | 335 
   4 files changed, 1141 insertions(+), 1 deletion(-)
   create mode 100644 target-s390x/pci_ic.c
   create mode 100644 target-s390x/pci_ic.h
 
 
 [...]
 
  +int kvm_pcilg_service_call(S390CPU *cpu, struct kvm_run *run)
  +{
  +CPUS390XState *env = cpu-env;
  +S390PCIBusDevice *pbdev;
  +uint8_t r1 = (run-s390_sieic.ipb  0x00f0)  20;
  +uint8_t r2 = (run-s390_sieic.ipb  0x000f)  16;
  +PciLgStg *rp;
  +uint64_t offset;
  +uint64_t data;
  +uint8_t len;
  +
  +cpu_synchronize_state(CPU(cpu));
  +
  +if (env-psw.mask  PSW_MASK_PSTATE) {
  +program_interrupt(env, PGM_PRIVILEGED, 4);
  +return 0;
  +}
  +
  +if (r2  0x1) {
  +program_interrupt(env, PGM_SPECIFICATION, 4);
  +return 0;
  +}
  +
  +rp = (PciLgStg *)env-regs[r2];
  +offset = env-regs[r2 + 1];
  +
  +pbdev = s390_pci_find_dev_by_fh(rp-fh);
  +if (!pbdev) {
  +DPRINTF(pcilg no pci dev\n);
  +setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
  +return 0;
  +}
  +
  +len = rp-len  0xF;
  +if (rp-pcias  6) {
  +if ((8 - (offset  0x7))  len) {
  +program_interrupt(env, PGM_OPERAND, 4);
  +return 0;
  +}
  +MemoryRegion *mr = pbdev-pdev-io_regions[rp-pcias].memory;
  +io_mem_read(mr, offset, data, len);
  +} else if (rp-pcias == 15) {
  +if ((4 - (offset  0x3))  len) {
  +program_interrupt(env, PGM_OPERAND, 4);
  +return 0;
  +}
  +data =  pci_host_config_read_common(
  +   pbdev-pdev, offset, pci_config_size(pbdev-pdev), 
  len);
  +
  +switch (len) {
  +case 1:
  +break;
  +case 2:
  +data = cpu_to_le16(data);
  +break;
  +case 4:
  +data = cpu_to_le32(data);
  +break;
  +case 8:
  +data = cpu_to_le64(data);
  +break;
 
  Why? Also, this is wrong. cpu_to_le64 convert between host endianness
  and LE. So if you're running this on an LE host, you won't swap the
  value and get a broken result.
 
  If you know that the value is always swapped, use bswapxx().
 
  
  Actually the code is right and required for a big endian host :-)
  pcilg/pcistg provide access to the PCI config space which is defined
  as PCI byte order (little endian). Since pci_host_config_read_common does
  already a le to cpu conversion we have to convert back to PCI byte order.
  Doing an unconditional swap would be a bug on a little endian host.
 
 Why would it be a bug? The value you end up writing is contents of a
 register and thus doesn't have endianness. So if QEMU was an LE process,

No, the s390 guest executing pcilg instruction expects to receive config space 
data
in PCI byte order.

 the value of data would be identical as on a BE QEMU before your swab.
 After the swab, it would be bswap'ed on BE, but not LE. So LE hosts break.


Again on BE endian host we do the swap because of pci_host_config_read_common 
does
read the value and do a byte swap for that value, but we need PCI byte order 
not BE here.

On LE host pci_host_config_read_common does not do a byte swap so we do not 
have to
convert back to PCI byte order.
 
 
 Alex
 




Re: [Qemu-devel] [PATCH 2/3] s390: implement pci instructions

2014-11-11 Thread Frank Blaschka
On Tue, Nov 11, 2014 at 12:17:17PM +, Peter Maydell wrote:
 On 11 November 2014 12:10, Frank Blaschka blasc...@linux.vnet.ibm.com wrote:
  On Mon, Nov 10, 2014 at 04:56:21PM +0100, Alexander Graf wrote:
   +static uint8_t barsize(uint64_t size)
   +{
   +uint64_t mask = 1;
   +int i;
   +
   +if (!size) {
   +return 0;
   +}
   +
   +for (i = 0; i  64; i++) {
   +if (size  mask) {
   +break;
   +}
   +mask = (mask  1);
   +}
   +
   +return i;
   +}
 
  Isn't there an existing helper for this in the PCI layer?
 
 
  Did not find one, this function is used to fill a s390 specific len
  in an instruction intercept (architecture specific encoding of the len).
 
 If you do need to implement this here then you should probably
 be using ctz64(). I think what you have here is equivalent to
 
 return size ? ctz64(size) : 0;
 
 but you should check that.

will do thx!

 
 thanks
 -- PMM
 




Re: [Qemu-devel] [PATCH 2/3] s390: implement pci instructions

2014-11-11 Thread Frank Blaschka
On Tue, Nov 11, 2014 at 01:51:25PM +0100, Alexander Graf wrote:
 
 
 
  Am 11.11.2014 um 13:39 schrieb Frank Blaschka blasc...@linux.vnet.ibm.com:
  
  On Tue, Nov 11, 2014 at 01:16:04PM +0100, Alexander Graf wrote:
  
  
  On 11.11.14 13:10, Frank Blaschka wrote:
  On Mon, Nov 10, 2014 at 04:56:21PM +0100, Alexander Graf wrote:
  
  
  On 10.11.14 15:20, Frank Blaschka wrote:
  From: Frank Blaschka frank.blasc...@de.ibm.com
  
  This patch implements the s390 pci instructions in qemu. It allows
  to access and drive pci devices attached to the s390 pci bus.
  Because of platform constrains devices using IO BARs are not
  supported. Also a device has to support MSI/MSI-X to run on s390.
  
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
  ---
  target-s390x/Makefile.objs |   2 +-
  target-s390x/kvm.c |  52 
  target-s390x/pci_ic.c  | 753 
  +
  target-s390x/pci_ic.h  | 335 
  4 files changed, 1141 insertions(+), 1 deletion(-)
  create mode 100644 target-s390x/pci_ic.c
  create mode 100644 target-s390x/pci_ic.h
  
  
  [...]
  
  +int kvm_pcilg_service_call(S390CPU *cpu, struct kvm_run *run)
  +{
  +CPUS390XState *env = cpu-env;
  +S390PCIBusDevice *pbdev;
  +uint8_t r1 = (run-s390_sieic.ipb  0x00f0)  20;
  +uint8_t r2 = (run-s390_sieic.ipb  0x000f)  16;
  +PciLgStg *rp;
  +uint64_t offset;
  +uint64_t data;
  +uint8_t len;
  +
  +cpu_synchronize_state(CPU(cpu));
  +
  +if (env-psw.mask  PSW_MASK_PSTATE) {
  +program_interrupt(env, PGM_PRIVILEGED, 4);
  +return 0;
  +}
  +
  +if (r2  0x1) {
  +program_interrupt(env, PGM_SPECIFICATION, 4);
  +return 0;
  +}
  +
  +rp = (PciLgStg *)env-regs[r2];
  +offset = env-regs[r2 + 1];
  +
  +pbdev = s390_pci_find_dev_by_fh(rp-fh);
  +if (!pbdev) {
  +DPRINTF(pcilg no pci dev\n);
  +setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
  +return 0;
  +}
  +
  +len = rp-len  0xF;
  +if (rp-pcias  6) {
  +if ((8 - (offset  0x7))  len) {
  +program_interrupt(env, PGM_OPERAND, 4);
  +return 0;
  +}
  +MemoryRegion *mr = pbdev-pdev-io_regions[rp-pcias].memory;
  +io_mem_read(mr, offset, data, len);
  +} else if (rp-pcias == 15) {
  +if ((4 - (offset  0x3))  len) {
  +program_interrupt(env, PGM_OPERAND, 4);
  +return 0;
  +}
  +data =  pci_host_config_read_common(
  +   pbdev-pdev, offset, pci_config_size(pbdev-pdev), 
  len);
  +
  +switch (len) {
  +case 1:
  +break;
  +case 2:
  +data = cpu_to_le16(data);
  +break;
  +case 4:
  +data = cpu_to_le32(data);
  +break;
  +case 8:
  +data = cpu_to_le64(data);
  +break;
  
  Why? Also, this is wrong. cpu_to_le64 convert between host endianness
  and LE. So if you're running this on an LE host, you won't swap the
  value and get a broken result.
  
  If you know that the value is always swapped, use bswapxx().
  
  
  Actually the code is right and required for a big endian host :-)
  pcilg/pcistg provide access to the PCI config space which is defined
  as PCI byte order (little endian). Since pci_host_config_read_common does
  already a le to cpu conversion we have to convert back to PCI byte order.
  Doing an unconditional swap would be a bug on a little endian host.
  
  Why would it be a bug? The value you end up writing is contents of a
  register and thus doesn't have endianness. So if QEMU was an LE process,
  
  No, the s390 guest executing pcilg instruction expects to receive config 
  space data
  in PCI byte order.
  
  the value of data would be identical as on a BE QEMU before your swab.
  After the swab, it would be bswap'ed on BE, but not LE. So LE hosts break.
  
  
  Again on BE endian host we do the swap because of 
  pci_host_config_read_common does
  read the value and do a byte swap for that value, but we need PCI byte 
  order not BE here.
  
  On LE host pci_host_config_read_common does not do a byte swap so we do not 
  have to
  convert back to PCI byte order.
 
 We maintain the PCI config space always in LE byte order in memory, that's 
 why there is a bwap in its read function. The return result of the read 
 function however is always the same, regardless of LE or BE host. If I do a 
 read of size 4, I will always get 0x1, not 0x0100 returned.
 
 So now you need to convert that 0x1 into a 0x0100 manually here because 
 some architect thought that registers have endianness (which they don't). But 
 you need to do it always, even on an LE host, because the pci config space 
 return value is identical on LE and BE.
 
so you tell me pci_host_config_read_common does not end up in 
pci_default_read_config?

uint32_t

[Qemu-devel] [PATCH 3/3] kvm: extend kvm_irqchip_add_msi_route to work on s390

2014-11-10 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

on s390 MSI-X irqs are presented as thin or adapter interrupts
for this we have to reorganize the routing entry to contain
valid information for the adapter interrupt code on s390.
To minimize impact on existing code we introduce an architecture
function to fixup the routing entry.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 include/sysemu/kvm.h |  4 
 kvm-all.c|  7 +++
 target-arm/kvm.c |  6 ++
 target-i386/kvm.c|  6 ++
 target-mips/kvm.c|  6 ++
 target-ppc/kvm.c |  6 ++
 target-s390x/kvm.c   | 26 ++
 7 files changed, 61 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index b0cd657..702dc93 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -148,6 +148,7 @@ extern bool kvm_readonly_mem_allowed;
 
 struct kvm_run;
 struct kvm_lapic_state;
+struct kvm_irq_routing_entry;
 
 typedef struct KVMCapabilityInfo {
 const char *name;
@@ -259,6 +260,9 @@ int kvm_arch_on_sigbus(int code, void *addr);
 
 void kvm_arch_init_irq_routing(KVMState *s);
 
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data);
+
 int kvm_set_irq(KVMState *s, int irq, int level);
 int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
 
diff --git a/kvm-all.c b/kvm-all.c
index 44a5e72..7556d3f 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1206,6 +1206,10 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage 
msg)
 kroute.u.msi.address_lo = (uint32_t)msg.address;
 kroute.u.msi.address_hi = msg.address  32;
 kroute.u.msi.data = le32_to_cpu(msg.data);
+if (kvm_arch_fixup_msi_route(kroute, msg.address, msg.data)) {
+kvm_irqchip_release_virq(s, virq);
+return -EINVAL;
+}
 
 kvm_add_routing_entry(s, kroute);
 kvm_irqchip_commit_routes(s);
@@ -1231,6 +1235,9 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, 
MSIMessage msg)
 kroute.u.msi.address_lo = (uint32_t)msg.address;
 kroute.u.msi.address_hi = msg.address  32;
 kroute.u.msi.data = le32_to_cpu(msg.data);
+if (kvm_arch_fixup_msi_route(kroute, msg.address, msg.data)) {
+return -EINVAL;
+}
 
 return kvm_update_routing_entry(s, kroute);
 }
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 319784d..3285f81 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -441,3 +441,9 @@ int kvm_arch_irqchip_create(KVMState *s)
 
 return 0;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index ccf36e8..7bc818c 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -2707,3 +2707,9 @@ int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id)
 return kvm_deassign_irq_internal(s, dev_id, KVM_DEV_IRQ_GUEST_MSIX |
 KVM_DEV_IRQ_HOST_MSIX);
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 97fd51a..c7eb1dc 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -688,3 +688,9 @@ int kvm_arch_get_registers(CPUState *cs)
 
 return ret;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 6843fa0..04c83cd 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -2388,3 +2388,9 @@ out_close:
 error_out:
 return;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+return 0;
+}
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index d59e740..a08641b 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -41,6 +41,7 @@
 #include trace.h
 #include qapi-event.h
 #include pci_ic.h
+#include hw/s390x/s390-pci-bus.h
 
 /* #define DEBUG_KVM */
 
@@ -1414,3 +1415,28 @@ int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t 
cpu_state)
 
 return ret;
 }
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+  uint64_t address, uint32_t data)
+{
+S390PCIBusDevice *pbdev;
+uint32_t fid = data  ZPCI_MSI_VEC_BITS;
+uint32_t vec = data  ZPCI_MSI_VEC_MASK;
+
+pbdev = s390_pci_find_dev_by_fid(fid);
+if (!pbdev) {
+DPRINTF(add_msi_route no dev\n);
+return -ENODEV;
+}
+
+pbdev-routes.adapter.ind_offset = vec;
+
+route-type = KVM_IRQ_ROUTING_S390_ADAPTER;
+route-flags = 0;
+route-u.adapter.summary_addr = pbdev-routes.adapter.summary_addr;
+route-u.adapter.ind_addr = pbdev-routes.adapter.ind_addr;
+route-u.adapter.summary_offset = pbdev

[Qemu-devel] [PATCH 0/3] add PCI support for the s390 platform

2014-11-10 Thread Frank Blaschka
This set of patches implemets PCI support for the s390 platform.
Now it is possible to run virtio-net-pci and potentially all
virtual pci devices conforming to s390 platform constrains.

Please review and consider for integration into 2.3

Thanks,

Frank Blaschka (3):
  s390: Add PCI bus support
  s390: implement pci instructions
  kvm: extend kvm_irqchip_add_msi_route to work on s390

 default-configs/s390x-softmmu.mak |   1 +
 hw/s390x/Makefile.objs|   1 +
 hw/s390x/css.c|   5 +
 hw/s390x/css.h|   1 +
 hw/s390x/s390-pci-bus.c   | 485 
 hw/s390x/s390-pci-bus.h   | 254 +
 hw/s390x/s390-virtio-ccw.c|   3 +
 hw/s390x/sclp.c   |  10 +-
 include/hw/s390x/sclp.h   |   8 +
 include/sysemu/kvm.h  |   4 +
 kvm-all.c |   7 +
 target-arm/kvm.c  |   6 +
 target-i386/kvm.c |   6 +
 target-mips/kvm.c |   6 +
 target-ppc/kvm.c  |   6 +
 target-s390x/Makefile.objs|   2 +-
 target-s390x/ioinst.c |  52 +++
 target-s390x/ioinst.h |   1 +
 target-s390x/kvm.c|  78 
 target-s390x/pci_ic.c | 753 ++
 target-s390x/pci_ic.h | 335 +
 21 files changed, 2022 insertions(+), 2 deletions(-)
 create mode 100644 hw/s390x/s390-pci-bus.c
 create mode 100644 hw/s390x/s390-pci-bus.h
 create mode 100644 target-s390x/pci_ic.c
 create mode 100644 target-s390x/pci_ic.h

-- 
1.8.5.5




[Qemu-devel] [PATCH 1/3] s390: Add PCI bus support

2014-11-10 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements a pci bus for s390x together with infrastructure
to generate and handle hotplug events, to configure/unconfigure via
sclp instruction, to do iommu translations and provide s390 support for
MSI/MSI-X notification processing.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 default-configs/s390x-softmmu.mak |   1 +
 hw/s390x/Makefile.objs|   1 +
 hw/s390x/css.c|   5 +
 hw/s390x/css.h|   1 +
 hw/s390x/s390-pci-bus.c   | 485 ++
 hw/s390x/s390-pci-bus.h   | 254 
 hw/s390x/s390-virtio-ccw.c|   3 +
 hw/s390x/sclp.c   |  10 +-
 include/hw/s390x/sclp.h   |   8 +
 target-s390x/ioinst.c |  52 
 target-s390x/ioinst.h |   1 +
 11 files changed, 820 insertions(+), 1 deletion(-)
 create mode 100644 hw/s390x/s390-pci-bus.c
 create mode 100644 hw/s390x/s390-pci-bus.h

diff --git a/default-configs/s390x-softmmu.mak 
b/default-configs/s390x-softmmu.mak
index 126d88d..6ee2ff8 100644
--- a/default-configs/s390x-softmmu.mak
+++ b/default-configs/s390x-softmmu.mak
@@ -1,3 +1,4 @@
+include pci.mak
 CONFIG_VIRTIO=y
 CONFIG_SCLPCONSOLE=y
 CONFIG_S390_FLIC=y
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 1ba6c3a..428d957 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -8,3 +8,4 @@ obj-y += ipl.o
 obj-y += css.o
 obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
+obj-y += s390-pci-bus.o
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index b67c039..7553085 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1299,6 +1299,11 @@ void css_generate_chp_crws(uint8_t cssid, uint8_t chpid)
 /* TODO */
 }
 
+void css_generate_css_crws(uint8_t cssid)
+{
+css_queue_crw(CRW_RSC_CSS, 0, 0, 0);
+}
+
 int css_enable_mcsse(void)
 {
 trace_css_enable_facility(mcsse);
diff --git a/hw/s390x/css.h b/hw/s390x/css.h
index 33104ac..7e53148 100644
--- a/hw/s390x/css.h
+++ b/hw/s390x/css.h
@@ -101,6 +101,7 @@ void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, 
uint16_t rsid);
 void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
int hotplugged, int add);
 void css_generate_chp_crws(uint8_t cssid, uint8_t chpid);
+void css_generate_css_crws(uint8_t cssid);
 void css_adapter_interrupt(uint8_t isc);
 
 #define CSS_IO_ADAPTER_VIRTIO 1
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
new file mode 100644
index 000..f2fa6ba
--- /dev/null
+++ b/hw/s390x/s390-pci-bus.c
@@ -0,0 +1,485 @@
+/*
+ * s390 PCI BUS
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include hw/pci/pci.h
+#include hw/pci/pci_bus.h
+#include hw/s390x/css.h
+#include hw/s390x/sclp.h
+#include hw/pci/msi.h
+#include qemu/error-report.h
+#include s390-pci-bus.h
+
+/* #define DEBUG_S390PCI_BUS */
+#ifdef DEBUG_S390PCI_BUS
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, S390pci-bus:  fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+static const unsigned long be_to_le = BITS_PER_LONG - 1;
+static QTAILQ_HEAD(, SeiContainer) pending_sei =
+QTAILQ_HEAD_INITIALIZER(pending_sei);
+static QTAILQ_HEAD(, S390PCIBusDevice) device_list =
+QTAILQ_HEAD_INITIALIZER(device_list);
+
+int chsc_sei_nt2_get_event(void *res)
+{
+ChscSeiNt2Res *nt2_res = (ChscSeiNt2Res *)res;
+PciCcdfAvail *accdf;
+PciCcdfErr *eccdf;
+int rc = 1;
+SeiContainer *sei_cont;
+
+sei_cont = QTAILQ_FIRST(pending_sei);
+if (sei_cont) {
+QTAILQ_REMOVE(pending_sei, sei_cont, link);
+nt2_res-nt = 2;
+nt2_res-cc = sei_cont-cc;
+switch (sei_cont-cc) {
+case 1: /* error event */
+eccdf = (PciCcdfErr *)nt2_res-ccdf;
+eccdf-fid = cpu_to_be32(sei_cont-fid);
+eccdf-fh = cpu_to_be32(sei_cont-fh);
+break;
+case 2: /* availability event */
+accdf = (PciCcdfAvail *)nt2_res-ccdf;
+accdf-fid = cpu_to_be32(sei_cont-fid);
+accdf-fh = cpu_to_be32(sei_cont-fh);
+accdf-pec = cpu_to_be16(sei_cont-pec);
+break;
+default:
+abort();
+}
+g_free(sei_cont);
+rc = 0;
+}
+
+return rc;
+}
+
+int chsc_sei_nt2_have_event(void)
+{
+return !QTAILQ_EMPTY(pending_sei);
+}
+
+S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid)
+{
+S390PCIBusDevice *pbdev;
+
+QTAILQ_FOREACH(pbdev, device_list, next) {
+if (pbdev-fid == fid) {
+return pbdev

Re: [Qemu-devel] [PATCH] vfio: check if host device supports INTx

2014-10-24 Thread Frank Blaschka
On Thu, Oct 23, 2014 at 08:26:51AM -0600, Alex Williamson wrote:
 On Thu, 2014-10-23 at 10:21 +0200, Frank Blaschka wrote:
  On Wed, Oct 22, 2014 at 11:17:11AM -0600, Alex Williamson wrote:
   On Wed, 2014-10-22 at 17:13 +0200, Frank Blaschka wrote:
From: Frank Blaschka frank.blasc...@de.ibm.com

Let the kernel announce if INTx is available. Yes, there are platforms
(e.g. s390) which do not support INTx.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 hw/misc/vfio.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index d66f3d2..3e9600b 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -109,6 +109,7 @@ typedef struct VFIOVGA {
 } VFIOVGA;
 
 typedef struct VFIOINTx {
+bool available; /* intx available */
 bool pending; /* interrupt pending */
 bool kvm_accel; /* set when QEMU bypass through KVM enabled */
 uint8_t pin; /* which pin to pull for qemu_set_irq */
@@ -554,7 +555,7 @@ static int vfio_enable_intx(VFIODevice *vdev)
 struct vfio_irq_set *irq_set;
 int32_t *pfd;
 
-if (!pin) {
+if (!pin || !vdev-intx.available) {
 return 0;
 }
 
@@ -4032,6 +4033,21 @@ static int vfio_get_device(VFIOGroup *group, 
const char *name, VFIODevice *vdev)
  vdev-host.function);
 }
 
+irq_info.index = VFIO_PCI_INTX_IRQ_INDEX;
+ret = ioctl(vdev-fd, VFIO_DEVICE_GET_IRQ_INFO, irq_info);
+if (ret) {
+/*
+ * This can fail for an old kernel or legacy PCI dev
+ * we assume intx is available
+ */
   
   Is this true?  It's unfortunately from an ABI stability standpoint that
   we weren't calling this, but the ioctl should have always been there and
   worked.  I'd rather error out here than add a fallback if this is just
  
  ok
  
   paranoia.  Note that SR-IOV VFs will also report count=0 but their IRQ
   pin register will read 0.  We do also have the option to virtualize the
   IRQ pin register for s390 devices which would make them look the same as
  
  sounds interesting, can you elaborate a little bit more on this?
  At what point can we hook in and modify the pci device config space?
 
 Untested, but I think it would be something like this:


This is great, works perfect and there is no need to do any qemu vfio changes
anymore. You can forget about this patch.

Thx,
Frank
 
 --- a/drivers/vfio/pci/vfio_pci_config.c
 +++ b/drivers/vfio/pci/vfio_pci_config.c
 @@ -609,6 +609,10 @@ static int __init init_pci_cap_basic_perm(struct 
 perm_bits 
 
 /* Sometimes used by sw, just virtualize */
 p_setb(perm, PCI_INTERRUPT_LINE, (u8)ALL_VIRT, (u8)ALL_WRITE);
 +
 +   /* Virtualize interrupt pin to allow hiding INTx */
 +   p_setb(perm, PCI_INTERRUPT_PIN, (u8)ALL_VIRT, (u8)NO_WRITE);
 +
 return 0;
  }
 
 @@ -1445,6 +1449,9 @@ int vfio_config_init(struct vfio_pci_device *vdev)
 *(__le16 *)vconfig[PCI_DEVICE_ID] = 
 cpu_to_le16(pdev-device);
 }
 
 +   if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX))
 +   vconfig[PCI_INTERRUPT_PIN] = 0;
 +
 ret = vfio_cap_init(vdev);
 if (ret)
 goto out;
 
 




[Qemu-devel] [PATCH 3/3 RPC] kvm: extend kvm_irqchip_add_msi_route to work on s390

2014-10-22 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

on s390 MSI-X irqs are presented as thin or adapter interrupts
for this we have to reorganize the routing entry to contain
valid information for the adapter interrupt code on s390.
To minimize impact on existing code we introduce an architecture
function to fixup the routing entry.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 include/sysemu/kvm.h |  4 
 kvm-all.c|  2 ++
 target-arm/kvm.c |  5 +
 target-i386/kvm.c|  5 +
 target-mips/kvm.c|  5 +
 target-ppc/kvm.c |  5 +
 target-s390x/kvm.c   | 25 +
 7 files changed, 51 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 77ee240..d4c89c3 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -148,6 +148,7 @@ extern bool kvm_readonly_mem_allowed;
 
 struct kvm_run;
 struct kvm_lapic_state;
+struct kvm_irq_routing_entry;
 
 typedef struct KVMCapabilityInfo {
 const char *name;
@@ -261,6 +262,9 @@ int kvm_arch_on_sigbus(int code, void *addr);
 
 void kvm_arch_init_irq_routing(KVMState *s);
 
+void kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+  uint64_t address, uint32_t data);
+
 int kvm_set_irq(KVMState *s, int irq, int level);
 int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
 
diff --git a/kvm-all.c b/kvm-all.c
index 682420b..965c888 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1198,6 +1198,7 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
 kroute.u.msi.address_lo = (uint32_t)msg.address;
 kroute.u.msi.address_hi = msg.address  32;
 kroute.u.msi.data = le32_to_cpu(msg.data);
+kvm_arch_fixup_msi_route(kroute, msg.address, msg.data);
 
 kvm_add_routing_entry(s, kroute);
 kvm_irqchip_commit_routes(s);
@@ -1223,6 +1224,7 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, 
MSIMessage msg)
 kroute.u.msi.address_lo = (uint32_t)msg.address;
 kroute.u.msi.address_hi = msg.address  32;
 kroute.u.msi.data = le32_to_cpu(msg.data);
+kvm_arch_fixup_msi_route(kroute, msg.address, msg.data);
 
 return kvm_update_routing_entry(s, kroute);
 }
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 319784d..5204c48 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -441,3 +441,8 @@ int kvm_arch_irqchip_create(KVMState *s)
 
 return 0;
 }
+
+void kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+  uint64_t address, uint32_t data)
+{
+}
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index ddedc73..5e80ecd 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -2688,3 +2688,8 @@ int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id)
 return kvm_deassign_irq_internal(s, dev_id, KVM_DEV_IRQ_GUEST_MSIX |
 KVM_DEV_IRQ_HOST_MSIX);
 }
+
+void kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+  uint64_t address, uint32_t data)
+{
+}
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 97fd51a..fe34eb2 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -688,3 +688,8 @@ int kvm_arch_get_registers(CPUState *cs)
 
 return ret;
 }
+
+void kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+  uint64_t address, uint32_t data)
+{
+}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 9c23c6b..55627b9 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -2388,3 +2388,8 @@ out_close:
 error_out:
 return;
 }
+
+void kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+  uint64_t address, uint32_t data)
+{
+}
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 9280132..c3b3b0f 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -43,6 +43,7 @@
 #include trace.h
 #include qapi-event.h
 #include pci_ic.h
+#include hw/s390x/s390-pci-bus.h
 
 /* #define DEBUG_KVM */
 
@@ -1639,3 +1640,27 @@ int kvm_s390_get_machine_props(S390MachineProps *prop)
 {
 return cpu_model_get(KVM_S390_VM_CPU_MACHINE, (uint64_t) prop);
 }
+
+void kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+  uint64_t address, uint32_t data)
+{
+S390PCIBusDevice *pbdev;
+uint32_t fid = data  ZPCI_MSI_VEC_BITS;
+uint32_t vec = data  ZPCI_MSI_VEC_MASK;
+
+pbdev = s390_pci_find_dev_by_fid(fid);
+if (!pbdev) {
+DPRINTF(add_msi_route no dev\n);
+return;
+}
+
+pbdev-routes.adapter.ind_offset = vec;
+
+route-type = KVM_IRQ_ROUTING_S390_ADAPTER;
+route-flags = 0;
+route-u.adapter.summary_addr = pbdev-routes.adapter.summary_addr;
+route-u.adapter.ind_addr = pbdev-routes.adapter.ind_addr;
+route-u.adapter.summary_offset = pbdev-routes.adapter.summary_offset;
+route-u.adapter.ind_offset = pbdev-routes.adapter.ind_offset;
+route-u.adapter.adapter_id = pbdev-routes.adapter.adapter_id

[Qemu-devel] [PATCH 1/3 RFC] s390: Add PCI bus support

2014-10-22 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements a pci bus for s390x together with infrastructure
to generate and handle hotplug events, to configure/unconfigure via
sclp instruction, to do iommu translations and provide s390 support for
MSI/MSI-X notification processing.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 default-configs/s390x-softmmu.mak |   1 +
 hw/s390x/Makefile.objs|   1 +
 hw/s390x/css.c|   5 +
 hw/s390x/css.h|   1 +
 hw/s390x/s390-pci-bus.c   | 447 ++
 hw/s390x/s390-pci-bus.h   | 252 +
 hw/s390x/s390-virtio-ccw.c|   3 +
 hw/s390x/sclp.c   |  10 +-
 include/hw/s390x/sclp.h   |   8 +
 target-s390x/cpu-models.h |   8 +-
 target-s390x/ioinst.c |  52 +
 target-s390x/ioinst.h |   1 +
 12 files changed, 787 insertions(+), 2 deletions(-)
 create mode 100644 hw/s390x/s390-pci-bus.c
 create mode 100644 hw/s390x/s390-pci-bus.h

diff --git a/default-configs/s390x-softmmu.mak 
b/default-configs/s390x-softmmu.mak
index a683760..db9284f 100644
--- a/default-configs/s390x-softmmu.mak
+++ b/default-configs/s390x-softmmu.mak
@@ -1,3 +1,4 @@
+include pci.mak
 CONFIG_VIRTIO=y
 CONFIG_SCLPCONSOLE=y
 CONFIG_S390_FLIC=y
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index dc03e1d..921e255 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -8,4 +8,5 @@ obj-y += ipl.o
 obj-y += css.o
 obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
+obj-y += s390-pci-bus.o
 obj-$(CONFIG_S390_CONFIG) += config.o
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index b67c039..7553085 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1299,6 +1299,11 @@ void css_generate_chp_crws(uint8_t cssid, uint8_t chpid)
 /* TODO */
 }
 
+void css_generate_css_crws(uint8_t cssid)
+{
+css_queue_crw(CRW_RSC_CSS, 0, 0, 0);
+}
+
 int css_enable_mcsse(void)
 {
 trace_css_enable_facility(mcsse);
diff --git a/hw/s390x/css.h b/hw/s390x/css.h
index 33104ac..7e53148 100644
--- a/hw/s390x/css.h
+++ b/hw/s390x/css.h
@@ -101,6 +101,7 @@ void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, 
uint16_t rsid);
 void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
int hotplugged, int add);
 void css_generate_chp_crws(uint8_t cssid, uint8_t chpid);
+void css_generate_css_crws(uint8_t cssid);
 void css_adapter_interrupt(uint8_t isc);
 
 #define CSS_IO_ADAPTER_VIRTIO 1
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
new file mode 100644
index 000..f612108
--- /dev/null
+++ b/hw/s390x/s390-pci-bus.c
@@ -0,0 +1,447 @@
+/*
+ * s390 PCI BUS
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include hw/pci/pci.h
+#include hw/pci/pci_bus.h
+#include hw/s390x/css.h
+#include hw/s390x/sclp.h
+#include hw/pci/msi.h
+#include qemu/error-report.h
+#include s390-pci-bus.h
+
+/* #define DEBUG_S390PCI_BUS */
+#ifdef DEBUG_S390PCI_BUS
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, S390pci-bus:  fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+static const unsigned long be_to_le = BITS_PER_LONG - 1;
+static QTAILQ_HEAD(, SeiContainer) pending_sei =
+QTAILQ_HEAD_INITIALIZER(pending_sei);
+static QTAILQ_HEAD(, S390PCIBusDevice) device_list =
+QTAILQ_HEAD_INITIALIZER(device_list);
+
+int chsc_sei_nt2_get_event(void *res)
+{
+ChscSeiNt2Res *nt2_res = (ChscSeiNt2Res *)res;
+PciCcdfAvail *accdf;
+PciCcdfErr *eccdf;
+int rc = 1;
+SeiContainer *sei_cont;
+
+sei_cont = QTAILQ_FIRST(pending_sei);
+if (sei_cont) {
+QTAILQ_REMOVE(pending_sei, sei_cont, link);
+nt2_res-nt = 2;
+nt2_res-cc = sei_cont-cc;
+switch (sei_cont-cc) {
+case 1: /* error event */
+eccdf = (PciCcdfErr *)nt2_res-ccdf;
+eccdf-fid = cpu_to_be32(sei_cont-fid);
+eccdf-fh = cpu_to_be32(sei_cont-fh);
+break;
+case 2: /* availability event */
+accdf = (PciCcdfAvail *)nt2_res-ccdf;
+accdf-fid = cpu_to_be32(sei_cont-fid);
+accdf-fh = cpu_to_be32(sei_cont-fh);
+accdf-pec = cpu_to_be16(sei_cont-pec);
+break;
+default:
+abort();
+}
+g_free(sei_cont);
+rc = 0;
+}
+
+return rc;
+}
+
+int chsc_sei_nt2_have_event(void)
+{
+return !QTAILQ_EMPTY(pending_sei);
+}
+
+S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid)
+{
+S390PCIBusDevice *pbdev;
+
+QTAILQ_FOREACH(pbdev, device_list, next

[Qemu-devel] [PATCH 0/3 RFC] add PCI support for the s390 platform

2014-10-22 Thread Frank Blaschka
This set of patches implemets PCI support for the s390 platform.
Now it is possible to run virtio-net-pci and potentially all
virtual pci devices conforming to s390 platform constrains.
(In parallel I also post some changes to make vfio run on s390)

I hope to get feedback and guidance especially for

kvm: extend kvm_irqchip_add_msi_route to work on s390

which adds the s390 interpretation of MSI-X to the common kvm
add_msi_route functionality.

Thx for any help,

Frank


Frank Blaschka (3):
  s390: Add PCI bus support
  s390: implement pci instructions
  kvm: extend kvm_irqchip_add_msi_route to work on s390

 default-configs/s390x-softmmu.mak |   1 +
 hw/s390x/Makefile.objs|   1 +
 hw/s390x/css.c|   5 +
 hw/s390x/css.h|   1 +
 hw/s390x/s390-pci-bus.c   | 447 +++
 hw/s390x/s390-pci-bus.h   | 252 +
 hw/s390x/s390-virtio-ccw.c|   3 +
 hw/s390x/sclp.c   |  10 +-
 include/hw/s390x/sclp.h   |   8 +
 include/sysemu/kvm.h  |   4 +
 kvm-all.c |   2 +
 target-arm/kvm.c  |   5 +
 target-i386/kvm.c |   5 +
 target-mips/kvm.c |   5 +
 target-ppc/kvm.c  |   5 +
 target-s390x/Makefile.objs|   2 +-
 target-s390x/cpu-models.h |   8 +-
 target-s390x/ioinst.c |  52 +++
 target-s390x/ioinst.h |   1 +
 target-s390x/kvm.c|  77 
 target-s390x/pci_ic.c | 735 ++
 target-s390x/pci_ic.h | 316 
 22 files changed, 1942 insertions(+), 3 deletions(-)
 create mode 100644 hw/s390x/s390-pci-bus.c
 create mode 100644 hw/s390x/s390-pci-bus.h
 create mode 100644 target-s390x/pci_ic.c
 create mode 100644 target-s390x/pci_ic.h

-- 
1.8.5.5




[Qemu-devel] [PATCH 2/3 RFC] s390: implement pci instructions

2014-10-22 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements the s390 pci instructions in qemu. It allows
to access and drive pci devices attached to the s390 pci bus.
Because of platform constrains devices using IO BARs are not
supported. Also a device has to support MSI/MSI-X to run on s390.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 target-s390x/Makefile.objs |   2 +-
 target-s390x/kvm.c |  52 
 target-s390x/pci_ic.c  | 735 +
 target-s390x/pci_ic.h  | 316 +++
 4 files changed, 1104 insertions(+), 1 deletion(-)
 create mode 100644 target-s390x/pci_ic.c
 create mode 100644 target-s390x/pci_ic.h

diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index 9f55140..b99849e 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -3,4 +3,4 @@ obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o 
misc_helper.o
 obj-y += gdbstub.o
 obj-y += cpu-models.o
 obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o
-obj-$(CONFIG_KVM) += kvm.o
+obj-$(CONFIG_KVM) += kvm.o pci_ic.o
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 467f452..9280132 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -42,6 +42,7 @@
 #include exec/gdbstub.h
 #include trace.h
 #include qapi-event.h
+#include pci_ic.h
 
 /* #define DEBUG_KVM */
 
@@ -58,6 +59,7 @@
 #define IPA0_B2 0xb200
 #define IPA0_B9 0xb900
 #define IPA0_EB 0xeb00
+#define IPA0_E3 0xe300
 
 #define PRIV_B2_SCLP_CALL   0x20
 #define PRIV_B2_CSCH0x30
@@ -78,8 +80,17 @@
 #define PRIV_B2_XSCH0x76
 
 #define PRIV_EB_SQBS0x8a
+#define PRIV_EB_PCISTB  0xd0
+#define PRIV_EB_SIC 0xd1
 
 #define PRIV_B9_EQBS0x9c
+#define PRIV_B9_CLP 0xa0
+#define PRIV_B9_PCISTG  0xd0
+#define PRIV_B9_PCILG   0xd2
+#define PRIV_B9_RPCIT   0xd3
+
+#define PRIV_E3_MPCIFC  0xd0
+#define PRIV_E3_STPCIFC 0xd4
 
 #define DIAG_IPL0x308
 #define DIAG_KVM_HYPERCALL  0x500
@@ -923,6 +934,18 @@ static int handle_b9(S390CPU *cpu, struct kvm_run *run, 
uint8_t ipa1)
 int r = 0;
 
 switch (ipa1) {
+case PRIV_B9_CLP:
+r = kvm_clp_service_call(cpu, run);
+break;
+case PRIV_B9_PCISTG:
+r = kvm_pcistg_service_call(cpu, run);
+break;
+case PRIV_B9_PCILG:
+r = kvm_pcilg_service_call(cpu, run);
+break;
+case PRIV_B9_RPCIT:
+r = kvm_rpcit_service_call(cpu, run);
+break;
 case PRIV_B9_EQBS:
 /* just inject exception */
 r = -1;
@@ -941,6 +964,12 @@ static int handle_eb(S390CPU *cpu, struct kvm_run *run, 
uint8_t ipbl)
 int r = 0;
 
 switch (ipbl) {
+case PRIV_EB_PCISTB:
+r = kvm_pcistb_service_call(cpu, run);
+break;
+case PRIV_EB_SIC:
+r = kvm_sic_service_call(cpu, run);
+break;
 case PRIV_EB_SQBS:
 /* just inject exception */
 r = -1;
@@ -954,6 +983,26 @@ static int handle_eb(S390CPU *cpu, struct kvm_run *run, 
uint8_t ipbl)
 return r;
 }
 
+static int handle_e3(S390CPU *cpu, struct kvm_run *run, uint8_t ipbl)
+{
+int r = 0;
+
+switch (ipbl) {
+case PRIV_E3_MPCIFC:
+r = kvm_mpcifc_service_call(cpu, run);
+break;
+case PRIV_E3_STPCIFC:
+r = kvm_stpcifc_service_call(cpu, run);
+break;
+default:
+r = -1;
+DPRINTF(KVM: unhandled PRIV: 0xe3%x\n, ipbl);
+break;
+}
+
+return r;
+}
+
 static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)
 {
 CPUS390XState *env = cpu-env;
@@ -1150,6 +1199,9 @@ static int handle_instruction(S390CPU *cpu, struct 
kvm_run *run)
 case IPA0_EB:
 r = handle_eb(cpu, run, run-s390_sieic.ipb  0xff);
 break;
+case IPA0_E3:
+r = handle_e3(cpu, run, run-s390_sieic.ipb  0xff);
+break;
 case IPA0_DIAG:
 r = handle_diag(cpu, run, run-s390_sieic.ipb);
 break;
diff --git a/target-s390x/pci_ic.c b/target-s390x/pci_ic.c
new file mode 100644
index 000..a496e6b
--- /dev/null
+++ b/target-s390x/pci_ic.c
@@ -0,0 +1,735 @@
+/*
+ * s390 PCI intercepts
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include sys/types.h
+#include sys/ioctl.h
+#include sys/mman.h
+
+#include linux/kvm.h
+#include asm/ptrace.h
+#include hw/pci/pci.h
+#include hw/pci/pci_host.h
+#include

[Qemu-devel] [PATCH] vfio: check if host device supports INTx

2014-10-22 Thread Frank Blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

Let the kernel announce if INTx is available. Yes, there are platforms
(e.g. s390) which do not support INTx.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 hw/misc/vfio.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index d66f3d2..3e9600b 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -109,6 +109,7 @@ typedef struct VFIOVGA {
 } VFIOVGA;
 
 typedef struct VFIOINTx {
+bool available; /* intx available */
 bool pending; /* interrupt pending */
 bool kvm_accel; /* set when QEMU bypass through KVM enabled */
 uint8_t pin; /* which pin to pull for qemu_set_irq */
@@ -554,7 +555,7 @@ static int vfio_enable_intx(VFIODevice *vdev)
 struct vfio_irq_set *irq_set;
 int32_t *pfd;
 
-if (!pin) {
+if (!pin || !vdev-intx.available) {
 return 0;
 }
 
@@ -4032,6 +4033,21 @@ static int vfio_get_device(VFIOGroup *group, const char 
*name, VFIODevice *vdev)
  vdev-host.function);
 }
 
+irq_info.index = VFIO_PCI_INTX_IRQ_INDEX;
+ret = ioctl(vdev-fd, VFIO_DEVICE_GET_IRQ_INFO, irq_info);
+if (ret) {
+/*
+ * This can fail for an old kernel or legacy PCI dev
+ * we assume intx is available
+ */
+vdev-intx.available = true;
+ret = 0;
+} else if (irq_info.count == 0) {
+vdev-intx.available = false;
+} else {
+vdev-intx.available = true;
+}
+
 error:
 if (ret) {
 QLIST_REMOVE(vdev, next);
-- 
1.8.5.5




[Qemu-devel] [PATCH] vfio: fix adding memory listener to the right address space

2014-10-17 Thread Frank Blaschka
Depending on the device, container-space-as contains the valid AddressSpace.
Using address_space_memory breaks devices sitting behind an iommu (and using
a separate address space).

Signed-off-by: Frank Blaschka blasc...@linux.vnet.ibm.com
---
 hw/misc/vfio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index d66f3d2..fcc1958 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -3703,7 +3703,7 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as)
 container-iommu_data.release = vfio_listener_release;
 
 memory_listener_register(container-iommu_data.type1.listener,
- address_space_memory);
+ container-space-as);
 
 if (container-iommu_data.type1.error) {
 ret = container-iommu_data.type1.error;
-- 
1.8.5.5




Re: [Qemu-devel] [RFC patch 0/6] vfio based pci pass-through for qemu/KVM on s390

2014-10-02 Thread Frank Blaschka
On Wed, Oct 01, 2014 at 11:26:51AM -0600, Alex Williamson wrote:
 On Wed, 2014-10-01 at 11:11 +0200, Frank Blaschka wrote:
  On Fri, Sep 26, 2014 at 01:59:40PM -0600, Alex Williamson wrote:
   On Fri, 2014-09-26 at 08:45 +0200, Frank Blaschka wrote:
On Wed, Sep 24, 2014 at 10:05:57AM -0600, Alex Williamson wrote:
 On Wed, 2014-09-24 at 10:47 +0200, Frank Blaschka wrote:
  On Mon, Sep 22, 2014 at 02:47:31PM -0600, Alex Williamson wrote:
   On Fri, 2014-09-19 at 13:54 +0200, frank.blasc...@de.ibm.com 
   wrote:
This set of patches implements a vfio based solution for pci
pass-through on the s390 platform. The kernel stuff is pretty
much straight forward, but qemu needs more work.

Most interesting patch is:
  vfio: make vfio run on s390 platform

I hope Alex  Alex can give me some guidance how to do the 
changes
in an appropriate way. After creating a separate iommmu address 
space
for each attached PCI device I can successfully run the vfio 
type1
iommu. So If we could extend type1 not registering all guest 
memory
(see patch) I think we do not need a special vfio iommu for s390
for the moment.

The patches implement the base pass-through support. s390 
specific
virtualization functions are currently not included. This would
be a second step after the base support is done.

kernel patches apply to linux-kvm-next

KVM: s390: Enable PCI instructions
iommu: add iommu for s390 platform
vfio: make vfio build on s390

qemu patches apply to qemu-master

s390: Add PCI bus support
s390: implement pci instruction
vfio: make vfio run on s390 platform

Thx for feedback and review comments
   
   Sending patches as attachments makes it difficult to comment 
   inline.
  
  Sorry, don't understand this. I sent every patch as separate email 
  so
  you can comment directly on the patch. What do you prefer?
 
 The patches in each email are showing up as attachments in my mail
 client.  Is it just me?
 
   2/6
- careful of the namespace as you're changing functions from 
   static and
   exporting them
- doesn't seem like functions need to be exported, just 
   non-static to
   call from s390-iommu.c
   
  Ok, will change this.
  
   6/6
- We shouldn't need to globally disable mmap, each VFIO region 
   reports
   whether it supports mmap and vfio-pci on s390 should indicate 
   mmap is
   not supported on the platform.
  Yes, this is even better to let the kernel announce a BAR can not be
  mmap'ed. Checking the kernel code I realized the BARs are valid for
  mmap'ing but the s390 platform does simply not allow this. So I 
  feal we
  have to introduce a platform switch in kernel. How about this ...
  
  --- a/drivers/vfio/pci/vfio_pci.c
  +++ b/drivers/vfio/pci/vfio_pci.c
  @@ -377,9 +377,11 @@ static long vfio_pci_ioctl(void *device_
  
  info.flags = VFIO_REGION_INFO_FLAG_READ |
   VFIO_REGION_INFO_FLAG_WRITE;
  +#ifndef CONFIG_S390
  if (pci_resource_flags(pdev, info.index) 
  IORESOURCE_MEM  info.size = 
  PAGE_SIZE)
  info.flags |= 
  VFIO_REGION_INFO_FLAG_MMAP;
  +#endif
  break;
  case VFIO_PCI_ROM_REGION_INDEX:
  {
 
 Maybe pull it out into a function.  Also, is there some capability or
 feature we can test rather than just the architecture?  I'd prefer it 
 to
 be excluded because of a platform feature that prevents it rather than
 the overall architecture itself.


Ok, understand this. There is no capability of feature so I will go with
the function.
 
- INTx should be done the same way, the interrupt index for INTx 
   should
   report 0 count.  The current code likely doesn't handle this, but 
   it
   should be easy to fix.
  The current code is fine. Problem is the card reports an interrupt 
  index
  (PCI_INTERRUPT_PIN) but again the platform does not support INTx at 
  all.
  So we need a platform switch as well. 
 
 Yep, let's try to do something consistent with the MMAP testing.


Do you mean let the kernel announce this also?
   
   Yes, the kernel reports a count of 0 in vfio_irq_info when the interrupt
   type is not supported.  We do this for MSI/X already, but it's assumed
   that INTx is always present since it's part of what most platforms would
   consider the minimal feature set

Re: [Qemu-devel] [RFC patch 0/6] vfio based pci pass-through for qemu/KVM on s390

2014-10-01 Thread Frank Blaschka
On Fri, Sep 26, 2014 at 01:59:40PM -0600, Alex Williamson wrote:
 On Fri, 2014-09-26 at 08:45 +0200, Frank Blaschka wrote:
  On Wed, Sep 24, 2014 at 10:05:57AM -0600, Alex Williamson wrote:
   On Wed, 2014-09-24 at 10:47 +0200, Frank Blaschka wrote:
On Mon, Sep 22, 2014 at 02:47:31PM -0600, Alex Williamson wrote:
 On Fri, 2014-09-19 at 13:54 +0200, frank.blasc...@de.ibm.com wrote:
  This set of patches implements a vfio based solution for pci
  pass-through on the s390 platform. The kernel stuff is pretty
  much straight forward, but qemu needs more work.
  
  Most interesting patch is:
vfio: make vfio run on s390 platform
  
  I hope Alex  Alex can give me some guidance how to do the changes
  in an appropriate way. After creating a separate iommmu address 
  space
  for each attached PCI device I can successfully run the vfio type1
  iommu. So If we could extend type1 not registering all guest memory
  (see patch) I think we do not need a special vfio iommu for s390
  for the moment.
  
  The patches implement the base pass-through support. s390 specific
  virtualization functions are currently not included. This would
  be a second step after the base support is done.
  
  kernel patches apply to linux-kvm-next
  
  KVM: s390: Enable PCI instructions
  iommu: add iommu for s390 platform
  vfio: make vfio build on s390
  
  qemu patches apply to qemu-master
  
  s390: Add PCI bus support
  s390: implement pci instruction
  vfio: make vfio run on s390 platform
  
  Thx for feedback and review comments
 
 Sending patches as attachments makes it difficult to comment inline.

Sorry, don't understand this. I sent every patch as separate email so
you can comment directly on the patch. What do you prefer?
   
   The patches in each email are showing up as attachments in my mail
   client.  Is it just me?
   
 2/6
  - careful of the namespace as you're changing functions from static 
 and
 exporting them
  - doesn't seem like functions need to be exported, just non-static to
 call from s390-iommu.c
 
Ok, will change this.

 6/6
  - We shouldn't need to globally disable mmap, each VFIO region 
 reports
 whether it supports mmap and vfio-pci on s390 should indicate mmap is
 not supported on the platform.
Yes, this is even better to let the kernel announce a BAR can not be
mmap'ed. Checking the kernel code I realized the BARs are valid for
mmap'ing but the s390 platform does simply not allow this. So I feal we
have to introduce a platform switch in kernel. How about this ...

--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -377,9 +377,11 @@ static long vfio_pci_ioctl(void *device_

info.flags = VFIO_REGION_INFO_FLAG_READ |
 VFIO_REGION_INFO_FLAG_WRITE;
+#ifndef CONFIG_S390
if (pci_resource_flags(pdev, info.index) 
IORESOURCE_MEM  info.size = PAGE_SIZE)
info.flags |= 
VFIO_REGION_INFO_FLAG_MMAP;
+#endif
break;
case VFIO_PCI_ROM_REGION_INDEX:
{
   
   Maybe pull it out into a function.  Also, is there some capability or
   feature we can test rather than just the architecture?  I'd prefer it to
   be excluded because of a platform feature that prevents it rather than
   the overall architecture itself.
  
  
  Ok, understand this. There is no capability of feature so I will go with
  the function.
   
  - INTx should be done the same way, the interrupt index for INTx 
 should
 report 0 count.  The current code likely doesn't handle this, but it
 should be easy to fix.
The current code is fine. Problem is the card reports an interrupt index
(PCI_INTERRUPT_PIN) but again the platform does not support INTx at all.
So we need a platform switch as well. 
   
   Yep, let's try to do something consistent with the MMAP testing.
  
  
  Do you mean let the kernel announce this also?
 
 Yes, the kernel reports a count of 0 in vfio_irq_info when the interrupt
 type is not supported.  We do this for MSI/X already, but it's assumed
 that INTx is always present since it's part of what most platforms would
 consider the minimal feature set.
 
  - s390_msix_notify() vs msix_notify() should be abstracted somewhere

Platform does not have have an apic so there is nothing we could emulate
in qemu to make the existing msix_notify() work.

 else.  How would an emulated PCI device with MSI-X support work?
  - same for add_msi_route
Same here, we have to setup an adapter route due to the fact MSIX
notifications are delivered as adapter/thin IRQs on the platform

Re: [Qemu-devel] [RFC patch 0/6] vfio based pci pass-through for qemu/KVM on s390

2014-09-26 Thread Frank Blaschka
On Wed, Sep 24, 2014 at 10:05:57AM -0600, Alex Williamson wrote:
 On Wed, 2014-09-24 at 10:47 +0200, Frank Blaschka wrote:
  On Mon, Sep 22, 2014 at 02:47:31PM -0600, Alex Williamson wrote:
   On Fri, 2014-09-19 at 13:54 +0200, frank.blasc...@de.ibm.com wrote:
This set of patches implements a vfio based solution for pci
pass-through on the s390 platform. The kernel stuff is pretty
much straight forward, but qemu needs more work.

Most interesting patch is:
  vfio: make vfio run on s390 platform

I hope Alex  Alex can give me some guidance how to do the changes
in an appropriate way. After creating a separate iommmu address space
for each attached PCI device I can successfully run the vfio type1
iommu. So If we could extend type1 not registering all guest memory
(see patch) I think we do not need a special vfio iommu for s390
for the moment.

The patches implement the base pass-through support. s390 specific
virtualization functions are currently not included. This would
be a second step after the base support is done.

kernel patches apply to linux-kvm-next

KVM: s390: Enable PCI instructions
iommu: add iommu for s390 platform
vfio: make vfio build on s390

qemu patches apply to qemu-master

s390: Add PCI bus support
s390: implement pci instruction
vfio: make vfio run on s390 platform

Thx for feedback and review comments
   
   Sending patches as attachments makes it difficult to comment inline.
  
  Sorry, don't understand this. I sent every patch as separate email so
  you can comment directly on the patch. What do you prefer?
 
 The patches in each email are showing up as attachments in my mail
 client.  Is it just me?
 
   2/6
- careful of the namespace as you're changing functions from static and
   exporting them
- doesn't seem like functions need to be exported, just non-static to
   call from s390-iommu.c
   
  Ok, will change this.
  
   6/6
- We shouldn't need to globally disable mmap, each VFIO region reports
   whether it supports mmap and vfio-pci on s390 should indicate mmap is
   not supported on the platform.
  Yes, this is even better to let the kernel announce a BAR can not be
  mmap'ed. Checking the kernel code I realized the BARs are valid for
  mmap'ing but the s390 platform does simply not allow this. So I feal we
  have to introduce a platform switch in kernel. How about this ...
  
  --- a/drivers/vfio/pci/vfio_pci.c
  +++ b/drivers/vfio/pci/vfio_pci.c
  @@ -377,9 +377,11 @@ static long vfio_pci_ioctl(void *device_
  
  info.flags = VFIO_REGION_INFO_FLAG_READ |
   VFIO_REGION_INFO_FLAG_WRITE;
  +#ifndef CONFIG_S390
  if (pci_resource_flags(pdev, info.index) 
  IORESOURCE_MEM  info.size = PAGE_SIZE)
  info.flags |= VFIO_REGION_INFO_FLAG_MMAP;
  +#endif
  break;
  case VFIO_PCI_ROM_REGION_INDEX:
  {
 
 Maybe pull it out into a function.  Also, is there some capability or
 feature we can test rather than just the architecture?  I'd prefer it to
 be excluded because of a platform feature that prevents it rather than
 the overall architecture itself.


Ok, understand this. There is no capability of feature so I will go with
the function.
 
- INTx should be done the same way, the interrupt index for INTx should
   report 0 count.  The current code likely doesn't handle this, but it
   should be easy to fix.
  The current code is fine. Problem is the card reports an interrupt index
  (PCI_INTERRUPT_PIN) but again the platform does not support INTx at all.
  So we need a platform switch as well. 
 
 Yep, let's try to do something consistent with the MMAP testing.


Do you mean let the kernel announce this also?

- s390_msix_notify() vs msix_notify() should be abstracted somewhere
  
  Platform does not have have an apic so there is nothing we could emulate
  in qemu to make the existing msix_notify() work.
  
   else.  How would an emulated PCI device with MSI-X support work?
- same for add_msi_route
  Same here, we have to setup an adapter route due to the fact MSIX
  notifications are delivered as adapter/thin IRQs on the platform.
  
  Any suggestion or idea how a better abstraction could look like?
  
  With all the platform constraints I was not able to find a suitable
  emulated device. Remember s390:
  - does not support IO BARs
  - does not support INTx only MSIX
 
 What about MSI (non-X)?

In theory MSI should work also but I have not seen in reality.

 
  - in reality currently there is only a PCI network card available
 
 On the physical hardware?
 

yes

  - platform does not support fancy I/O like usb or audio :-)
So we don't even have kernel (host and guest) support for this
kind of devices.
 
 Does that mean you couldn't

Re: [Qemu-devel] [RFC patch 5/6] s390: implement pci instruction

2014-09-22 Thread Frank Blaschka
On Fri, Sep 19, 2014 at 05:12:15PM +0200, Thomas Huth wrote:
 
  Hi Frank,
 
 On Fri, 19 Sep 2014 13:54:34 +0200
 frank.blasc...@de.ibm.com wrote:
 
  From: Frank Blaschka frank.blasc...@de.ibm.com
  
  This patch implements the s390 pci instructions in qemu. This allows
  to attach qemu pci devices including vfio. This does not mean the
  devices are functional but at least detection and config/memory space
  access is working.
  
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
  ---
   target-s390x/Makefile.objs |2 
   target-s390x/kvm.c |   52 +++
   target-s390x/pci_ic.c  |  621 
  +
   target-s390x/pci_ic.h  |  425 ++
   4 files changed, 1099 insertions(+), 1 deletion(-)
  
  --- a/target-s390x/Makefile.objs
  +++ b/target-s390x/Makefile.objs
  @@ -2,4 +2,4 @@ obj-y += translate.o helper.o cpu.o inte
   obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
   obj-y += gdbstub.o
   obj-$(CONFIG_SOFTMMU) += ioinst.o arch_dump.o
  -obj-$(CONFIG_KVM) += kvm.o
  +obj-$(CONFIG_KVM) += kvm.o pci_ic.o
  --- a/target-s390x/kvm.c
  +++ b/target-s390x/kvm.c
  @@ -40,6 +40,7 @@
   #include exec/gdbstub.h
   #include trace.h
   #include qapi-event.h
  +#include pci_ic.h
  
   /* #define DEBUG_KVM */
  
  @@ -56,6 +57,7 @@
   #define IPA0_B2 0xb200
   #define IPA0_B9 0xb900
   #define IPA0_EB 0xeb00
  +#define IPA0_E3 0xe300
  
   #define PRIV_B2_SCLP_CALL   0x20
   #define PRIV_B2_CSCH0x30
  @@ -76,8 +78,17 @@
   #define PRIV_B2_XSCH0x76
  
   #define PRIV_EB_SQBS0x8a
  +#define PRIV_EB_PCISTB  0xd0
  +#define PRIV_EB_SIC 0xd1
  
   #define PRIV_B9_EQBS0x9c
  +#define PRIV_B9_CLP 0xa0
  +#define PRIV_B9_PCISTG  0xd0
  +#define PRIV_B9_PCILG   0xd2
  +#define PRIV_B9_RPCIT   0xd3
  +
  +#define PRIV_E3_MPCIFC  0xd0
  +#define PRIV_E3_STPCIFC 0xd4
  
   #define DIAG_IPL0x308
   #define DIAG_KVM_HYPERCALL  0x500
  @@ -813,6 +824,18 @@ static int handle_b9(S390CPU *cpu, struc
   int r = 0;
  
   switch (ipa1) {
  +case PRIV_B9_CLP:
  +r = kvm_clp_service_call(cpu, run);
  +break;
  +case PRIV_B9_PCISTG:
  +r = kvm_pcistg_service_call(cpu, run);
  +break;
  +case PRIV_B9_PCILG:
  +r = kvm_pcilg_service_call(cpu, run);
  +break;
  +case PRIV_B9_RPCIT:
  +r = kvm_rpcit_service_call(cpu, run);
  +break;
   case PRIV_B9_EQBS:
   /* just inject exception */
   r = -1;
  @@ -831,6 +854,12 @@ static int handle_eb(S390CPU *cpu, struc
   int r = 0;
  
   switch (ipa1) {
  +case PRIV_EB_PCISTB:
  +r = kvm_pcistb_service_call(cpu, run);
  +break;
  +case PRIV_EB_SIC:
  +r = kvm_sic_service_call(cpu, run);
  +break;
   case PRIV_EB_SQBS:
   /* just inject exception */
   r = -1;
 
 I'm not sure, but I think the handler for the eb instructions is wrong:
 The second byte of the opcode is encoded in the lowest byte of the ipb
 field, not the lowest byte of the ipa field (just like with the e3
 handler). Did you verify that your handlers get called correctly?


Hi Thomas, you are absolutely right. I already have a patch available for
this issue but did not append it to this RFC post (since it is basically a bug
fix). To the next posting I will add this patch as well.

Will also fix the remaining issues thx for your review.
 
  @@ -844,6 +873,26 @@ static int handle_eb(S390CPU *cpu, struc
   return r;
   }
  
  +static int handle_e3(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
  +{
  +int r = 0;
  +
  +switch (ipa1) {
  +case PRIV_E3_MPCIFC:
  +r = kvm_mpcifc_service_call(cpu, run);
  +break;
  +case PRIV_E3_STPCIFC:
  +r = kvm_stpcifc_service_call(cpu, run);
  +break;
  +default:
  +r = -1;
  +DPRINTF(KVM: unhandled PRIV: 0xe3%x\n, ipa1);
  +break;
  +}
  +
  +return r;
  +}
 
 Could you please replace ipa1 with ipb1 to avoid confusion here?
 
   static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)
   {
   CPUS390XState *env = cpu-env;
  @@ -1038,6 +1087,9 @@ static int handle_instruction(S390CPU *c
   case IPA0_EB:
   r = handle_eb(cpu, run, ipa1);
   break;
  +case IPA0_E3:
  +r = handle_e3(cpu, run, run-s390_sieic.ipb  0xff);
  +break;
   case IPA0_DIAG:
   r = handle_diag(cpu, run, run-s390_sieic.ipb);
   break;
  --- /dev/null
  +++ b/target-s390x/pci_ic.c
  @@ -0,0 +1,621 @@
 [...]
  +
  +int kvm_pcilg_service_call

[Qemu-devel] [RFC patch 3/6] vfio: make vfio build on s390

2014-09-19 Thread frank . blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch adds some small changes to make vfio build on s390.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 drivers/vfio/Kconfig |2 +-
 drivers/vfio/pci/vfio_pci_rdwr.c |8 
 2 files changed, 9 insertions(+), 1 deletion(-)

--- a/drivers/vfio/Kconfig
+++ b/drivers/vfio/Kconfig
@@ -16,7 +16,7 @@ config VFIO_SPAPR_EEH
 menuconfig VFIO
tristate VFIO Non-Privileged userspace driver framework
depends on IOMMU_API
-   select VFIO_IOMMU_TYPE1 if X86
+   select VFIO_IOMMU_TYPE1 if (X86 || S390)
select VFIO_IOMMU_SPAPR_TCE if (PPC_POWERNV || PPC_PSERIES)
select VFIO_SPAPR_EEH if (PPC_POWERNV || PPC_PSERIES)
select ANON_INODES
--- a/drivers/vfio/pci/vfio_pci_rdwr.c
+++ b/drivers/vfio/pci/vfio_pci_rdwr.c
@@ -177,6 +177,13 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_
return done;
 }
 
+#ifdef CONFIG_NO_IOPORT_MAP
+ssize_t vfio_pci_vga_rw(struct vfio_pci_device *vdev, char __user *buf,
+   size_t count, loff_t *ppos, bool iswrite)
+{
+   return -EINVAL;
+}
+#else
 ssize_t vfio_pci_vga_rw(struct vfio_pci_device *vdev, char __user *buf,
   size_t count, loff_t *ppos, bool iswrite)
 {
@@ -236,3 +243,4 @@ ssize_t vfio_pci_vga_rw(struct vfio_pci_
 
return done;
 }
+#endif




[Qemu-devel] [RFC patch 1/6] KVM: s390: Enable PCI instructions

2014-09-19 Thread frank . blaschka
Enable PCI instructions for s390 KVM.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 arch/s390/kvm/kvm-s390.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1787,7 +1787,7 @@ static int __init kvm_s390_init(void)
}
memcpy(vfacilities, S390_lowcore.stfle_fac_list, 16);
vfacilities[0] = 0xff82fff3f4fc2000UL;
-   vfacilities[1] = 0x005cUL;
+   vfacilities[1] = 0x07dcUL;
return 0;
 }
 




[Qemu-devel] [RFC patch 0/6] vfio based pci pass-through for qemu/KVM on s390

2014-09-19 Thread frank . blaschka
This set of patches implements a vfio based solution for pci
pass-through on the s390 platform. The kernel stuff is pretty
much straight forward, but qemu needs more work.

Most interesting patch is:
  vfio: make vfio run on s390 platform

I hope Alex  Alex can give me some guidance how to do the changes
in an appropriate way. After creating a separate iommmu address space
for each attached PCI device I can successfully run the vfio type1
iommu. So If we could extend type1 not registering all guest memory
(see patch) I think we do not need a special vfio iommu for s390
for the moment.

The patches implement the base pass-through support. s390 specific
virtualization functions are currently not included. This would
be a second step after the base support is done.

kernel patches apply to linux-kvm-next

KVM: s390: Enable PCI instructions
iommu: add iommu for s390 platform
vfio: make vfio build on s390

qemu patches apply to qemu-master

s390: Add PCI bus support
s390: implement pci instruction
vfio: make vfio run on s390 platform

Thx for feedback and review comments

Frank




[Qemu-devel] [RFC patch 5/6] s390: implement pci instruction

2014-09-19 Thread frank . blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements the s390 pci instructions in qemu. This allows
to attach qemu pci devices including vfio. This does not mean the
devices are functional but at least detection and config/memory space
access is working.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 target-s390x/Makefile.objs |2 
 target-s390x/kvm.c |   52 +++
 target-s390x/pci_ic.c  |  621 +
 target-s390x/pci_ic.h  |  425 ++
 4 files changed, 1099 insertions(+), 1 deletion(-)

--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -2,4 +2,4 @@ obj-y += translate.o helper.o cpu.o inte
 obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
 obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += ioinst.o arch_dump.o
-obj-$(CONFIG_KVM) += kvm.o
+obj-$(CONFIG_KVM) += kvm.o pci_ic.o
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -40,6 +40,7 @@
 #include exec/gdbstub.h
 #include trace.h
 #include qapi-event.h
+#include pci_ic.h
 
 /* #define DEBUG_KVM */
 
@@ -56,6 +57,7 @@
 #define IPA0_B2 0xb200
 #define IPA0_B9 0xb900
 #define IPA0_EB 0xeb00
+#define IPA0_E3 0xe300
 
 #define PRIV_B2_SCLP_CALL   0x20
 #define PRIV_B2_CSCH0x30
@@ -76,8 +78,17 @@
 #define PRIV_B2_XSCH0x76
 
 #define PRIV_EB_SQBS0x8a
+#define PRIV_EB_PCISTB  0xd0
+#define PRIV_EB_SIC 0xd1
 
 #define PRIV_B9_EQBS0x9c
+#define PRIV_B9_CLP 0xa0
+#define PRIV_B9_PCISTG  0xd0
+#define PRIV_B9_PCILG   0xd2
+#define PRIV_B9_RPCIT   0xd3
+
+#define PRIV_E3_MPCIFC  0xd0
+#define PRIV_E3_STPCIFC 0xd4
 
 #define DIAG_IPL0x308
 #define DIAG_KVM_HYPERCALL  0x500
@@ -813,6 +824,18 @@ static int handle_b9(S390CPU *cpu, struc
 int r = 0;
 
 switch (ipa1) {
+case PRIV_B9_CLP:
+r = kvm_clp_service_call(cpu, run);
+break;
+case PRIV_B9_PCISTG:
+r = kvm_pcistg_service_call(cpu, run);
+break;
+case PRIV_B9_PCILG:
+r = kvm_pcilg_service_call(cpu, run);
+break;
+case PRIV_B9_RPCIT:
+r = kvm_rpcit_service_call(cpu, run);
+break;
 case PRIV_B9_EQBS:
 /* just inject exception */
 r = -1;
@@ -831,6 +854,12 @@ static int handle_eb(S390CPU *cpu, struc
 int r = 0;
 
 switch (ipa1) {
+case PRIV_EB_PCISTB:
+r = kvm_pcistb_service_call(cpu, run);
+break;
+case PRIV_EB_SIC:
+r = kvm_sic_service_call(cpu, run);
+break;
 case PRIV_EB_SQBS:
 /* just inject exception */
 r = -1;
@@ -844,6 +873,26 @@ static int handle_eb(S390CPU *cpu, struc
 return r;
 }
 
+static int handle_e3(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
+{
+int r = 0;
+
+switch (ipa1) {
+case PRIV_E3_MPCIFC:
+r = kvm_mpcifc_service_call(cpu, run);
+break;
+case PRIV_E3_STPCIFC:
+r = kvm_stpcifc_service_call(cpu, run);
+break;
+default:
+r = -1;
+DPRINTF(KVM: unhandled PRIV: 0xe3%x\n, ipa1);
+break;
+}
+
+return r;
+}
+
 static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)
 {
 CPUS390XState *env = cpu-env;
@@ -1038,6 +1087,9 @@ static int handle_instruction(S390CPU *c
 case IPA0_EB:
 r = handle_eb(cpu, run, ipa1);
 break;
+case IPA0_E3:
+r = handle_e3(cpu, run, run-s390_sieic.ipb  0xff);
+break;
 case IPA0_DIAG:
 r = handle_diag(cpu, run, run-s390_sieic.ipb);
 break;
--- /dev/null
+++ b/target-s390x/pci_ic.c
@@ -0,0 +1,621 @@
+/*
+ * s390 PCI intercepts
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include sys/types.h
+#include sys/ioctl.h
+#include sys/mman.h
+
+#include linux/kvm.h
+#include asm/ptrace.h
+#include hw/pci/pci.h
+#include hw/pci/pci_host.h
+#include net/net.h
+
+#include qemu-common.h
+#include qemu/timer.h
+#include migration/qemu-file.h
+#include sysemu/sysemu.h
+#include sysemu/kvm.h
+#include cpu.h
+#include sysemu/device_tree.h
+#include monitor/monitor.h
+#include pci_ic.h
+
+#include hw/hw.h
+#include hw/pci/pci.h
+#include hw/pci/pci_bridge.h
+#include hw/pci/pci_bus.h
+#include hw/pci/pci_host.h
+#include hw/s390x/s390-pci-bus.h
+#include exec/exec-all.h
+
+/* #define DEBUG_S390PCI_IC */
+#ifdef DEBUG_S390PCI_IC
+#define DPRINTF(fmt

[Qemu-devel] [RFC patch 2/6] iommu: add iommu for s390 platform

2014-09-19 Thread frank . blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

Add a basic iommu for the s390 platform. The code is pretty
simple since on s390 each PCI device has its own virtual io address
space starting at the same vio address. For this a domain could
hold only one pci device. Also there is no relation between pci
devices so each device belongs to a separate iommu group.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 arch/s390/include/asm/pci.h |3 
 arch/s390/pci/pci_dma.c |   21 -
 drivers/iommu/Kconfig   |9 ++
 drivers/iommu/Makefile  |1 
 drivers/iommu/s390-iommu.c  |  181 
 5 files changed, 213 insertions(+), 2 deletions(-)

--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -177,6 +177,9 @@ struct zpci_dev *get_zdev_by_fid(u32);
 /* DMA */
 int zpci_dma_init(void);
 void zpci_dma_exit(void);
+int dma_update_trans(struct zpci_dev *zdev, unsigned long pa,
+dma_addr_t dma_addr, size_t size, int flags);
+void dma_purge_rto_entries(struct zpci_dev *zdev);
 
 /* FMB */
 int zpci_fmb_enable_device(struct zpci_dev *);
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -139,8 +139,8 @@ static void dma_update_cpu_trans(struct
entry_clr_protected(entry);
 }
 
-static int dma_update_trans(struct zpci_dev *zdev, unsigned long pa,
-   dma_addr_t dma_addr, size_t size, int flags)
+int dma_update_trans(struct zpci_dev *zdev, unsigned long pa,
+dma_addr_t dma_addr, size_t size, int flags)
 {
unsigned int nr_pages = PAGE_ALIGN(size)  PAGE_SHIFT;
u8 *page_addr = (u8 *) (pa  PAGE_MASK);
@@ -180,6 +180,7 @@ no_refresh:
spin_unlock_irqrestore(zdev-dma_table_lock, irq_flags);
return rc;
 }
+EXPORT_SYMBOL_GPL(dma_update_trans);
 
 static void dma_free_seg_table(unsigned long entry)
 {
@@ -210,6 +211,22 @@ static void dma_cleanup_tables(struct zp
zdev-dma_table = NULL;
 }
 
+void dma_purge_rto_entries(struct zpci_dev *zdev)
+{
+   unsigned long *table;
+   int rtx;
+
+   if (!zdev || !zdev-dma_table)
+   return;
+   table = zdev-dma_table;
+   for (rtx = 0; rtx  ZPCI_TABLE_ENTRIES; rtx++)
+   if (reg_entry_isvalid(table[rtx])) {
+   dma_free_seg_table(table[rtx]);
+   invalidate_table_entry(table[rtx]);
+   }
+}
+EXPORT_SYMBOL_GPL(dma_purge_rto_entries);
+
 static unsigned long __dma_alloc_iommu(struct zpci_dev *zdev,
   unsigned long start, int size)
 {
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -302,4 +302,13 @@ config ARM_SMMU
  Say Y here if your SoC includes an IOMMU device implementing
  the ARM SMMU architecture.
 
+config S390_IOMMU
+bool s390 IOMMU Support
+depends on S390
+select IOMMU_API
+help
+  Support for the IBM s/390 IOMMU
+
+  If unsure, say N here.
+
 endif # IOMMU_SUPPORT
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -19,3 +19,4 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iom
 obj-$(CONFIG_SHMOBILE_IOMMU) += shmobile-iommu.o
 obj-$(CONFIG_SHMOBILE_IPMMU) += shmobile-ipmmu.o
 obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
+obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
--- /dev/null
+++ b/drivers/iommu/s390-iommu.c
@@ -0,0 +1,181 @@
+#include linux/io.h
+#include linux/interrupt.h
+#include linux/platform_device.h
+#include linux/slab.h
+#include linux/pm_runtime.h
+#include linux/clk.h
+#include linux/err.h
+#include linux/mm.h
+#include linux/iommu.h
+#include linux/errno.h
+#include linux/list.h
+#include linux/memblock.h
+#include linux/export.h
+#include linux/pci.h
+#include linux/sizes.h
+#include asm/pci_dma.h
+
+#define S390_IOMMU_PGSIZES SZ_4K
+
+struct s390_domain {
+   struct zpci_dev *zdev;
+};
+
+static int s390_iommu_domain_init(struct iommu_domain *domain)
+{
+   struct s390_domain *priv;
+
+   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+   if (!priv)
+   return -ENOMEM;
+
+   domain-priv = priv;
+   return 0;
+}
+
+static void s390_iommu_domain_destroy(struct iommu_domain *domain)
+{
+   kfree(domain-priv);
+   domain-priv = NULL;
+}
+
+static int s390_iommu_attach_device(struct iommu_domain *domain,
+   struct device *dev)
+{
+   struct s390_domain *priv = domain-priv;
+
+   if (priv-zdev)
+   return -EEXIST;
+
+   priv-zdev = (struct zpci_dev *)to_pci_dev(dev)-sysdata;
+   return 0;
+}
+
+static void s390_iommu_detach_device(struct iommu_domain *domain,
+struct device *dev)
+{
+   struct s390_domain *priv = domain-priv;
+
+   dma_purge_rto_entries(priv-zdev);
+   priv-zdev = NULL;
+}
+
+static int s390_iommu_map(struct iommu_domain *domain, unsigned long iova

[Qemu-devel] [RFC patch 6/6] vfio: make vfio run on s390 platform

2014-09-19 Thread frank . blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

Following changes are made because of platform differences:

1) s390 does not support mmap'ing of PCI BARs so we have to go via slow path
2) no intx support
3) no classic MSIX interrupts. The pci hw understands the concept
   of requesting MSIX irqs but irqs are delivered as s390 adapter irqs.
   Introduce s390 specific functions for msix notification (slow path) and
   msi routes (kvm fast path).
4) Use type1 iommu but register only for iommu address space

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 hw/misc/vfio.c |   24 
 1 file changed, 24 insertions(+)

--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -40,6 +40,9 @@
 #include sysemu/kvm.h
 #include sysemu/sysemu.h
 #include hw/misc/vfio.h
+#ifdef TARGET_S390X
+#include hw/s390x/s390-pci-bus.h
+#endif
 
 /* #define DEBUG_VFIO */
 #ifdef DEBUG_VFIO
@@ -51,7 +54,11 @@
 #endif
 
 /* Extra debugging, trap acceleration paths for more logging */
+#ifdef TARGET_S390X
+#define VFIO_ALLOW_MMAP 0
+#else
 #define VFIO_ALLOW_MMAP 1
+#endif
 #define VFIO_ALLOW_KVM_INTX 1
 #define VFIO_ALLOW_KVM_MSI 1
 #define VFIO_ALLOW_KVM_MSIX 1
@@ -554,6 +561,10 @@ static int vfio_enable_intx(VFIODevice *
 struct vfio_irq_set *irq_set;
 int32_t *pfd;
 
+#ifdef TARGET_S390X
+return 0;
+#endif
+
 if (!pin) {
 return 0;
 }
@@ -664,7 +675,11 @@ static void vfio_msi_interrupt(void *opa
 #endif
 
 if (vdev-interrupt == VFIO_INT_MSIX) {
+#ifdef TARGET_S390X
+s390_msix_notify(vdev-pdev, nr);
+#else
 msix_notify(vdev-pdev, nr);
+#endif
 } else if (vdev-interrupt == VFIO_INT_MSI) {
 msi_notify(vdev-pdev, nr);
 } else {
@@ -730,7 +745,11 @@ static void vfio_add_kvm_msi_virq(VFIOMS
 return;
 }
 
+#ifdef TARGET_S390X
+virq = s390_irqchip_add_msi_route(vector-vdev-pdev, kvm_state, *msg);
+#else
 virq = kvm_irqchip_add_msi_route(kvm_state, *msg);
+#endif
 if (virq  0) {
 event_notifier_cleanup(vector-kvm_interrupt);
 return;
@@ -3702,8 +3721,13 @@ static int vfio_connect_container(VFIOGr
 container-iommu_data.type1.listener = vfio_memory_listener;
 container-iommu_data.release = vfio_listener_release;
 
+#ifdef TARGET_S390X
+memory_listener_register(container-iommu_data.type1.listener,
+ container-space-as);
+#else
 memory_listener_register(container-iommu_data.type1.listener,
  address_space_memory);
+#endif
 
 if (container-iommu_data.type1.error) {
 ret = container-iommu_data.type1.error;




[Qemu-devel] [RFC patch 4/6] s390: Add PCI bus support

2014-09-19 Thread frank . blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements a pci bus for s390x together with some infrastructure
to generate and handle hotplug events. It also provides device 
configuration/unconfiguration via sclp instruction interception.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 default-configs/s390x-softmmu.mak |1 
 hw/s390x/Makefile.objs|1 
 hw/s390x/css.c|5 
 hw/s390x/css.h|1 
 hw/s390x/s390-pci-bus.c   |  404 ++
 hw/s390x/s390-pci-bus.h   |  166 +++
 hw/s390x/s390-virtio-ccw.c|2 
 hw/s390x/sclp.c   |   10 
 include/hw/s390x/sclp.h   |8 
 target-s390x/ioinst.c |   52 
 target-s390x/ioinst.h |1 
 11 files changed, 650 insertions(+), 1 deletion(-)

--- a/default-configs/s390x-softmmu.mak
+++ b/default-configs/s390x-softmmu.mak
@@ -1,3 +1,4 @@
+include pci.mak
 CONFIG_VIRTIO=y
 CONFIG_SCLPCONSOLE=y
 CONFIG_S390_FLIC=y
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -8,3 +8,4 @@ obj-y += ipl.o
 obj-y += css.o
 obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
+obj-$(CONFIG_KVM) += s390-pci-bus.o
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1281,6 +1281,11 @@ void css_generate_chp_crws(uint8_t cssid
 /* TODO */
 }
 
+void css_generate_css_crws(uint8_t cssid)
+{
+css_queue_crw(CRW_RSC_CSS, 0, 0, 0);
+}
+
 int css_enable_mcsse(void)
 {
 trace_css_enable_facility(mcsse);
--- a/hw/s390x/css.h
+++ b/hw/s390x/css.h
@@ -99,6 +99,7 @@ void css_queue_crw(uint8_t rsc, uint8_t
 void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
int hotplugged, int add);
 void css_generate_chp_crws(uint8_t cssid, uint8_t chpid);
+void css_generate_css_crws(uint8_t cssid);
 void css_adapter_interrupt(uint8_t isc);
 
 #define CSS_IO_ADAPTER_VIRTIO 1
--- /dev/null
+++ b/hw/s390x/s390-pci-bus.c
@@ -0,0 +1,404 @@
+/*
+ * s390 PCI BUS
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include hw/pci/pci.h
+#include hw/s390x/css.h
+#include hw/s390x/sclp.h
+#include hw/pci/msi.h
+#include qemu/error-report.h
+#include s390-pci-bus.h
+
+/* #define DEBUG_S390PCI_BUS */
+#ifdef DEBUG_S390PCI_BUS
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, S390pci-bus:  fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+static const unsigned long be_to_le = BITS_PER_LONG - 1;
+static QTAILQ_HEAD(, SeiContainer) pending_sei =
+QTAILQ_HEAD_INITIALIZER(pending_sei);
+static QTAILQ_HEAD(, S390PCIBusDevice) device_list =
+QTAILQ_HEAD_INITIALIZER(device_list);
+
+int chsc_sei_nt2_get_event(void *res)
+{
+ChscSeiNt2Res *nt2_res = (ChscSeiNt2Res *)res;
+PciCcdfAvail *accdf;
+PciCcdfErr *eccdf;
+int rc = 1;
+SeiContainer *sei_cont;
+
+sei_cont = QTAILQ_FIRST(pending_sei);
+if (sei_cont) {
+QTAILQ_REMOVE(pending_sei, sei_cont, link);
+nt2_res-nt = 2;
+nt2_res-cc = sei_cont-cc;
+switch (sei_cont-cc) {
+case 1: /* error event */
+eccdf = (PciCcdfErr *)nt2_res-ccdf;
+eccdf-fid = cpu_to_be32(sei_cont-fid);
+eccdf-fh = cpu_to_be32(sei_cont-fh);
+break;
+case 2: /* availability event */
+accdf = (PciCcdfAvail *)nt2_res-ccdf;
+accdf-fid = cpu_to_be32(sei_cont-fid);
+accdf-fh = cpu_to_be32(sei_cont-fh);
+accdf-pec = cpu_to_be16(sei_cont-pec);
+break;
+default:
+abort();
+}
+g_free(sei_cont);
+rc = 0;
+}
+
+return rc;
+}
+
+int chsc_sei_nt2_have_event(void)
+{
+return !QTAILQ_EMPTY(pending_sei);
+}
+
+static S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid)
+{
+S390PCIBusDevice *pbdev;
+
+QTAILQ_FOREACH(pbdev, device_list, next) {
+if (pbdev-fid == fid) {
+return pbdev;
+}
+}
+return NULL;
+}
+
+void s390_pci_sclp_configure(int configure, SCCB *sccb)
+{
+PciCfgSccb *psccb = (PciCfgSccb *)sccb;
+S390PCIBusDevice *pbdev = 
s390_pci_find_dev_by_fid(be32_to_cpu(psccb-aid));
+uint16_t rc;
+
+if (pbdev) {
+if ((configure == 1  pbdev-configured == true) ||
+(configure == 0  pbdev-configured == false)) {
+rc = SCLP_RC_NO_ACTION_REQUIRED;
+} else {
+pbdev-configured = !pbdev-configured;
+rc = SCLP_RC_NORMAL_COMPLETION;
+}
+} else {
+DPRINTF(sclp config %d no dev found\n, configure);
+rc

Re: [Qemu-devel] [RFC][patch 0/6] pci pass-through support for qemu/KVM on s390

2014-09-05 Thread Frank Blaschka
On Thu, Sep 04, 2014 at 07:16:24AM -0600, Alex Williamson wrote:
 On Thu, 2014-09-04 at 12:52 +0200, frank.blasc...@de.ibm.com wrote:
  This set of patches implements pci pass-through support for qemu/KVM on 
  s390.
  PCI support on s390 is very different from other platforms.
  Major differences are:
  
  1) all PCI operations are driven by special s390 instructions
 
 Generating config cycles is always arch specific.
 
  2) all s390 PCI instructions are privileged
 
 While the operations to generate config cycles on x86 are not
 privileged, they must be arbitrated between accesses, so in a sense
 they're privileged.
 
  3) PCI config and memory spaces can not be mmap'ed
 
 VFIO has mapping flags that allow any region to specify mmap support.


Hi Alex,

thx for your reply.

Let me elaborate a little bit ore on 1 - 3. Config and memory space can not
be accessed via memory operations. You have to use special s390 instructions.
This instructions can not be executed in user space. So there is no other
way than executing this instructions in kernel. Yes vfio does support a
slow path via ioctrl we could use, but this seems suboptimal from performance
point of view.
 
  4) no classic interrupts (INTX, MSI). The pci hw understands the concept
 of requesting MSIX irqs but irqs are delivered as s390 adapter irqs.
 
 VFIO delivers interrupts as eventfds regardless of the underlying
 platform mechanism.
 

yes that's right, but then we have to do platform specific stuff to present
the irq to the guest. I do not say this is impossible but we have add s390
specific code to vfio. 

  5) For DMA access there is always an IOMMU required.
 
 x86 requires the same.
 
   s390 pci implementation
 does not support a complete memory to iommu mapping, dma mappings are
 created on request.
 
 Sounds like POWER.

Don't know the details from power, maybe it is similar but not the same.
We might be able to extend vfio to have a new interface allowing
us to do DMA mappings on request.

 
  6) The OS does not get any informations about the physical layout
 of the PCI bus.
 
 If that means that every device is isolated (seems unlikely for
 multifunction devices) then that makes IOMMU group support really easy.


OK
 
  7) To take advantage of system z specific virtualization features
 we need to access the SIE control block residing in the kernel KVM
 
 The KVM-VFIO device allows interaction between VFIO devices and KVM.
 
  8) To enable system z specific virtualization features we have to manipulate
 the zpci device in kernel.
 
 VFIO supports different device backends, currently pci_dev and working
 towards platform devices.  zpci might just be an extension to standard
 pci.
 

7 - 8 At least this is not as straightforward as the pure kernel approach, but
I have to dig into that in more detail if we could only agree on a vfio 
solution.

  For this reasons I decided to implement a kernel based approach similar
  to x86 device assignment. There is a new qemu device (s390-pci) 
  representing a
  pass through device on the host. Here is a sample qemu device configuration:
  
  -device s390-pci,host=:00:00.0
  
  The device executes the KVM_ASSIGN_PCI_DEVICE ioctl to create a proxy 
  instance
  in the kernel KVM and connect this instance to the host pci device.
  
  kernel patches apply to linux-kvm
  
  s390: cio: chsc function to register GIB
  s390: pci: export pci functions for pass-through usage
  KVM: s390: Add GISA support
  KVM: s390: Add PCI pass-through support
  
  qemu patches apply to qemu-master
  
  s390: Add PCI bus support
  s390: Add PCI pass-through device support
  
  Feedback and discussion is highly welcome ...
 
 KVM-based device assignment needs to go away.  It's a horrible model for
 devices, it offers very little protection to the kernel, assumes every
 device is fully isolated and visible to the IOMMU, relies on smattering
 of sysfs files to operate, etc.  x86, POWER, and ARM are all moving to
 VFIO-based device assignment.  Why is s390 special enough to repeat all
 the mistakes that x86 did?  Thanks,
 

Is this your personal opinion or was this a strategic decision of the
QEMU/KVM community? Can anybody give us direction about this?

Actually I can understand your point. In the last weeks I did some development
and testing regarding the use of vfio too. But the in kernel solutions seems to
offer the best performance and most straighforward implementation for our
platform.

Greetings,

Frank

 Alex
 
 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 




Re: [Qemu-devel] [RFC][patch 3/6] KVM: s390: Add GISA support

2014-09-05 Thread Frank Blaschka
On Fri, Sep 05, 2014 at 10:29:26AM +0200, Alexander Graf wrote:
 
 
 On 04.09.14 12:52, frank.blasc...@de.ibm.com wrote:
  From: Frank Blaschka frank.blasc...@de.ibm.com
  
  This patch adds GISA (Guest Interrupt State Area) support
  to s390 kvm. GISA can be used for exitless interrupts. The
  patch provides a set of functions for GISA related operations
  like accessing GISA fields or registering ISCs for alert.
  Exploiters of GISA will follow with additional patches.
  
  Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
 
 That's a nice feature. However, please make sure that you maintain the
 abstraction levels.
 
 What should happen is that you request an irqfd from FLIC. Then you
 associate that irqfd with the PCI device.
 
 Thanks to that association, both parties can now talk to each other and
 negotiate their GISA number space and make sure things are connected.
 
 However, it should always be possible to do things without this direct
 IRQ injection.
 
 So you should be able to receive an irqfd event when an IRQ happened, so
 that VFIO user space applications can also handle interrupts for example.
 
 And the same applies for interrupt injection. We also need to be able to
 inject an adapter interrupt from QEMU for emulated devices ;).


OK, assuming we are doing the vfio solution expoiting GISA would be a
second step. Will take your feedback into account. THX!
 
 Alex
 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 




Re: [Qemu-devel] [RFC][patch 0/6] pci pass-through support for qemu/KVM on s390

2014-09-05 Thread Frank Blaschka
On Fri, Sep 05, 2014 at 10:21:27AM +0200, Alexander Graf wrote:
 
 
 On 04.09.14 12:52, frank.blasc...@de.ibm.com wrote:
  This set of patches implements pci pass-through support for qemu/KVM on 
  s390.
  PCI support on s390 is very different from other platforms.
  Major differences are:
  
  1) all PCI operations are driven by special s390 instructions
  2) all s390 PCI instructions are privileged
  3) PCI config and memory spaces can not be mmap'ed
 
 That's ok, vfio abstracts config space anyway.
 
  4) no classic interrupts (INTX, MSI). The pci hw understands the concept
 of requesting MSIX irqs but irqs are delivered as s390 adapter irqs.
 
 This is in line with other implementations. Interrupts go from
 
   device - PHB - PIC - CPU
 
 (some times you can have another converter device in between)
 
 In your case, the PHB converts INTX and MSI interrupts to Adapter
 interrupts to go to the floating interrupt controller. Same thing as
 everyone else really.
 

Yes, I think this can be done, but we need s390 specific changes in vfio.

  5) For DMA access there is always an IOMMU required. s390 pci implementation
 does not support a complete memory to iommu mapping, dma mappings are
 created on request.
 
 Sounds great :). So I suppose we should implement a guest facing IOMMU?
 
  6) The OS does not get any informations about the physical layout
 of the PCI bus.
 
 So how does it know whether different devices are behind the same IOMMU
 context? Or can we assume that every device has its own context?

Actually yes

 
  7) To take advantage of system z specific virtualization features
 we need to access the SIE control block residing in the kernel KVM
 
 Pleas elaborate.
 
  8) To enable system z specific virtualization features we have to manipulate
 the zpci device in kernel.
 
 Why?


We have following s390 specific virtualization features:

1) interpretive execution of pci load/store instruction. If we use this function
   pci access does not get intercepted (no SIE exit) but is handled via 
microcode.
   To enable this we have to disable zpci device and enable it again with 
information
   from the SIE control block. Further in qemu problem is: vfio traps access to
   MSIX table so we have to find another way programming msix if we do not get
   intercepts for memory space access.

2) Adapter event forwarding (with alerting). This is a mechanism the adpater 
event (irq)
   is directly forwarded to the guest. To set this up we also need to manipulate
   the zpci device (in kernel) with information form the SIE block. Exploiting
   GISA is only one part of this mechanism.

Both might be possible with some more or less nice looking vfio extensions. As 
I said
before we have to dig more into. Also this can be further optimazation steps 
later
if we have a running vfio implementation on the platform. 
 
  
  For this reasons I decided to implement a kernel based approach similar
  to x86 device assignment. There is a new qemu device (s390-pci) 
  representing a
 
 I fail to see the rationale and I definitely don't want to see anything
 even remotely similar to the legacy x86 device assignment on s390 ;).
 
 Can't we just enhance VFIO?
 

Probably yes, but we need some vfio changes (kernel and qemu)

 Also, I think we'll get the cleanest model if we start off with an
 implementation that allows us to add emulated PCI devices to an s390x
 machine and only then follow on with physical ones.
 

I can already do this. With some more s390 intercepts a device can be detected 
and
guest is able to access config/memory space. Unfortunately s390 platform does 
not
support I/O bars so non of the emulated devices will work on the platform ...

 
 Alex
 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 




Re: [Qemu-devel] [RFC][patch 0/6] pci pass-through support for qemu/KVM on s390

2014-09-05 Thread Frank Blaschka
On Fri, Sep 05, 2014 at 10:35:59AM +0200, Alexander Graf wrote:
 
 
 On 05.09.14 09:46, Frank Blaschka wrote:
  On Thu, Sep 04, 2014 at 07:16:24AM -0600, Alex Williamson wrote:
  On Thu, 2014-09-04 at 12:52 +0200, frank.blasc...@de.ibm.com wrote:
  This set of patches implements pci pass-through support for qemu/KVM on 
  s390.
  PCI support on s390 is very different from other platforms.
  Major differences are:
 
  1) all PCI operations are driven by special s390 instructions
 
  Generating config cycles is always arch specific.
 
  2) all s390 PCI instructions are privileged
 
  While the operations to generate config cycles on x86 are not
  privileged, they must be arbitrated between accesses, so in a sense
  they're privileged.
 
  3) PCI config and memory spaces can not be mmap'ed
 
  VFIO has mapping flags that allow any region to specify mmap support.
 
  
  Hi Alex,
  
  thx for your reply.
  
  Let me elaborate a little bit ore on 1 - 3. Config and memory space can not
  be accessed via memory operations. You have to use special s390 
  instructions.
  This instructions can not be executed in user space. So there is no other
  way than executing this instructions in kernel. Yes vfio does support a
  slow path via ioctrl we could use, but this seems suboptimal from 
  performance
  point of view.
 
 Ah, I missed the memory spaces part ;). I agree that it's suboptimal
 to call into the kernel for every PCI access, but I still think that
 VFIO provides the correct abstraction layer for us to use. If nothing
 else, it would at least give us identical configuration to x86 and nice
 debugability en par with the other platforms.
 
   
  4) no classic interrupts (INTX, MSI). The pci hw understands the concept
 of requesting MSIX irqs but irqs are delivered as s390 adapter irqs.
 
  VFIO delivers interrupts as eventfds regardless of the underlying
  platform mechanism.
 
  
  yes that's right, but then we have to do platform specific stuff to present
  the irq to the guest. I do not say this is impossible but we have add s390
  specific code to vfio. 
 
 Not at all - interrupt delivery is completely transparent to VFIO.


interrupt yes, but MSIX no
 
  
  5) For DMA access there is always an IOMMU required.
 
  x86 requires the same.
 
   s390 pci implementation
 does not support a complete memory to iommu mapping, dma mappings are
 created on request.
 
  Sounds like POWER.
  
  Don't know the details from power, maybe it is similar but not the same.
  We might be able to extend vfio to have a new interface allowing
  us to do DMA mappings on request.
 
 We already have that.


Great, can you give me some pointers how to use? Thx!
 
  
 
  6) The OS does not get any informations about the physical layout
 of the PCI bus.
 
  If that means that every device is isolated (seems unlikely for
  multifunction devices) then that makes IOMMU group support really easy.
 
  
  OK
   
  7) To take advantage of system z specific virtualization features
 we need to access the SIE control block residing in the kernel KVM
 
  The KVM-VFIO device allows interaction between VFIO devices and KVM.
 
  8) To enable system z specific virtualization features we have to 
  manipulate
 the zpci device in kernel.
 
  VFIO supports different device backends, currently pci_dev and working
  towards platform devices.  zpci might just be an extension to standard
  pci.
 
  
  7 - 8 At least this is not as straightforward as the pure kernel approach, 
  but
  I have to dig into that in more detail if we could only agree on a vfio 
  solution.
 
 Please do so, yes :).
 
  
  For this reasons I decided to implement a kernel based approach similar
  to x86 device assignment. There is a new qemu device (s390-pci) 
  representing a
  pass through device on the host. Here is a sample qemu device 
  configuration:
 
  -device s390-pci,host=:00:00.0
 
  The device executes the KVM_ASSIGN_PCI_DEVICE ioctl to create a proxy 
  instance
  in the kernel KVM and connect this instance to the host pci device.
 
  kernel patches apply to linux-kvm
 
  s390: cio: chsc function to register GIB
  s390: pci: export pci functions for pass-through usage
  KVM: s390: Add GISA support
  KVM: s390: Add PCI pass-through support
 
  qemu patches apply to qemu-master
 
  s390: Add PCI bus support
  s390: Add PCI pass-through device support
 
  Feedback and discussion is highly welcome ...
 
  KVM-based device assignment needs to go away.  It's a horrible model for
  devices, it offers very little protection to the kernel, assumes every
  device is fully isolated and visible to the IOMMU, relies on smattering
  of sysfs files to operate, etc.  x86, POWER, and ARM are all moving to
  VFIO-based device assignment.  Why is s390 special enough to repeat all
  the mistakes that x86 did?  Thanks,
 
  
  Is this your personal opinion or was this a strategic decision of the
  QEMU/KVM community? Can anybody give us direction about

[Qemu-devel] [RFC][patch 3/6] KVM: s390: Add GISA support

2014-09-04 Thread frank . blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch adds GISA (Guest Interrupt State Area) support
to s390 kvm. GISA can be used for exitless interrupts. The
patch provides a set of functions for GISA related operations
like accessing GISA fields or registering ISCs for alert.
Exploiters of GISA will follow with additional patches.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 arch/s390/include/asm/kvm_host.h |   72 
 arch/s390/kvm/kvm-s390.c |  167 +++
 arch/s390/kvm/kvm-s390.h |   28 ++
 3 files changed, 265 insertions(+), 2 deletions(-)

--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -129,11 +129,12 @@ struct kvm_s390_sie_block {
__u8reserved60; /* 0x0060 */
__u8ecb;/* 0x0061 */
__u8ecb2;   /* 0x0062 */
-   __u8reserved63[1];  /* 0x0063 */
+   __u8ecb3;   /* 0x0063 */
__u32   scaol;  /* 0x0064 */
__u8reserved68[4];  /* 0x0068 */
__u32   todpr;  /* 0x006c */
-   __u8reserved70[32]; /* 0x0070 */
+   __u32   gd; /* 0x0070 */
+   __u8reserved74[28]; /* 0x0074 */
psw_t   gpsw;   /* 0x0090 */
__u64   gg14;   /* 0x00a0 */
__u64   gg15;   /* 0x00a8 */
@@ -300,6 +301,70 @@ struct kvm_s390_interrupt_info {
 #define ACTION_STORE_ON_STOP   (10)
 #define ACTION_STOP_ON_STOP(11)
 
+#define KVM_S390_GISA_FORMAT_0 0
+#define KVM_S390_GISA_FORMAT_1 1
+
+struct kvm_s390_gisa_f0 {
+   u32 next_alert;
+   u8 ipm;
+   u16 rsv0:14;
+   u16 g:1;
+   u16 c:1;
+   u8 iam;
+   u32 rsv1;
+   u32 count;
+} __packed;
+
+struct kvm_s390_gisa_f1 {
+   u32 next_alert;
+   u8 ipm;
+   u8 simm;
+   u8 nimm;
+   u8 iam;
+   u64 aisma;
+   u32 rsv0:6;
+   u32 g:1;
+   u32 c:1;
+   u32 rsv1:24;
+   u64 rsv2;
+   u32 count;
+} __packed;
+
+union kvm_s390_gisa {
+   struct kvm_s390_gisa_f0 f0;
+   struct kvm_s390_gisa_f1 f1;
+};
+
+struct kvm_s390_gait {
+   u32 gd;
+   u16  : 5;
+   u16 gisc : 3;
+   u16 rpu  : 8;
+   u16: 10;
+   u16 gaisbo :  6;
+   u64 gaisba;
+} __packed;
+
+struct kvm_s390_aifte {
+   u64 faisba;
+   u64 gaita;
+   u16 simm : 8;
+   u16  : 5;
+   u16 afi  : 3;
+   u16 reserved1;
+   u16 reserved2;
+   u16 faal;
+} __packed;
+
+struct kvm_s390_gib {
+   u32 alo;
+   u32 reserved1;
+   u32  : 5;
+   u32 nisc : 3;
+   u32  : 24;
+   u8 reserverd2[20];
+} __packed;
+
 struct kvm_s390_local_interrupt {
spinlock_t lock;
struct list_head list;
@@ -420,6 +485,9 @@ struct kvm_arch{
struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS];
wait_queue_head_t ipte_wq;
spinlock_t start_stop_lock;
+   union kvm_s390_gisa *gisa;
+   unsigned long iam;
+   atomic_t in_sie;
 };
 
 #define KVM_HVA_ERR_BAD(-1UL)
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -404,6 +404,16 @@ long kvm_arch_vm_ioctl(struct file *filp
return r;
 }
 
+static u8 kvm_s390_gisa_get_alert_mask(struct kvm *kvm)
+{
+   return (u8)ACCESS_ONCE(kvm-arch.iam);
+}
+
+static void kvm_s390_gisa_set_alert_mask(struct kvm *kvm, u8 iam)
+{
+   xchg(kvm-arch.iam, iam);
+}
+
 int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 {
int rc;
@@ -461,6 +471,14 @@ int kvm_arch_init_vm(struct kvm *kvm, un
kvm-arch.css_support = 0;
kvm-arch.use_irqchip = 0;
 
+   kvm-arch.gisa = (union kvm_s390_gisa *)get_zeroed_page(
+   GFP_KERNEL | GFP_DMA);
+   if (!kvm-arch.gisa)
+   goto out_nogmap;
+   kvm_s390_gisa_set_next_alert(kvm, (u32)(unsigned long)kvm-arch.gisa);
+   kvm_s390_gisa_set_alert_mask(kvm, 0);
+   atomic_set(kvm-arch.in_sie, 0);
+
spin_lock_init(kvm-arch.start_stop_lock);
 
return 0;
@@ -520,6 +538,7 @@ void kvm_arch_sync_events(struct kvm *kv
 
 void kvm_arch_destroy_vm(struct kvm *kvm)
 {
+   free_page((unsigned long)kvm-arch.gisa);
kvm_free_vcpus(kvm);
free_page((unsigned long)(kvm-arch.sca));
debug_unregister(kvm-arch.dbf);
@@ -656,6 +675,19 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu
return rc;
 }
 
+u32 kvm_s390_gisa_get_fmt(void)
+{
+   if (test_facility(70) || test_facility(72))
+   return KVM_S390_GISA_FORMAT_1;
+   else
+   return KVM_S390_GISA_FORMAT_0;
+}
+
+static u32 kvm_s390_build_gd(struct kvm *kvm)
+{
+   return (u32)(unsigned long)kvm-arch.gisa | kvm_s390_gisa_get_fmt();
+}
+
 struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm

[Qemu-devel] [RFC][patch 1/6] s390: cio: chsc function to register GIB

2014-09-04 Thread frank . blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch provides a new chsc function to register/unregister
a GIB (Guest Information Block).

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 arch/s390/include/asm/cio.h |1 
 drivers/s390/cio/chsc.c |   50 
 2 files changed, 51 insertions(+)

--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -311,5 +311,6 @@ extern int cio_get_iplinfo(struct cio_ip
 /* Function from drivers/s390/cio/chsc.c */
 int chsc_sstpc(void *page, unsigned int op, u16 ctrl);
 int chsc_sstpi(void *page, void *result, size_t size);
+int chsc_sgib(u32 gibo);
 
 #endif
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -1188,6 +1188,56 @@ out:
 EXPORT_SYMBOL_GPL(chsc_siosl);
 
 /**
+ * chsc_sgib() - register guest information block
+ * @gibo: guest information block
+ *
+ * gibo must be allocated in low memory
+ *
+ * Returns 0 on success.
+ */
+int chsc_sgib(u32 gibo)
+{
+   struct {
+   struct chsc_header request;
+   u16 operation_code;
+   u16 : 16;
+   u32 : 4;
+   u32 fmt : 4;
+   u32 : 24;
+   u32 : 32;
+   u32 : 32;
+   u32 gibo;
+   u64 : 64;
+   u32 : 16;
+   u32 aix : 8;
+   u32 : 8;
+   u32 reserved[1007];
+   struct chsc_header response;
+   } __packed *scssc;
+   unsigned long flags;
+   int rc;
+
+   spin_lock_irqsave(chsc_page_lock, flags);
+   memset(chsc_page, 0, PAGE_SIZE);
+   scssc = chsc_page;
+
+   scssc-request.length = 0x0fe0;
+   scssc-request.code = 0x0021;
+   scssc-operation_code = 1;
+   scssc-gibo = gibo;
+
+   rc = chsc(scssc);
+   if (rc)
+   rc = -EIO;
+   else
+   rc = chsc_error_from_response(scssc-response.code);
+
+   spin_unlock_irqrestore(chsc_page_lock, flags);
+   return rc;
+}
+EXPORT_SYMBOL_GPL(chsc_sgib);
+
+/**
  * chsc_scm_info() - store SCM information (SSI)
  * @scm_area: request and response block for SSI
  * @token: continuation token




[Qemu-devel] [RFC][patch 4/6] KVM: s390: Add PCI pass-through support

2014-09-04 Thread frank . blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implemets PCI pass-through kernel support for s390.
Design approach is very similar to the x86 device assignment.
User space executes the KVM_ASSIGN_PCI_DEVICE ioctl to create
a proxy instance in the kernel KVM and connect this instance to the
host pci device. s390 pci instructions are intercepted in kernel and
operations are passed directly to the assigned pci device.
To take advantage of all system z specific virtualization features
we need to access the SIE control block residing in KVM. Also we have to
enable z pci devices with special configuration information coming
form the SIE block as well.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 arch/s390/include/asm/kvm_host.h |1 
 arch/s390/kvm/Makefile   |2 
 arch/s390/kvm/intercept.c|1 
 arch/s390/kvm/kvm-s390.c |   33 
 arch/s390/kvm/kvm-s390.h |   17 
 arch/s390/kvm/pci.c  | 2130 +++
 arch/s390/kvm/priv.c |   21 
 7 files changed, 2202 insertions(+), 3 deletions(-)

--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -488,6 +488,7 @@ struct kvm_arch{
union kvm_s390_gisa *gisa;
unsigned long iam;
atomic_t in_sie;
+   struct list_head ppt_dev_list;
 };
 
 #define KVM_HVA_ERR_BAD(-1UL)
--- a/arch/s390/kvm/Makefile
+++ b/arch/s390/kvm/Makefile
@@ -12,6 +12,6 @@ common-objs = $(KVM)/kvm_main.o $(KVM)/e
 ccflags-y := -Ivirt/kvm -Iarch/s390/kvm
 
 kvm-objs := $(common-objs) kvm-s390.o intercept.o interrupt.o priv.o sigp.o
-kvm-objs += diag.o gaccess.o guestdbg.o
+kvm-objs += diag.o gaccess.o guestdbg.o pci.o
 
 obj-$(CONFIG_KVM) += kvm.o
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -34,6 +34,7 @@ static const intercept_handler_t instruc
[0xb6] = kvm_s390_handle_stctl,
[0xb7] = kvm_s390_handle_lctl,
[0xb9] = kvm_s390_handle_b9,
+   [0xe3] = kvm_s390_handle_e3,
[0xe5] = kvm_s390_handle_e5,
[0xeb] = kvm_s390_handle_eb,
 };
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -397,6 +397,24 @@ long kvm_arch_vm_ioctl(struct file *filp
r = kvm_s390_vm_has_attr(kvm, attr);
break;
}
+   case KVM_ASSIGN_PCI_DEVICE: {
+   struct kvm_assigned_pci_dev assigned_dev;
+
+   r = -EFAULT;
+   if (copy_from_user(assigned_dev, argp, sizeof(assigned_dev)))
+   break;
+   r = kvm_s390_ioctrl_assign_pci(kvm, assigned_dev);
+   break;
+   }
+   case KVM_DEASSIGN_PCI_DEVICE: {
+   struct kvm_assigned_pci_dev assigned_dev;
+
+   r = -EFAULT;
+   if (copy_from_user(assigned_dev, argp, sizeof(assigned_dev)))
+   break;
+   r = kvm_s390_ioctrl_deassign_pci(kvm, assigned_dev);
+   break;
+   }
default:
r = -ENOTTY;
}
@@ -478,6 +496,7 @@ int kvm_arch_init_vm(struct kvm *kvm, un
kvm_s390_gisa_set_next_alert(kvm, (u32)(unsigned long)kvm-arch.gisa);
kvm_s390_gisa_set_alert_mask(kvm, 0);
atomic_set(kvm-arch.in_sie, 0);
+   INIT_LIST_HEAD(kvm-arch.ppt_dev_list);
 
spin_lock_init(kvm-arch.start_stop_lock);
 
@@ -538,6 +557,7 @@ void kvm_arch_sync_events(struct kvm *kv
 
 void kvm_arch_destroy_vm(struct kvm *kvm)
 {
+   s390_pci_cleanup(kvm);
free_page((unsigned long)kvm-arch.gisa);
kvm_free_vcpus(kvm);
free_page((unsigned long)(kvm-arch.sca));
@@ -656,7 +676,10 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu
vcpu-arch.sie_block-ecb |= 0x10;
 
vcpu-arch.sie_block-ecb2  = 8;
-   vcpu-arch.sie_block-eca   = 0xD1002000U;
+   vcpu-arch.sie_block-eca   = 0xD1202000U;
+   vcpu-arch.sie_block-ecb2 |= 0x02;
+   vcpu-arch.sie_block-ecb3 = 0x20;
+
if (sclp_has_siif())
vcpu-arch.sie_block-eca |= 1;
vcpu-arch.sie_block-fac   = (int) (long) vfacilities;
@@ -1920,6 +1943,12 @@ static int __init kvm_s390_init(void)
if (ret)
return ret;
 
+   ret = s390_pci_init();
+   if (ret) {
+   kvm_exit();
+   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
@@ -1932,7 +1961,7 @@ static int __init kvm_s390_init(void)
}
memcpy(vfacilities, S390_lowcore.stfle_fac_list, 16);
vfacilities[0] = 0xff82fff3f4fc2000UL;
-   vfacilities[1] = 0x005cUL;
+   vfacilities[1] = 0x07dcUL;
return 0;
 }
 
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -167,6 +167,7 @@ int kvm_s390_mask_adapter(struct kvm *kv
 /* implemented in priv.c */
 int is_valid_psw(psw_t *psw);
 int

[Qemu-devel] [RFC][patch 0/6] pci pass-through support for qemu/KVM on s390

2014-09-04 Thread frank . blaschka
This set of patches implements pci pass-through support for qemu/KVM on s390.
PCI support on s390 is very different from other platforms.
Major differences are:

1) all PCI operations are driven by special s390 instructions
2) all s390 PCI instructions are privileged
3) PCI config and memory spaces can not be mmap'ed
4) no classic interrupts (INTX, MSI). The pci hw understands the concept
   of requesting MSIX irqs but irqs are delivered as s390 adapter irqs.
5) For DMA access there is always an IOMMU required. s390 pci implementation
   does not support a complete memory to iommu mapping, dma mappings are
   created on request.
6) The OS does not get any informations about the physical layout
   of the PCI bus.
7) To take advantage of system z specific virtualization features
   we need to access the SIE control block residing in the kernel KVM
8) To enable system z specific virtualization features we have to manipulate
   the zpci device in kernel.

For this reasons I decided to implement a kernel based approach similar
to x86 device assignment. There is a new qemu device (s390-pci) representing a
pass through device on the host. Here is a sample qemu device configuration:

-device s390-pci,host=:00:00.0

The device executes the KVM_ASSIGN_PCI_DEVICE ioctl to create a proxy instance
in the kernel KVM and connect this instance to the host pci device.

kernel patches apply to linux-kvm

s390: cio: chsc function to register GIB
s390: pci: export pci functions for pass-through usage
KVM: s390: Add GISA support
KVM: s390: Add PCI pass-through support

qemu patches apply to qemu-master

s390: Add PCI bus support
s390: Add PCI pass-through device support

Feedback and discussion is highly welcome ...
Thx!

Frank




[Qemu-devel] [RFC][patch 2/6] s390: pci: export pci functions for pass-through usage

2014-09-04 Thread frank . blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch exports a couple of zPCI functions. The new pci
pass-through driver for KVM will use this functions to enable the
device with virtualization information and update the device dma
translation table on the host. We add a new interface to purge
the translation table of a device. Also we moved some zPCI functions
to the pci_insn header file.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 arch/s390/include/asm/pci.h  |6 ++
 arch/s390/include/asm/pci_clp.h  |3 -
 arch/s390/include/asm/pci_insn.h |   92 
 arch/s390/pci/pci_clp.c  |4 +
 arch/s390/pci/pci_dma.c  |   24 -
 arch/s390/pci/pci_insn.c |   97 ---
 6 files changed, 126 insertions(+), 100 deletions(-)

--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -140,6 +140,7 @@ int zpci_register_ioat(struct zpci_dev *
 int zpci_unregister_ioat(struct zpci_dev *, u8);
 
 /* CLP */
+u8 clp_instr(void *data);
 int clp_scan_pci_devices(void);
 int clp_rescan_pci_devices(void);
 int clp_rescan_pci_devices_simple(void);
@@ -177,6 +178,11 @@ struct zpci_dev *get_zdev_by_fid(u32);
 /* DMA */
 int zpci_dma_init(void);
 void zpci_dma_exit(void);
+int dma_update_trans(struct zpci_dev *zdev, unsigned long pa,
+dma_addr_t dma_addr, size_t size, int flags);
+void dma_update_cpu_trans(struct zpci_dev *zdev, void *page_addr,
+ dma_addr_t dma_addr, int flags);
+void dma_purge_rto_entries(struct zpci_dev *zdev);
 
 /* FMB */
 int zpci_fmb_enable_device(struct zpci_dev *);
--- a/arch/s390/include/asm/pci_clp.h
+++ b/arch/s390/include/asm/pci_clp.h
@@ -148,7 +148,8 @@ struct clp_req_set_pci {
u16 reserved2;
u8 oc;  /* operation controls */
u8 ndas;/* number of dma spaces */
-   u64 reserved3;
+   u32 reserved3;
+   u32 gd; /* GISA Designation */
 } __packed;
 
 /* Set PCI function response */
--- a/arch/s390/include/asm/pci_insn.h
+++ b/arch/s390/include/asm/pci_insn.h
@@ -1,6 +1,8 @@
 #ifndef _ASM_S390_PCI_INSN_H
 #define _ASM_S390_PCI_INSN_H
 
+#include asm/processor.h
+
 /* Load/Store status codes */
 #define ZPCI_PCI_ST_FUNC_NOT_ENABLED   4
 #define ZPCI_PCI_ST_FUNC_IN_ERR8
@@ -83,4 +85,94 @@ int zpci_store(u64 data, u64 req, u64 of
 int zpci_store_block(const u64 *data, u64 req, u64 offset);
 void zpci_set_irq_ctrl(u16 ctl, char *unused, u8 isc);
 
+static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status)
+{
+   u8 cc;
+
+   asm volatile (
+  .insn   rxy,0xe3d0,%[req],%[fib]\n
+  ipm %[cc]\n
+  srl %[cc],28\n
+   : [cc] =d (cc), [req] +d (req), [fib] +Q (*fib)
+   : : cc);
+   *status = req  24  0xff;
+   return cc;
+}
+
+static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status)
+{
+   register u64 __addr asm(2) = addr;
+   register u64 __range asm(3) = range;
+   u8 cc;
+
+   asm volatile (
+  .insn   rre,0xb9d3,%[fn],%[addr]\n
+  ipm %[cc]\n
+  srl %[cc],28\n
+   : [cc] =d (cc), [fn] +d (fn)
+   : [addr] d (__addr), d (__range)
+   : cc);
+   *status = fn  24  0xff;
+   return cc;
+}
+
+static inline int __pcilg(u64 *data, u64 req, u64 offset, u8 *status)
+{
+   register u64 __req asm(2) = req;
+   register u64 __offset asm(3) = offset;
+   int cc = -ENXIO;
+   u64 __data;
+
+   asm volatile (
+  .insn   rre,0xb9d2,%[data],%[req]\n
+   0: ipm %[cc]\n
+  srl %[cc],28\n
+   1:\n
+   EX_TABLE(0b, 1b)
+   : [cc] +d (cc), [data] =d (__data), [req] +d (__req)
+   :  d (__offset)
+   : cc);
+   *status = __req  24  0xff;
+   if (!cc)
+   *data = __data;
+
+   return cc;
+}
+
+static inline int __pcistg(u64 data, u64 req, u64 offset, u8 *status)
+{
+   register u64 __req asm(2) = req;
+   register u64 __offset asm(3) = offset;
+   int cc = -ENXIO;
+
+   asm volatile (
+  .insn   rre,0xb9d0,%[data],%[req]\n
+   0: ipm %[cc]\n
+  srl %[cc],28\n
+   1:\n
+   EX_TABLE(0b, 1b)
+   : [cc] +d (cc), [req] +d (__req)
+   : d (__offset), [data] d (data)
+   : cc);
+   *status = __req  24  0xff;
+   return cc;
+}
+
+static inline int __pcistb(const u64 *data, u64 req, u64 offset, u8 *status)
+{
+   int cc = -ENXIO;
+
+   asm volatile (
+  .insn   rsy,0xebd0,%[req],%[offset],%[data]\n

[Qemu-devel] [RFC][patch 6/6] s390: Add PCI pass-through device support

2014-09-04 Thread frank . blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch adds a new device class handling s390 pci pass-through device
assignment. The approach is very similar to the x86 device assignment.
The device executes the KVM_ASSIGN_PCI_DEVICE ioctl to create a proxy instance
in the kernel KVM and connect this instance to the host pci device.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 hw/s390x/Makefile.objs  |2 
 hw/s390x/s390-pci-bus.c |   14 +-
 hw/s390x/s390_pci.c |  321 
 hw/s390x/s390_pci.h |   31 
 4 files changed, 365 insertions(+), 3 deletions(-)

--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -8,4 +8,4 @@ obj-y += ipl.o
 obj-y += css.o
 obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
-obj-$(CONFIG_KVM) += s390-pci-bus.o
+obj-$(CONFIG_KVM) += s390-pci-bus.o s390_pci.o
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -16,6 +16,7 @@
 #include hw/s390x/sclp.h
 #include qemu/error-report.h
 #include s390-pci-bus.h
+#include s390_pci.h
 
 /* #define DEBUG_S390PCI_BUS */
 #ifdef DEBUG_S390PCI_BUS
@@ -219,8 +220,17 @@ static void s390_pcihost_hot_plug(Hotplu
 pbdev-pdev = pci_dev;
 pbdev-configured = true;
 
-pbdev-fh = s390_pci_get_pfh(pci_dev);
-pbdev-is_virt = 1;
+if (!strcmp(pci_dev-name, s390-pci)) {
+S390PCIDevice *sdev = DO_UPCAST(S390PCIDevice, pdev, pci_dev);
+pbdev-fh = s390_pci_get_fh(sdev-host);
+if (!pbdev-fh) {
+g_free(pbdev);
+return;
+}
+} else {
+pbdev-fh = s390_pci_get_pfh(pci_dev);
+pbdev-is_virt = 1;
+}
 
 QTAILQ_INSERT_TAIL(device_list, pbdev, next);
 if (dev-hotplugged) {
--- /dev/null
+++ b/hw/s390x/s390_pci.c
@@ -0,0 +1,321 @@
+/*
+ * s390 PCI pass-through device assignment
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include hw/pci/pci.h
+#include hw/pci/pci_host.h
+#include hw/pci/pci_bus.h
+#include net/net.h
+#include hw/s390x/css.h
+#include hw/s390x/sclp.h
+#include exec/exec-all.h
+#include sysemu/sysemu.h
+#include exec/address-spaces.h
+#include qemu/error-report.h
+#include qapi/qmp/qerror.h
+
+#include s390_pci.h
+#include s390-pci-bus.h
+
+/* #define DEBUG_S390PCI */
+#ifdef DEBUG_S390PCI
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, s390pci:  fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+#define ASSIGN_FLAG_HOSTIRQ 0x1
+
+uint32_t s390_pci_get_fh(PCIHostDeviceAddress host)
+{
+char fh_path[128];
+struct stat st;
+FILE *fd;
+uint32_t fh;
+
+snprintf(fh_path, sizeof(fh_path),
+/sys/bus/pci/devices/%04x:%02x:%02x.%x/function_handle,
+host.domain, host.bus, host.slot, host.function);
+
+if (stat(fh_path, st)) {
+error_report(get function handle faild: no host device specified);
+return -1;
+}
+
+fd = fopen(fh_path, r);
+if (fd == NULL) {
+error_report(%s: %s: %m, __func__, fh_path);
+return 0;
+}
+if (fscanf(fd, %x, fh) != 1) {
+fclose(fd);
+return 0;
+}
+fclose(fd);
+return fh;
+}
+
+uint32_t s390_pci_get_fid(PCIHostDeviceAddress host)
+{
+char fid_path[128];
+struct stat st;
+FILE *fd;
+uint32_t fid;
+
+snprintf(fid_path, sizeof(fid_path),
+/sys/bus/pci/devices/%04x:%02x:%02x.%x/function_id,
+host.domain, host.bus, host.slot, host.function);
+
+if (stat(fid_path, st)) {
+error_report(get function id faild: no host device specified);
+return -1;
+}
+
+fd = fopen(fid_path, r);
+if (fd == NULL) {
+error_report(%s: %s: %m, __func__, fid_path);
+return -1;
+}
+if (fscanf(fd, %x, fid) != 1) {
+fclose(fd);
+return -1;
+}
+fclose(fd);
+return fid;
+}
+
+static int get_real_id(const char *devpath, const char *idname, uint16_t *val)
+{
+FILE *f;
+char name[128];
+long id;
+
+snprintf(name, sizeof(name), %s%s, devpath, idname);
+f = fopen(name, r);
+if (f == NULL) {
+error_report(%s: %s: %m, __func__, name);
+return -1;
+}
+if (fscanf(f, %li\n, id) == 1) {
+*val = id;
+} else {
+fclose(f);
+return -1;
+}
+fclose(f);
+
+return 0;
+}
+
+static int get_real_vendor_id(const char *devpath, uint16_t *val)
+{
+return get_real_id(devpath, vendor, val);
+}
+
+static int get_real_device_id(const char *devpath, uint16_t *val)
+{
+return get_real_id(devpath, device, val);
+}
+
+static void assign_failed_examine(S390PCIDevice *dev)
+{
+char name[PATH_MAX], dir[PATH_MAX], driver

[Qemu-devel] [RFC][patch 5/6] s390: Add PCI bus support

2014-09-04 Thread frank . blaschka
From: Frank Blaschka frank.blasc...@de.ibm.com

This patch implements a pci bus for s390x together with some infrastructure
to generate and handle hotplug events. It also provides device 
configuration/unconfiguration via sclp instruction interception.

Signed-off-by: Frank Blaschka frank.blasc...@de.ibm.com
---
 default-configs/s390x-softmmu.mak |1 
 hw/s390x/Makefile.objs|1 
 hw/s390x/css.c|5 
 hw/s390x/css.h|1 
 hw/s390x/s390-pci-bus.c   |  287 ++
 hw/s390x/s390-pci-bus.h   |  139 ++
 hw/s390x/s390-virtio-ccw.c|2 
 hw/s390x/sclp.c   |   10 +
 include/hw/s390x/sclp.h   |8 +
 target-s390x/Makefile.objs|2 
 target-s390x/ioinst.c |   52 ++
 target-s390x/ioinst.h |1 
 target-s390x/kvm.c|5 
 target-s390x/pci_ic.c |  230 ++
 target-s390x/pci_ic.h |  214 
 15 files changed, 956 insertions(+), 2 deletions(-)

--- a/default-configs/s390x-softmmu.mak
+++ b/default-configs/s390x-softmmu.mak
@@ -1,4 +1,5 @@
 CONFIG_VIRTIO=y
+CONFIG_PCI=y
 CONFIG_SCLPCONSOLE=y
 CONFIG_S390_FLIC=y
 CONFIG_S390_FLIC_KVM=$(CONFIG_KVM)
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -8,3 +8,4 @@ obj-y += ipl.o
 obj-y += css.o
 obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
+obj-$(CONFIG_KVM) += s390-pci-bus.o
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1281,6 +1281,11 @@ void css_generate_chp_crws(uint8_t cssid
 /* TODO */
 }
 
+void css_generate_css_crws(uint8_t cssid)
+{
+css_queue_crw(CRW_RSC_CSS, 0, 0, 0);
+}
+
 int css_enable_mcsse(void)
 {
 trace_css_enable_facility(mcsse);
--- a/hw/s390x/css.h
+++ b/hw/s390x/css.h
@@ -99,6 +99,7 @@ void css_queue_crw(uint8_t rsc, uint8_t
 void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
int hotplugged, int add);
 void css_generate_chp_crws(uint8_t cssid, uint8_t chpid);
+void css_generate_css_crws(uint8_t cssid);
 void css_adapter_interrupt(uint8_t isc);
 
 #define CSS_IO_ADAPTER_VIRTIO 1
--- /dev/null
+++ b/hw/s390x/s390-pci-bus.c
@@ -0,0 +1,287 @@
+/*
+ * s390 PCI BUS
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Frank Blaschka frank.blasc...@de.ibm.com
+ *Hong Bo Li lih...@cn.ibm.com
+ *Yi Min Zhao zyi...@cn.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include hw/pci/pci.h
+#include hw/s390x/css.h
+#include hw/s390x/sclp.h
+#include qemu/error-report.h
+#include s390-pci-bus.h
+
+/* #define DEBUG_S390PCI_BUS */
+#ifdef DEBUG_S390PCI_BUS
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, S390pci-bus:  fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+static QTAILQ_HEAD(, SeiContainer) pending_sei =
+QTAILQ_HEAD_INITIALIZER(pending_sei);
+static QTAILQ_HEAD(, S390PCIBusDevice) device_list =
+QTAILQ_HEAD_INITIALIZER(device_list);
+
+int chsc_sei_nt2_get_event(void *res)
+{
+ChscSeiNt2Res *nt2_res = (ChscSeiNt2Res *)res;
+PciCcdfAvail *accdf;
+PciCcdfErr *eccdf;
+int rc = 1;
+SeiContainer *sei_cont;
+
+sei_cont = QTAILQ_FIRST(pending_sei);
+if (sei_cont) {
+QTAILQ_REMOVE(pending_sei, sei_cont, link);
+nt2_res-nt = 2;
+nt2_res-cc = sei_cont-cc;
+switch (sei_cont-cc) {
+case 1: /* error event */
+eccdf = (PciCcdfErr *)nt2_res-ccdf;
+eccdf-fid = cpu_to_be32(sei_cont-fid);
+eccdf-fh = cpu_to_be32(sei_cont-fh);
+break;
+case 2: /* availability event */
+accdf = (PciCcdfAvail *)nt2_res-ccdf;
+accdf-fid = cpu_to_be32(sei_cont-fid);
+accdf-fh = cpu_to_be32(sei_cont-fh);
+accdf-pec = cpu_to_be16(sei_cont-pec);
+break;
+default:
+abort();
+}
+g_free(sei_cont);
+rc = 0;
+}
+
+return rc;
+}
+
+int chsc_sei_nt2_have_event(void)
+{
+return !QTAILQ_EMPTY(pending_sei);
+}
+
+static S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid)
+{
+S390PCIBusDevice *pbdev;
+
+QTAILQ_FOREACH(pbdev, device_list, next) {
+if (pbdev-fid == fid) {
+return pbdev;
+}
+}
+return NULL;
+}
+
+void s390_pci_sclp_configure(int configure, SCCB *sccb)
+{
+PciCfgSccb *psccb = (PciCfgSccb *)sccb;
+S390PCIBusDevice *pbdev = 
s390_pci_find_dev_by_fid(be32_to_cpu(psccb-aid));
+uint16_t rc;
+
+if (pbdev) {
+if ((configure == 1  pbdev-configured == true) ||
+(configure == 0  pbdev-configured == false)) {
+rc = SCLP_RC_NO_ACTION_REQUIRED;
+} else {
+pbdev-configured