Commit 48070c73 authored by Christian Borntraeger's avatar Christian Borntraeger Committed by Heiko Carstens

s390/pci: do not require AIS facility

As of today QEMU does not provide the AIS facility to its guest.  This
prevents Linux guests from using PCI devices as the ais facility is
checked during init. As this is just a performance optimization, we can
move the ais check into the code where we need it (calling the SIC
instruction). This is used at initialization and on interrupt. Both
places do not require any serialization, so we can simply skip the
instruction.

Since we will now get all interrupts, we can also avoid the 2nd scan.
As we can have multiple interrupts in parallel we might trigger spurious
irqs more often for the non-AIS case but the core code can handle that.
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: default avatarPierre Morel <pmorel@linux.vnet.ibm.com>
Reviewed-by: default avatarHalil Pasic <pasic@linux.vnet.ibm.com>
Acked-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
parent 30e8eb86
...@@ -81,6 +81,6 @@ int zpci_refresh_trans(u64 fn, u64 addr, u64 range); ...@@ -81,6 +81,6 @@ int zpci_refresh_trans(u64 fn, u64 addr, u64 range);
int zpci_load(u64 *data, u64 req, u64 offset); int zpci_load(u64 *data, u64 req, u64 offset);
int zpci_store(u64 data, u64 req, u64 offset); int zpci_store(u64 data, u64 req, u64 offset);
int zpci_store_block(const u64 *data, u64 req, u64 offset); int zpci_store_block(const u64 *data, u64 req, u64 offset);
void zpci_set_irq_ctrl(u16 ctl, char *unused, u8 isc); int zpci_set_irq_ctrl(u16 ctl, char *unused, u8 isc);
#endif #endif
...@@ -368,7 +368,8 @@ static void zpci_irq_handler(struct airq_struct *airq) ...@@ -368,7 +368,8 @@ static void zpci_irq_handler(struct airq_struct *airq)
/* End of second scan with interrupts on. */ /* End of second scan with interrupts on. */
break; break;
/* First scan complete, reenable interrupts. */ /* First scan complete, reenable interrupts. */
zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); if (zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC))
break;
si = 0; si = 0;
continue; continue;
} }
...@@ -956,7 +957,7 @@ static int __init pci_base_init(void) ...@@ -956,7 +957,7 @@ static int __init pci_base_init(void)
if (!s390_pci_probe) if (!s390_pci_probe)
return 0; return 0;
if (!test_facility(69) || !test_facility(71) || !test_facility(72)) if (!test_facility(69) || !test_facility(71))
return 0; return 0;
rc = zpci_debug_init(); rc = zpci_debug_init();
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/export.h> #include <linux/export.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <asm/facility.h>
#include <asm/pci_insn.h> #include <asm/pci_insn.h>
#include <asm/pci_debug.h> #include <asm/pci_debug.h>
#include <asm/processor.h> #include <asm/processor.h>
...@@ -91,11 +92,14 @@ int zpci_refresh_trans(u64 fn, u64 addr, u64 range) ...@@ -91,11 +92,14 @@ int zpci_refresh_trans(u64 fn, u64 addr, u64 range)
} }
/* Set Interruption Controls */ /* Set Interruption Controls */
void zpci_set_irq_ctrl(u16 ctl, char *unused, u8 isc) int zpci_set_irq_ctrl(u16 ctl, char *unused, u8 isc)
{ {
if (!test_facility(72))
return -EIO;
asm volatile ( asm volatile (
" .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n" " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n"
: : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused)); : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused));
return 0;
} }
/* PCI Load */ /* PCI Load */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment