1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * s390 kvm PCI passthrough support 4 * 5 * Copyright IBM Corp. 2022 6 * 7 * Author(s): Matthew Rosato <mjrosato@linux.ibm.com> 8 */ 9 10 #ifndef __KVM_S390_PCI_H 11 #define __KVM_S390_PCI_H 12 13 #include <linux/kvm.h> 14 #include <linux/kvm_host.h> 15 #include <linux/mutex.h> 16 #include <linux/pci.h> 17 #include <asm/airq.h> 18 #include <asm/cpu.h> 19 20 struct kvm_zdev { 21 struct zpci_dev *zdev; 22 struct kvm *kvm; 23 struct zpci_fib fib; 24 struct list_head entry; 25 }; 26 27 struct zpci_gaite { 28 u32 gisa; 29 u8 gisc; 30 u8 count; 31 u8 reserved; 32 u8 aisbo; 33 u64 aisb; 34 }; 35 36 struct zpci_aift { 37 struct zpci_gaite *gait; 38 struct airq_iv *sbv; 39 struct kvm_zdev **kzdev; 40 spinlock_t gait_lock; /* Protects the gait, used during AEN forward */ 41 struct mutex aift_lock; /* Protects the other structures in aift */ 42 }; 43 44 extern struct zpci_aift *aift; 45 46 static inline struct kvm *kvm_s390_pci_si_to_kvm(struct zpci_aift *aift, 47 unsigned long si) 48 { 49 if (!IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM) || aift->kzdev == 0 || 50 aift->kzdev[si] == 0) 51 return 0; 52 return aift->kzdev[si]->kvm; 53 }; 54 55 int kvm_s390_pci_aen_init(u8 nisc); 56 void kvm_s390_pci_aen_exit(void); 57 58 void kvm_s390_pci_init_list(struct kvm *kvm); 59 void kvm_s390_pci_clear_list(struct kvm *kvm); 60 61 int kvm_s390_pci_zpci_op(struct kvm *kvm, struct kvm_s390_zpci_op *args); 62 63 int kvm_s390_pci_init(void); 64 void kvm_s390_pci_exit(void); 65 66 static inline bool kvm_s390_pci_interp_allowed(void) 67 { 68 struct cpuid cpu_id; 69 70 get_cpu_id(&cpu_id); 71 switch (cpu_id.machine) { 72 case 0x2817: 73 case 0x2818: 74 case 0x2827: 75 case 0x2828: 76 case 0x2964: 77 case 0x2965: 78 /* No SHM on certain machines */ 79 return false; 80 default: 81 return (IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM) && 82 sclp.has_zpci_lsi && sclp.has_aeni && sclp.has_aisi && 83 sclp.has_aisii); 84 } 85 } 86 87 #endif /* __KVM_S390_PCI_H */ 88