aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2013-04-25 04:03:15 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-04-26 03:07:10 -0400
commit94c163663fc1dcfc067a5fb3cc1446b9469975ce (patch)
tree438604c3bc95a1ed22ea4f9e17f2014de800f75e
parent581618f226e83eb0fbe81ba2a623c6a55cbb7487 (diff)
s390/memory hotplug: prevent offline of active memory increments
In case a machine supports memory hotplug all active memory increments present at IPL time have been initialized with a "usecount" of 1. This is wrong if the memory increment size is larger than the memory section size of the memory hotplug code. If that is the case the usecount must be initialized with the number of memory sections that fit into one memory increment. Otherwise it is possible to put a memory increment into standby state even if there are still active sections. Afterwards addressing exceptions might happen which cause the kernel to panic. However even worse, if a memory increment was put into standby state and afterwards into active state again, it's contents would have been zeroed, leading to memory corruption. This was only an issue for machines that support standby memory and have at least 256GB memory. This is broken since commit fdb1bb15 "[S390] sclp/memory hotplug: fix initial usecount of increments". Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Reviewed-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> Cc: stable@vger.kernel.org # 2.6.39+ Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/char/sclp_cmd.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index cd798386b622..178836ec252b 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -561,6 +561,8 @@ static void __init sclp_add_standby_memory(void)
561 add_memory_merged(0); 561 add_memory_merged(0);
562} 562}
563 563
564#define MEM_SCT_SIZE (1UL << SECTION_SIZE_BITS)
565
564static void __init insert_increment(u16 rn, int standby, int assigned) 566static void __init insert_increment(u16 rn, int standby, int assigned)
565{ 567{
566 struct memory_increment *incr, *new_incr; 568 struct memory_increment *incr, *new_incr;
@@ -573,7 +575,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned)
573 new_incr->rn = rn; 575 new_incr->rn = rn;
574 new_incr->standby = standby; 576 new_incr->standby = standby;
575 if (!standby) 577 if (!standby)
576 new_incr->usecount = 1; 578 new_incr->usecount = rzm > MEM_SCT_SIZE ? rzm/MEM_SCT_SIZE : 1;
577 last_rn = 0; 579 last_rn = 0;
578 prev = &sclp_mem_list; 580 prev = &sclp_mem_list;
579 list_for_each_entry(incr, &sclp_mem_list, list) { 581 list_for_each_entry(incr, &sclp_mem_list, list) {