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.

virtio/s390: make airq summary indicators DMA

The hypervisor needs to interact with the summary indicators, so these
need to be DMA memory as well (at least for protected virtualization
guests).

Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Michael Mueller <mimu@linux.ibm.com>
Tested-by: Michael Mueller <mimu@linux.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>

authored by

Halil Pasic and committed by
Heiko Carstens
39c7dcb1 48720ba5

+24 -8
+24 -8
drivers/s390/virtio/virtio_ccw.c
··· 140 140 141 141 struct airq_info { 142 142 rwlock_t lock; 143 - u8 summary_indicator; 143 + u8 summary_indicator_idx; 144 144 struct airq_struct airq; 145 145 struct airq_iv *aiv; 146 146 }; 147 147 static struct airq_info *airq_areas[MAX_AIRQ_AREAS]; 148 + static u8 *summary_indicators; 149 + 150 + static inline u8 *get_summary_indicator(struct airq_info *info) 151 + { 152 + return summary_indicators + info->summary_indicator_idx; 153 + } 148 154 149 155 #define CCW_CMD_SET_VQ 0x13 150 156 #define CCW_CMD_VDEV_RESET 0x33 ··· 215 209 break; 216 210 vring_interrupt(0, (void *)airq_iv_get_ptr(info->aiv, ai)); 217 211 } 218 - info->summary_indicator = 0; 212 + *(get_summary_indicator(info)) = 0; 219 213 smp_wmb(); 220 214 /* Walk through indicators field, summary indicator not active. */ 221 215 for (ai = 0;;) { ··· 227 221 read_unlock(&info->lock); 228 222 } 229 223 230 - static struct airq_info *new_airq_info(void) 224 + static struct airq_info *new_airq_info(int index) 231 225 { 232 226 struct airq_info *info; 233 227 int rc; ··· 243 237 return NULL; 244 238 } 245 239 info->airq.handler = virtio_airq_handler; 246 - info->airq.lsi_ptr = &info->summary_indicator; 240 + info->summary_indicator_idx = index; 241 + info->airq.lsi_ptr = get_summary_indicator(info); 247 242 info->airq.lsi_mask = 0xff; 248 243 info->airq.isc = VIRTIO_AIRQ_ISC; 249 244 rc = register_adapter_interrupt(&info->airq); ··· 266 259 267 260 for (i = 0; i < MAX_AIRQ_AREAS && !indicator_addr; i++) { 268 261 if (!airq_areas[i]) 269 - airq_areas[i] = new_airq_info(); 262 + airq_areas[i] = new_airq_info(i); 270 263 info = airq_areas[i]; 271 264 if (!info) 272 265 return 0; ··· 352 345 if (!thinint_area) 353 346 return; 354 347 thinint_area->summary_indicator = 355 - (unsigned long) &airq_info->summary_indicator; 348 + (unsigned long) get_summary_indicator(airq_info); 356 349 thinint_area->isc = VIRTIO_AIRQ_ISC; 357 350 ccw->cmd_code = CCW_CMD_SET_IND_ADAPTER; 358 351 ccw->count = sizeof(*thinint_area); ··· 620 613 } 621 614 info = vcdev->airq_info; 622 615 thinint_area->summary_indicator = 623 - (unsigned long) &info->summary_indicator; 616 + (unsigned long) get_summary_indicator(info); 624 617 thinint_area->isc = VIRTIO_AIRQ_ISC; 625 618 ccw->cmd_code = CCW_CMD_SET_IND_ADAPTER; 626 619 ccw->flags = CCW_FLAG_SLI; ··· 1500 1493 1501 1494 static int __init virtio_ccw_init(void) 1502 1495 { 1496 + int rc; 1497 + 1503 1498 /* parse no_auto string before we do anything further */ 1504 1499 no_auto_parse(); 1505 - return ccw_driver_register(&virtio_ccw_driver); 1500 + 1501 + summary_indicators = cio_dma_zalloc(MAX_AIRQ_AREAS); 1502 + if (!summary_indicators) 1503 + return -ENOMEM; 1504 + rc = ccw_driver_register(&virtio_ccw_driver); 1505 + if (rc) 1506 + cio_dma_free(summary_indicators, MAX_AIRQ_AREAS); 1507 + return rc; 1506 1508 } 1507 1509 device_initcall(virtio_ccw_init);