Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 's390-5.11-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 fixes from Vasily Gorbik:

- Fix max number of VCPUs reported via ultravisor information sysfs
interface.

- Fix memory leaks during vfio-ap resources clean up on KVM pointer
invalidation notification.

- Fix potential specification exception by avoiding unnecessary
interrupts disable after queue reset in vfio-ap.

* tag 's390-5.11-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390: uv: Fix sysfs max number of VCPUs reporting
s390/vfio-ap: No need to disable IRQ after queue reset
s390/vfio-ap: clean up vfio_ap resources when KVM pointer invalidated

+101 -74
+1 -1
arch/s390/boot/uv.c
··· 35 35 uv_info.guest_cpu_stor_len = uvcb.cpu_stor_len; 36 36 uv_info.max_sec_stor_addr = ALIGN(uvcb.max_guest_stor_addr, PAGE_SIZE); 37 37 uv_info.max_num_sec_conf = uvcb.max_num_sec_conf; 38 - uv_info.max_guest_cpus = uvcb.max_guest_cpus; 38 + uv_info.max_guest_cpu_id = uvcb.max_guest_cpu_id; 39 39 } 40 40 41 41 #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
+2 -2
arch/s390/include/asm/uv.h
··· 96 96 u32 max_num_sec_conf; 97 97 u64 max_guest_stor_addr; 98 98 u8 reserved88[158 - 136]; 99 - u16 max_guest_cpus; 99 + u16 max_guest_cpu_id; 100 100 u8 reserveda0[200 - 160]; 101 101 } __packed __aligned(8); 102 102 ··· 273 273 unsigned long guest_cpu_stor_len; 274 274 unsigned long max_sec_stor_addr; 275 275 unsigned int max_num_sec_conf; 276 - unsigned short max_guest_cpus; 276 + unsigned short max_guest_cpu_id; 277 277 }; 278 278 279 279 extern struct uv_info uv_info;
+1 -1
arch/s390/kernel/uv.c
··· 368 368 struct kobj_attribute *attr, char *page) 369 369 { 370 370 return scnprintf(page, PAGE_SIZE, "%d\n", 371 - uv_info.max_guest_cpus); 371 + uv_info.max_guest_cpu_id + 1); 372 372 } 373 373 374 374 static struct kobj_attribute uv_query_max_guest_cpus_attr =
+1 -5
drivers/s390/crypto/vfio_ap_drv.c
··· 71 71 static void vfio_ap_queue_dev_remove(struct ap_device *apdev) 72 72 { 73 73 struct vfio_ap_queue *q; 74 - int apid, apqi; 75 74 76 75 mutex_lock(&matrix_dev->lock); 77 76 q = dev_get_drvdata(&apdev->device); 77 + vfio_ap_mdev_reset_queue(q, 1); 78 78 dev_set_drvdata(&apdev->device, NULL); 79 - apid = AP_QID_CARD(q->apqn); 80 - apqi = AP_QID_QUEUE(q->apqn); 81 - vfio_ap_mdev_reset_queue(apid, apqi, 1); 82 - vfio_ap_irq_disable(q); 83 79 kfree(q); 84 80 mutex_unlock(&matrix_dev->lock); 85 81 }
+90 -59
drivers/s390/crypto/vfio_ap_ops.c
··· 25 25 #define VFIO_AP_MDEV_NAME_HWVIRT "VFIO AP Passthrough Device" 26 26 27 27 static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev); 28 + static struct vfio_ap_queue *vfio_ap_find_queue(int apqn); 28 29 29 30 static int match_apqn(struct device *dev, const void *data) 30 31 { ··· 50 49 int apqn) 51 50 { 52 51 struct vfio_ap_queue *q; 53 - struct device *dev; 54 52 55 53 if (!test_bit_inv(AP_QID_CARD(apqn), matrix_mdev->matrix.apm)) 56 54 return NULL; 57 55 if (!test_bit_inv(AP_QID_QUEUE(apqn), matrix_mdev->matrix.aqm)) 58 56 return NULL; 59 57 60 - dev = driver_find_device(&matrix_dev->vfio_ap_drv->driver, NULL, 61 - &apqn, match_apqn); 62 - if (!dev) 63 - return NULL; 64 - q = dev_get_drvdata(dev); 65 - q->matrix_mdev = matrix_mdev; 66 - put_device(dev); 58 + q = vfio_ap_find_queue(apqn); 59 + if (q) 60 + q->matrix_mdev = matrix_mdev; 67 61 68 62 return q; 69 63 } ··· 115 119 */ 116 120 static void vfio_ap_free_aqic_resources(struct vfio_ap_queue *q) 117 121 { 118 - if (q->saved_isc != VFIO_AP_ISC_INVALID && q->matrix_mdev) 122 + if (!q) 123 + return; 124 + if (q->saved_isc != VFIO_AP_ISC_INVALID && 125 + !WARN_ON(!(q->matrix_mdev && q->matrix_mdev->kvm))) { 119 126 kvm_s390_gisc_unregister(q->matrix_mdev->kvm, q->saved_isc); 120 - if (q->saved_pfn && q->matrix_mdev) 127 + q->saved_isc = VFIO_AP_ISC_INVALID; 128 + } 129 + if (q->saved_pfn && !WARN_ON(!q->matrix_mdev)) { 121 130 vfio_unpin_pages(mdev_dev(q->matrix_mdev->mdev), 122 131 &q->saved_pfn, 1); 123 - q->saved_pfn = 0; 124 - q->saved_isc = VFIO_AP_ISC_INVALID; 132 + q->saved_pfn = 0; 133 + } 125 134 } 126 135 127 136 /** ··· 145 144 * Returns if ap_aqic function failed with invalid, deconfigured or 146 145 * checkstopped AP. 147 146 */ 148 - struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q) 147 + static struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q) 149 148 { 150 149 struct ap_qirq_ctrl aqic_gisa = {}; 151 150 struct ap_queue_status status; ··· 1038 1037 { 1039 1038 struct ap_matrix_mdev *m; 1040 1039 1041 - mutex_lock(&matrix_dev->lock); 1042 - 1043 1040 list_for_each_entry(m, &matrix_dev->mdev_list, node) { 1044 - if ((m != matrix_mdev) && (m->kvm == kvm)) { 1045 - mutex_unlock(&matrix_dev->lock); 1041 + if ((m != matrix_mdev) && (m->kvm == kvm)) 1046 1042 return -EPERM; 1047 - } 1048 1043 } 1049 1044 1050 1045 matrix_mdev->kvm = kvm; 1051 1046 kvm_get_kvm(kvm); 1052 1047 kvm->arch.crypto.pqap_hook = &matrix_mdev->pqap_hook; 1053 - mutex_unlock(&matrix_dev->lock); 1054 1048 1055 1049 return 0; 1056 1050 } ··· 1079 1083 return NOTIFY_DONE; 1080 1084 } 1081 1085 1086 + static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev) 1087 + { 1088 + kvm_arch_crypto_clear_masks(matrix_mdev->kvm); 1089 + matrix_mdev->kvm->arch.crypto.pqap_hook = NULL; 1090 + vfio_ap_mdev_reset_queues(matrix_mdev->mdev); 1091 + kvm_put_kvm(matrix_mdev->kvm); 1092 + matrix_mdev->kvm = NULL; 1093 + } 1094 + 1082 1095 static int vfio_ap_mdev_group_notifier(struct notifier_block *nb, 1083 1096 unsigned long action, void *data) 1084 1097 { 1085 - int ret; 1098 + int ret, notify_rc = NOTIFY_OK; 1086 1099 struct ap_matrix_mdev *matrix_mdev; 1087 1100 1088 1101 if (action != VFIO_GROUP_NOTIFY_SET_KVM) 1089 1102 return NOTIFY_OK; 1090 1103 1091 1104 matrix_mdev = container_of(nb, struct ap_matrix_mdev, group_notifier); 1105 + mutex_lock(&matrix_dev->lock); 1092 1106 1093 1107 if (!data) { 1094 - matrix_mdev->kvm = NULL; 1095 - return NOTIFY_OK; 1108 + if (matrix_mdev->kvm) 1109 + vfio_ap_mdev_unset_kvm(matrix_mdev); 1110 + goto notify_done; 1096 1111 } 1097 1112 1098 1113 ret = vfio_ap_mdev_set_kvm(matrix_mdev, data); 1099 - if (ret) 1100 - return NOTIFY_DONE; 1114 + if (ret) { 1115 + notify_rc = NOTIFY_DONE; 1116 + goto notify_done; 1117 + } 1101 1118 1102 1119 /* If there is no CRYCB pointer, then we can't copy the masks */ 1103 - if (!matrix_mdev->kvm->arch.crypto.crycbd) 1104 - return NOTIFY_DONE; 1120 + if (!matrix_mdev->kvm->arch.crypto.crycbd) { 1121 + notify_rc = NOTIFY_DONE; 1122 + goto notify_done; 1123 + } 1105 1124 1106 1125 kvm_arch_crypto_set_masks(matrix_mdev->kvm, matrix_mdev->matrix.apm, 1107 1126 matrix_mdev->matrix.aqm, 1108 1127 matrix_mdev->matrix.adm); 1109 1128 1110 - return NOTIFY_OK; 1129 + notify_done: 1130 + mutex_unlock(&matrix_dev->lock); 1131 + return notify_rc; 1111 1132 } 1112 1133 1113 - static void vfio_ap_irq_disable_apqn(int apqn) 1134 + static struct vfio_ap_queue *vfio_ap_find_queue(int apqn) 1114 1135 { 1115 1136 struct device *dev; 1116 - struct vfio_ap_queue *q; 1137 + struct vfio_ap_queue *q = NULL; 1117 1138 1118 1139 dev = driver_find_device(&matrix_dev->vfio_ap_drv->driver, NULL, 1119 1140 &apqn, match_apqn); 1120 1141 if (dev) { 1121 1142 q = dev_get_drvdata(dev); 1122 - vfio_ap_irq_disable(q); 1123 1143 put_device(dev); 1124 1144 } 1145 + 1146 + return q; 1125 1147 } 1126 1148 1127 - int vfio_ap_mdev_reset_queue(unsigned int apid, unsigned int apqi, 1149 + int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q, 1128 1150 unsigned int retry) 1129 1151 { 1130 1152 struct ap_queue_status status; 1153 + int ret; 1131 1154 int retry2 = 2; 1132 - int apqn = AP_MKQID(apid, apqi); 1133 1155 1134 - do { 1135 - status = ap_zapq(apqn); 1136 - switch (status.response_code) { 1137 - case AP_RESPONSE_NORMAL: 1138 - while (!status.queue_empty && retry2--) { 1139 - msleep(20); 1140 - status = ap_tapq(apqn, NULL); 1141 - } 1142 - WARN_ON_ONCE(retry2 <= 0); 1143 - return 0; 1144 - case AP_RESPONSE_RESET_IN_PROGRESS: 1145 - case AP_RESPONSE_BUSY: 1156 + if (!q) 1157 + return 0; 1158 + 1159 + retry_zapq: 1160 + status = ap_zapq(q->apqn); 1161 + switch (status.response_code) { 1162 + case AP_RESPONSE_NORMAL: 1163 + ret = 0; 1164 + break; 1165 + case AP_RESPONSE_RESET_IN_PROGRESS: 1166 + if (retry--) { 1146 1167 msleep(20); 1147 - break; 1148 - default: 1149 - /* things are really broken, give up */ 1150 - return -EIO; 1168 + goto retry_zapq; 1151 1169 } 1152 - } while (retry--); 1170 + ret = -EBUSY; 1171 + break; 1172 + case AP_RESPONSE_Q_NOT_AVAIL: 1173 + case AP_RESPONSE_DECONFIGURED: 1174 + case AP_RESPONSE_CHECKSTOPPED: 1175 + WARN_ON_ONCE(status.irq_enabled); 1176 + ret = -EBUSY; 1177 + goto free_resources; 1178 + default: 1179 + /* things are really broken, give up */ 1180 + WARN(true, "PQAP/ZAPQ completed with invalid rc (%x)\n", 1181 + status.response_code); 1182 + return -EIO; 1183 + } 1153 1184 1154 - return -EBUSY; 1185 + /* wait for the reset to take effect */ 1186 + while (retry2--) { 1187 + if (status.queue_empty && !status.irq_enabled) 1188 + break; 1189 + msleep(20); 1190 + status = ap_tapq(q->apqn, NULL); 1191 + } 1192 + WARN_ON_ONCE(retry2 <= 0); 1193 + 1194 + free_resources: 1195 + vfio_ap_free_aqic_resources(q); 1196 + 1197 + return ret; 1155 1198 } 1156 1199 1157 1200 static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev) ··· 1198 1163 int ret; 1199 1164 int rc = 0; 1200 1165 unsigned long apid, apqi; 1166 + struct vfio_ap_queue *q; 1201 1167 struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); 1202 1168 1203 1169 for_each_set_bit_inv(apid, matrix_mdev->matrix.apm, 1204 1170 matrix_mdev->matrix.apm_max + 1) { 1205 1171 for_each_set_bit_inv(apqi, matrix_mdev->matrix.aqm, 1206 1172 matrix_mdev->matrix.aqm_max + 1) { 1207 - ret = vfio_ap_mdev_reset_queue(apid, apqi, 1); 1173 + q = vfio_ap_find_queue(AP_MKQID(apid, apqi)); 1174 + ret = vfio_ap_mdev_reset_queue(q, 1); 1208 1175 /* 1209 1176 * Regardless whether a queue turns out to be busy, or 1210 1177 * is not operational, we need to continue resetting ··· 1214 1177 */ 1215 1178 if (ret) 1216 1179 rc = ret; 1217 - vfio_ap_irq_disable_apqn(AP_MKQID(apid, apqi)); 1218 1180 } 1219 1181 } 1220 1182 ··· 1258 1222 struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); 1259 1223 1260 1224 mutex_lock(&matrix_dev->lock); 1261 - if (matrix_mdev->kvm) { 1262 - kvm_arch_crypto_clear_masks(matrix_mdev->kvm); 1263 - matrix_mdev->kvm->arch.crypto.pqap_hook = NULL; 1264 - vfio_ap_mdev_reset_queues(mdev); 1265 - kvm_put_kvm(matrix_mdev->kvm); 1266 - matrix_mdev->kvm = NULL; 1267 - } 1225 + if (matrix_mdev->kvm) 1226 + vfio_ap_mdev_unset_kvm(matrix_mdev); 1268 1227 mutex_unlock(&matrix_dev->lock); 1269 1228 1270 1229 vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
+6 -6
drivers/s390/crypto/vfio_ap_private.h
··· 88 88 struct mdev_device *mdev; 89 89 }; 90 90 91 - extern int vfio_ap_mdev_register(void); 92 - extern void vfio_ap_mdev_unregister(void); 93 - int vfio_ap_mdev_reset_queue(unsigned int apid, unsigned int apqi, 94 - unsigned int retry); 95 - 96 91 struct vfio_ap_queue { 97 92 struct ap_matrix_mdev *matrix_mdev; 98 93 unsigned long saved_pfn; ··· 95 100 #define VFIO_AP_ISC_INVALID 0xff 96 101 unsigned char saved_isc; 97 102 }; 98 - struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q); 103 + 104 + int vfio_ap_mdev_register(void); 105 + void vfio_ap_mdev_unregister(void); 106 + int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q, 107 + unsigned int retry); 108 + 99 109 #endif /* _VFIO_AP_PRIVATE_H_ */