Commit 4d7b04c0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull s390 fixes from Vasily Gorbik:

 - Fix IOMMU bitmap allocation in s390 PCI to avoid out of bounds access
   when IOMMU pages aren't a multiple of 64

 - Fix kasan crashes when accessing DCSS mapping in memory holes by
   adding corresponding kasan zero shadow mappings

 - Fix a memory leak in css_alloc_subchannel in case
   dma_set_coherent_mask fails

* tag 's390-6.6-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/pci: fix iommu bitmap allocation
  s390/kasan: handle DCSS mapping in memory holes
  s390/cio: fix a memleak in css_alloc_subchannel
parents f51de61c c1ae1c59
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ static void kasan_populate_shadow(void)
	pmd_t pmd_z = __pmd(__pa(kasan_early_shadow_pte) | _SEGMENT_ENTRY);
	pud_t pud_z = __pud(__pa(kasan_early_shadow_pmd) | _REGION3_ENTRY);
	p4d_t p4d_z = __p4d(__pa(kasan_early_shadow_pud) | _REGION2_ENTRY);
	unsigned long memgap_start = 0;
	unsigned long untracked_end;
	unsigned long start, end;
	int i;
@@ -101,8 +102,12 @@ static void kasan_populate_shadow(void)
	 * +- shadow end ----+---------+- shadow end ---+
	 */

	for_each_physmem_usable_range(i, &start, &end)
	for_each_physmem_usable_range(i, &start, &end) {
		kasan_populate(start, end, POPULATE_KASAN_MAP_SHADOW);
		if (memgap_start && physmem_info.info_source == MEM_DETECT_DIAG260)
			kasan_populate(memgap_start, start, POPULATE_KASAN_ZERO_SHADOW);
		memgap_start = end;
	}
	if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) {
		untracked_end = VMALLOC_START;
		/* shallowly populate kasan shadow for vmalloc and modules */
+13 −2
Original line number Diff line number Diff line
@@ -565,6 +565,17 @@ static void s390_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
	}
}

static unsigned long *bitmap_vzalloc(size_t bits, gfp_t flags)
{
	size_t n = BITS_TO_LONGS(bits);
	size_t bytes;

	if (unlikely(check_mul_overflow(n, sizeof(unsigned long), &bytes)))
		return NULL;

	return vzalloc(bytes);
}
	
int zpci_dma_init_device(struct zpci_dev *zdev)
{
	u8 status;
@@ -604,13 +615,13 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
				zdev->end_dma - zdev->start_dma + 1);
	zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1;
	zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT;
	zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8);
	zdev->iommu_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL);
	if (!zdev->iommu_bitmap) {
		rc = -ENOMEM;
		goto free_dma_table;
	}
	if (!s390_iommu_strict) {
		zdev->lazy_bitmap = vzalloc(zdev->iommu_pages / 8);
		zdev->lazy_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL);
		if (!zdev->lazy_bitmap) {
			rc = -ENOMEM;
			goto free_bitmap;
+4 −2
Original line number Diff line number Diff line
@@ -233,17 +233,19 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid,
	 */
	ret = dma_set_coherent_mask(&sch->dev, DMA_BIT_MASK(31));
	if (ret)
		goto err;
		goto err_lock;
	/*
	 * But we don't have such restrictions imposed on the stuff that
	 * is handled by the streaming API.
	 */
	ret = dma_set_mask(&sch->dev, DMA_BIT_MASK(64));
	if (ret)
		goto err;
		goto err_lock;

	return sch;

err_lock:
	kfree(sch->lock);
err:
	kfree(sch);
	return ERR_PTR(ret);