lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1267801390.11737.38014.camel@zakaz.uk.xensource.com>
Date:	Fri, 5 Mar 2010 15:03:10 +0000
From:	Ian Campbell <Ian.Campbell@...rix.com>
To:	Yinghai Lu <yinghai@...nel.org>,
	Peter Zijlstra <peterz@...radead.org>,
	Ingo Molnar <mingo@...e.hu>
CC:	linux-kernel <linux-kernel@...r.kernel.org>
Subject: Infinite loop on boot in free_early_partial due to start==end on
 tip/master

Adding some debug, including a WARN_ON(start >= end) I get:

(early) [    0.000000] pcpu_embed_first_chunk CPU0 copy and return the unused part ffff880001f1f000 0x0. unit_size 122880 size sum 122880
(early) [    0.000000] free_early_partial 0x1f1f000-0x1f1f000
(early) [    0.000000] ------------[ cut here ]------------
(early) [    0.000000] WARNING: at /local/scratch/ianc/devel/kernels/linux-2.6/kernel/early_res.c:359 free_early_partial+0x46/0x15c()
(early) [    0.000000] Modules linked in:(early) 
(early) [    0.000000] Pid: 0, comm: swapper Not tainted 2.6.33-x86_64-xenU-tip+ #119
(early) [    0.000000] Call Trace:
(early) [    0.000000]  [<ffffffff81b3938e>] ? free_early_partial+0x46/0x15c
(early) [    0.000000]  [<ffffffff81047317>] warn_slowpath_common+0x77/0xa4
(early) [    0.000000]  [<ffffffff81047353>] warn_slowpath_null+0xf/0x11
(early) [    0.000000]  [<ffffffff81b3938e>] free_early_partial+0x46/0x15c
(early) [    0.000000]  [<ffffffff81b29a05>] pcpu_fc_free+0x1f/0x23
(early) [    0.000000]  [<ffffffff81b3fcf1>] pcpu_embed_first_chunk+0x22f/0x363
(early) [    0.000000]  [<ffffffff81b299e6>] ? pcpu_fc_free+0x0/0x23
(early) [    0.000000]  [<ffffffff81b29a09>] ? pcpu_fc_alloc+0x0/0xa9
(early) [    0.000000]  [<ffffffff81b29825>] setup_per_cpu_areas+0x82/0x238
(early) [    0.000000]  [<ffffffff81b1eabc>] start_kernel+0x14b/0x3ab
(early) [    0.000000]  [<ffffffff81b1e2ba>] x86_64_start_reservations+0xa5/0xa9
(early) [    0.000000]  [<ffffffff81b21d61>] xen_start_kernel+0x52e/0x535
(early) [    0.000000] ---[ end trace 4eaa2a86a8e2da22 ]---

I'm seeing this in a Xen guest but I don't think it relates to Xen
specifically. The problem occurs when ai->unit_size == size_sum in
pcpu_embed_first_chunk(). It looks like I just got unlucky with the
various sizes of stuff coming out of pcpu_build_alloc_info().

It's also possible that the presence or absence of PSE is responsible,
since it impacts atom_size which feeds into alloc_size and has an impact
on all these calculations.

I was able to reproduce on native 32 bit by disabling PSE and
artificially increasing dyn_size.

(early) [    0.000000] pcpu_build_alloc_info initial max_upa/upa is 1
(early) [    0.000000] pcpu_build_alloc_info after expansion best_upa/upa is 1
(early) [    0.000000] reserve_early_without_check: 0x1ce3000-0x1ce4000 "BOOTMEM"
(early) [    0.000000] pcpu_build_alloc_info unit_size 122880 == alloc_size 122880 / upa 1
(early) [    0.000000] pcpu_embed_first_chunk size_sum = 122880
(early) [    0.000000] pcpu_embed_first_chunk  static_size   = 91304
(early) [    0.000000] pcpu_embed_first_chunk  reserved_size = 8192
(early) [    0.000000] pcpu_embed_first_chunk  dyn_size      = 23384
(early) [    0.000000] pcpu_embed_first_chunk unit_size 122880

I guess the arises from fb90ef93 "early_res: Add free_early_partial"
since I don't see any other changes in this area recently.

Following patch fixes this specific issue and adds a warning to catch
future potential errors of this type.

--- 
Subject: x86: do not free zero sized per cpu areas

This avoids an infinite loop in free_early_partial().

Add a warning to free_early_partial to catch future problems.

Signed-off-by: Ian Campbell <ian.campbell@...rix.com>

diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index ef6370b..89a3205 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -140,7 +140,8 @@ static void __init pcpu_fc_free(void *ptr, size_t size)
 #ifdef CONFIG_NO_BOOTMEM
 	u64 start = __pa(ptr);
 	u64 end = start + size;
-	free_early_partial(start, end);
+	if (start < end)
+		free_early_partial(start, end);
 #else
 	free_bootmem(__pa(ptr), size);
 #endif
diff --git a/kernel/early_res.c b/kernel/early_res.c
index 3cb2c66..fbde443 100644
--- a/kernel/early_res.c
+++ b/kernel/early_res.c
@@ -333,6 +333,8 @@ void __init free_early_partial(u64 start, u64 end)
 	struct early_res *r;
 	int i;
 
+	WARN_ON(start>=end);
+
 try_next:
 	i = find_overlapped_early(start, end);
 	if (i >= max_early_res)


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ