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.

s390/airq: allow for airq structure that uses an input vector

When doing device passthrough where interrupts are being forwarded from
host to guest, we wish to use a pinned section of guest memory as the
vector (the same memory used by the guest as the vector). To accomplish
this, add a new parameter for airq_iv_create which allows passing an
existing vector to be used instead of allocating a new one. The caller
is responsible for ensuring the vector is pinned in memory as well as for
unpinning the memory when the vector is no longer needed.

A subsequent patch will use this new parameter for zPCI interpretation.

Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Acked-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Link: https://lore.kernel.org/r/20220606203325.110625-7-mjrosato@linux.ibm.com
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>

authored by

Matthew Rosato and committed by
Christian Borntraeger
932b6467 d2197485

+15 -9
+3 -1
arch/s390/include/asm/airq.h
··· 47 47 #define AIRQ_IV_PTR 4 /* Allocate the ptr array */ 48 48 #define AIRQ_IV_DATA 8 /* Allocate the data array */ 49 49 #define AIRQ_IV_CACHELINE 16 /* Cacheline alignment for the vector */ 50 + #define AIRQ_IV_GUESTVEC 32 /* Vector is a pinned guest page */ 50 51 51 - struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags); 52 + struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags, 53 + unsigned long *vec); 52 54 void airq_iv_release(struct airq_iv *iv); 53 55 unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num); 54 56 void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num);
+4 -4
arch/s390/pci/pci_irq.c
··· 296 296 zdev->aisb = bit; 297 297 298 298 /* Create adapter interrupt vector */ 299 - zdev->aibv = airq_iv_create(msi_vecs, AIRQ_IV_DATA | AIRQ_IV_BITLOCK); 299 + zdev->aibv = airq_iv_create(msi_vecs, AIRQ_IV_DATA | AIRQ_IV_BITLOCK, NULL); 300 300 if (!zdev->aibv) 301 301 return -ENOMEM; 302 302 ··· 419 419 union zpci_sic_iib iib = {{0}}; 420 420 unsigned int cpu; 421 421 422 - zpci_sbv = airq_iv_create(num_possible_cpus(), 0); 422 + zpci_sbv = airq_iv_create(num_possible_cpus(), 0, NULL); 423 423 if (!zpci_sbv) 424 424 return -ENOMEM; 425 425 ··· 441 441 zpci_ibv[cpu] = airq_iv_create(cache_line_size() * BITS_PER_BYTE, 442 442 AIRQ_IV_DATA | 443 443 AIRQ_IV_CACHELINE | 444 - (!cpu ? AIRQ_IV_ALLOC : 0)); 444 + (!cpu ? AIRQ_IV_ALLOC : 0), NULL); 445 445 if (!zpci_ibv[cpu]) 446 446 return -ENOMEM; 447 447 } ··· 458 458 if (!zpci_ibv) 459 459 return -ENOMEM; 460 460 461 - zpci_sbv = airq_iv_create(ZPCI_NR_DEVICES, AIRQ_IV_ALLOC); 461 + zpci_sbv = airq_iv_create(ZPCI_NR_DEVICES, AIRQ_IV_ALLOC, NULL); 462 462 if (!zpci_sbv) 463 463 goto out_free; 464 464
+7 -3
drivers/s390/cio/airq.c
··· 122 122 * airq_iv_create - create an interrupt vector 123 123 * @bits: number of bits in the interrupt vector 124 124 * @flags: allocation flags 125 + * @vec: pointer to pinned guest memory if AIRQ_IV_GUESTVEC 125 126 * 126 127 * Returns a pointer to an interrupt vector structure 127 128 */ 128 - struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags) 129 + struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags, 130 + unsigned long *vec) 129 131 { 130 132 struct airq_iv *iv; 131 133 unsigned long size; ··· 148 146 &iv->vector_dma); 149 147 if (!iv->vector) 150 148 goto out_free; 149 + } else if (flags & AIRQ_IV_GUESTVEC) { 150 + iv->vector = vec; 151 151 } else { 152 152 iv->vector = cio_dma_zalloc(size); 153 153 if (!iv->vector) ··· 189 185 kfree(iv->avail); 190 186 if (iv->flags & AIRQ_IV_CACHELINE && iv->vector) 191 187 dma_pool_free(airq_iv_cache, iv->vector, iv->vector_dma); 192 - else 188 + else if (!(iv->flags & AIRQ_IV_GUESTVEC)) 193 189 cio_dma_free(iv->vector, size); 194 190 kfree(iv); 195 191 out: ··· 208 204 kfree(iv->bitlock); 209 205 if (iv->flags & AIRQ_IV_CACHELINE) 210 206 dma_pool_free(airq_iv_cache, iv->vector, iv->vector_dma); 211 - else 207 + else if (!(iv->flags & AIRQ_IV_GUESTVEC)) 212 208 cio_dma_free(iv->vector, iv_size(iv->bits)); 213 209 kfree(iv->avail); 214 210 kfree(iv);
+1 -1
drivers/s390/virtio/virtio_ccw.c
··· 242 242 return NULL; 243 243 rwlock_init(&info->lock); 244 244 info->aiv = airq_iv_create(VIRTIO_IV_BITS, AIRQ_IV_ALLOC | AIRQ_IV_PTR 245 - | AIRQ_IV_CACHELINE); 245 + | AIRQ_IV_CACHELINE, NULL); 246 246 if (!info->aiv) { 247 247 kfree(info); 248 248 return NULL;