All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Slaby <jslaby@suse.cz>
To: stable@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
	Mikulas Patocka <mpatocka@redhat.com>,
	Helge Deller <deller@gmx.de>, Jiri Slaby <jslaby@suse.cz>
Subject: [PATCH 3.12 49/64] parisc iommu: fix panic due to trying to allocate too large region
Date: Thu, 11 Feb 2016 14:59:25 +0100	[thread overview]
Message-ID: <aaa9c9f8e2c0a4719f4592a03db81d719a2b6ad5.1455198893.git.jslaby@suse.cz> (raw)
In-Reply-To: <74c0820133f1dada0d70c74bc70a9530b2697f86.1455198893.git.jslaby@suse.cz>
In-Reply-To: <cover.1455198893.git.jslaby@suse.cz>

From: Mikulas Patocka <mpatocka@redhat.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit e46e31a3696ae2d66f32c207df3969613726e636 upstream.

When using the Promise TX2+ SATA controller on PA-RISC, the system often
crashes with kernel panic, for example just writing data with the dd
utility will make it crash.

Kernel panic - not syncing: drivers/parisc/sba_iommu.c: I/O MMU @ 000000000000a000 is out of mapping resources

CPU: 0 PID: 18442 Comm: mkspadfs Not tainted 4.4.0-rc2 #2
Backtrace:
 [<000000004021497c>] show_stack+0x14/0x20
 [<0000000040410bf0>] dump_stack+0x88/0x100
 [<000000004023978c>] panic+0x124/0x360
 [<0000000040452c18>] sba_alloc_range+0x698/0x6a0
 [<0000000040453150>] sba_map_sg+0x260/0x5b8
 [<000000000c18dbb4>] ata_qc_issue+0x264/0x4a8 [libata]
 [<000000000c19535c>] ata_scsi_translate+0xe4/0x220 [libata]
 [<000000000c19a93c>] ata_scsi_queuecmd+0xbc/0x320 [libata]
 [<0000000040499bbc>] scsi_dispatch_cmd+0xfc/0x130
 [<000000004049da34>] scsi_request_fn+0x6e4/0x970
 [<00000000403e95a8>] __blk_run_queue+0x40/0x60
 [<00000000403e9d8c>] blk_run_queue+0x3c/0x68
 [<000000004049a534>] scsi_run_queue+0x2a4/0x360
 [<000000004049be68>] scsi_end_request+0x1a8/0x238
 [<000000004049de84>] scsi_io_completion+0xfc/0x688
 [<0000000040493c74>] scsi_finish_command+0x17c/0x1d0

The cause of the crash is not exhaustion of the IOMMU space, there is
plenty of free pages. The function sba_alloc_range is called with size
0x11000, thus the pages_needed variable is 0x11. The function
sba_search_bitmap is called with bits_wanted 0x11 and boundary size is
0x10 (because dma_get_seg_boundary(dev) returns 0xffff).

The function sba_search_bitmap attempts to allocate 17 pages that must not
cross 16-page boundary - it can't satisfy this requirement
(iommu_is_span_boundary always returns true) and fails even if there are
many free entries in the IOMMU space.

How did it happen that we try to allocate 17 pages that don't cross
16-page boundary? The cause is in the function iommu_coalesce_chunks. This
function tries to coalesce adjacent entries in the scatterlist. The
function does several checks if it may coalesce one entry with the next,
one of those checks is this:

	if (startsg->length + dma_len > max_seg_size)
		break;

When it finishes coalescing adjacent entries, it allocates the mapping:

sg_dma_len(contig_sg) = dma_len;
dma_len = ALIGN(dma_len + dma_offset, IOVP_SIZE);
sg_dma_address(contig_sg) =
	PIDE_FLAG
	| (iommu_alloc_range(ioc, dev, dma_len) << IOVP_SHIFT)
	| dma_offset;

It is possible that (startsg->length + dma_len > max_seg_size) is false
(we are just near the 0x10000 max_seg_size boundary), so the funcion
decides to coalesce this entry with the next entry. When the coalescing
succeeds, the function performs
	dma_len = ALIGN(dma_len + dma_offset, IOVP_SIZE);
And now, because of non-zero dma_offset, dma_len is greater than 0x10000.
iommu_alloc_range (a pointer to sba_alloc_range) is called and it attempts
to allocate 17 pages for a device that must not cross 16-page boundary.

To fix the bug, we must make sure that dma_len after addition of
dma_offset and alignment doesn't cross the segment boundary. I.e. change
	if (startsg->length + dma_len > max_seg_size)
		break;
to
	if (ALIGN(dma_len + dma_offset + startsg->length, IOVP_SIZE) > max_seg_size)
		break;

This patch makes this change (it precalculates max_seg_boundary at the
beginning of the function iommu_coalesce_chunks). I also added a check
that the mapping length doesn't exceed dma_get_seg_boundary(dev) (it is
not needed for Promise TX2+ SATA, but it may be needed for other devices
that have dma_get_seg_boundary lower than dma_get_max_seg_size).

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/parisc/iommu-helpers.h | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h
index 8c33491b21fe..c6aa38883466 100644
--- a/drivers/parisc/iommu-helpers.h
+++ b/drivers/parisc/iommu-helpers.h
@@ -104,7 +104,11 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
 	struct scatterlist *contig_sg;	   /* contig chunk head */
 	unsigned long dma_offset, dma_len; /* start/len of DMA stream */
 	unsigned int n_mappings = 0;
-	unsigned int max_seg_size = dma_get_max_seg_size(dev);
+	unsigned int max_seg_size = min(dma_get_max_seg_size(dev),
+					(unsigned)DMA_CHUNK_SIZE);
+	unsigned int max_seg_boundary = dma_get_seg_boundary(dev) + 1;
+	if (max_seg_boundary)	/* check if the addition above didn't overflow */
+		max_seg_size = min(max_seg_size, max_seg_boundary);
 
 	while (nents > 0) {
 
@@ -139,14 +143,11 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
 
 			/*
 			** First make sure current dma stream won't
-			** exceed DMA_CHUNK_SIZE if we coalesce the
+			** exceed max_seg_size if we coalesce the
 			** next entry.
 			*/   
-			if(unlikely(ALIGN(dma_len + dma_offset + startsg->length,
-					    IOVP_SIZE) > DMA_CHUNK_SIZE))
-				break;
-
-			if (startsg->length + dma_len > max_seg_size)
+			if (unlikely(ALIGN(dma_len + dma_offset + startsg->length, IOVP_SIZE) >
+				     max_seg_size))
 				break;
 
 			/*
-- 
2.7.1

  parent reply	other threads:[~2016-02-11 14:04 UTC|newest]

Thread overview: 80+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-11 13:59 [PATCH 3.12 00/64] 3.12.54-stable review Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 01/64] ALSA: rme96: Fix unexpected volume reset after rate changes Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 02/64] ALSA: hda - Add inverted dmic for Packard Bell DOTS Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 03/64] ALSA: hda - Set SKL+ hda controller power at freeze() and thaw() Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 04/64] ALSA: hda/realtek - Fix silent headphone output on MacPro 4,1 (v2) Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 05/64] ALSA: seq: Fix missing NULL check at remove_events ioctl Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 06/64] ALSA: seq: Fix race at timer setup and close Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 07/64] ALSA: timer: Harden slave timer list handling Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 08/64] ALSA: timer: Fix race among timer ioctls Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 09/64] ALSA: timer: Fix double unlink of active_list Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 10/64] ALSA: seq: Fix snd_seq_call_port_info_ioctl in compat mode Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 11/64] ALSA: pcm: Fix snd_pcm_hw_params struct copy " Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 12/64] ALSA: hrtimer: Fix stall by hrtimer_cancel() Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 13/64] ALSA: control: Avoid kernel warnings from tlv ioctl with numid 0 Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 14/64] ASoC: wm8962: correct addresses for HPF_C_0/1 Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 15/64] ASoC: arizona: Fix bclk for sample rates that are multiple of 4kHz Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 16/64] ASoC: compress: Fix compress device direction check Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 17/64] usb: xhci: fix config fail of FS hub behind a HS hub with MTT Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 18/64] USB: ipaq.c: fix a timeout loop Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 19/64] USB: cp210x: add ID for ELV Marble Sound Board 1 Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 20/64] xhci: refuse loading if nousb is used Jiri Slaby
2016-02-16  3:06   ` Ben Hutchings
2016-02-16  8:49     ` Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 21/64] ARM: 8158/1: LLVMLinux: use static inline in ARM ftrace.h Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 22/64] ARM: 8160/1: drop warning about return_address not using unwind tables Jiri Slaby
2016-02-11 13:58 ` [PATCH 3.12 23/64] drm/radeon: cypress_dpm: Fix unused variable warning when CONFIG_ACPI=n Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 24/64] drm: radeon: ni_dpm: " Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 25/64] lkdtm: adjust recursion size to avoid warnings Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 26/64] RDMA/cxgb4: Fix gcc warning on 32-bit arch Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 27/64] mISDN: avoid arch specific __builtin_return_address call Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 28/64] veth: don’t modify ip_summed; doing so treats packets with bad checksums as good Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 29/64] ipv6/addrlabel: fix ip6addrlbl_get() Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 30/64] sctp: sctp should release assoc when sctp_make_abort_user return NULL in sctp_close Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 31/64] connector: bump skb->users before callback invocation Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 32/64] unix: properly account for FDs passed over unix sockets Jiri Slaby
2016-02-11 17:32   ` Willy Tarreau
2016-02-12  7:57     ` Jiri Slaby
2016-02-12  8:45       ` Philipp Hahn
2016-02-12  9:03         ` Willy Tarreau
2016-02-11 13:59 ` [PATCH 3.12 33/64] bridge: Only call /sbin/bridge-stp for the initial network namespace Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 34/64] net: sctp: prevent writes to cookie_hmac_alg from accessing invalid memory Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 35/64] ipv6: tcp: add rcu locking in tcp_v6_send_synack() Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 36/64] tcp_yeah: don't set ssthresh below 2 Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 37/64] phonet: properly unshare skbs in phonet_rcv() Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 38/64] ipv6: update skb->csum when CE mark is propagated Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 39/64] team: Replace rcu_read_lock with a mutex in team_vlan_rx_kill_vid Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 40/64] xfrm: dst_entries_init() per-net dst_ops Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 41/64] powerpc/tm: Block signal return setting invalid MSR state Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 42/64] powerpc: Make value-returning atomics fully ordered Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 43/64] powerpc: Make {cmp}xchg* and their atomic_ versions " Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 44/64] scripts/recordmcount.pl: support data in text section on powerpc Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 45/64] arm64: KVM: Fix AArch32 to AArch64 register mapping Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 46/64] arm64: fix building without CONFIG_UID16 Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 47/64] arm64: Clear out any singlestep state on a ptrace detach operation Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 48/64] arm64: mm: ensure that the zero page is visible to the page table walker Jiri Slaby
2016-02-11 13:59 ` Jiri Slaby [this message]
2016-02-11 13:59 ` [PATCH 3.12 50/64] HID: core: Avoid uninitialized buffer access Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 51/64] mn10300: Select CONFIG_HAVE_UID16 to fix build failure Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 52/64] arm64: restore bogomips information in /proc/cpuinfo Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 53/64] compiler/gcc4+: Remove inaccurate comment about 'asm goto' miscompiles Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 54/64] compiler-gcc: integrate the various compiler-gcc[345].h files Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 55/64] x86: vvar, fix excessive gcc-6 DECLARE_VVAR warnings Jiri Slaby
2016-02-12 16:42   ` Andy Lutomirski
2016-02-11 13:59 ` [PATCH 3.12 56/64] openrisc: fix CONFIG_UID16 setting Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 57/64] vmstat: explicitly schedule per-cpu work on the CPU we need it to run on Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 58/64] Revert "workqueue: make sure delayed work run in local cpu" Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 59/64] xhci: fix placement of call to usb_disabled() Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 60/64] recordmcount: Fix endianness handling bug for nop_mcount Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 61/64] crypto: algif_hash - Only export and import on sockets with data Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 62/64] dm btree: fix leak of bufio-backed block in btree_split_sibling error path Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 63/64] drivers/base/memory.c: prohibit offlining of memory blocks with missing sections Jiri Slaby
2016-02-11 13:59 ` [PATCH 3.12 64/64] HID: usbhid: fix recursive deadlock Jiri Slaby
2016-02-11 14:09 ` [PATCH 3.12 00/64] 3.12.54-stable review Nikolay Borisov
2016-02-11 14:10   ` Jiri Slaby
2016-02-11 14:12     ` Jiri Slaby
2016-02-11 14:17 ` [PATCH 3.12 65/65] dm thin: fix race condition when destroying thin pool workqueue Jiri Slaby
2016-02-11 18:17 ` [PATCH 3.12 00/64] 3.12.54-stable review Guenter Roeck
2016-02-11 19:26 ` Shuah Khan
2016-02-15 15:20   ` Jiri Slaby
2016-02-15 16:10     ` Winkler, Tomas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aaa9c9f8e2c0a4719f4592a03db81d719a2b6ad5.1455198893.git.jslaby@suse.cz \
    --to=jslaby@suse.cz \
    --cc=deller@gmx.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mpatocka@redhat.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.