summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/mem_detect.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-31 16:14:20 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-31 16:14:20 -0700
commit32087d4eeca14b82660dab288b1d659963b954bd (patch)
tree8c131ca9bf08f88d3b02e1937b795a42f8951d79 /arch/s390/kernel/mem_detect.c
parentb1c907f3b2675ecb01e340948fc62d6535ff5ac3 (diff)
parent07ea815b22b9f70ec8de6ddf8db63a1dd1585caf (diff)
downloadblackbird-op-linux-32087d4eeca14b82660dab288b1d659963b954bd.tar.gz
blackbird-op-linux-32087d4eeca14b82660dab288b1d659963b954bd.zip
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (54 commits) [S390] Remove error checking from copy_oldmem_page() [S390] qdio: prevent dsci access without adapter interrupts [S390] irqstats: split IPI interrupt accounting [S390] add missing __tlb_flush_global() for !CONFIG_SMP [S390] sparse: fix sparse symbol shadow warning [S390] sparse: fix sparse NULL pointer warnings [S390] sparse: fix sparse warnings with __user pointers [S390] sparse: fix sparse warnings in math-emu [S390] sparse: fix sparse warnings about missing prototypes [S390] sparse: fix sparse ANSI-C warnings [S390] sparse: fix sparse static warnings [S390] sparse: fix access past end of array warnings [S390] dasd: prevent path verification before resume [S390] qdio: remove multicast polling [S390] qdio: reset outbound SBAL error states [S390] qdio: EQBS retry after CCQ 96 [S390] qdio: add timestamp for last queue scan time [S390] Introduce get_clock_fast() [S390] kvm: Handle diagnose 0x10 (release pages) [S390] take mmap_sem when walking guest page table ...
Diffstat (limited to 'arch/s390/kernel/mem_detect.c')
-rw-r--r--arch/s390/kernel/mem_detect.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/arch/s390/kernel/mem_detect.c b/arch/s390/kernel/mem_detect.c
index 0fbe4e32f7ba..19b4568f4cee 100644
--- a/arch/s390/kernel/mem_detect.c
+++ b/arch/s390/kernel/mem_detect.c
@@ -62,3 +62,72 @@ void detect_memory_layout(struct mem_chunk chunk[])
arch_local_irq_restore(flags);
}
EXPORT_SYMBOL(detect_memory_layout);
+
+/*
+ * Create memory hole with given address, size, and type
+ */
+void create_mem_hole(struct mem_chunk chunks[], unsigned long addr,
+ unsigned long size, int type)
+{
+ unsigned long start, end, new_size;
+ int i;
+
+ for (i = 0; i < MEMORY_CHUNKS; i++) {
+ if (chunks[i].size == 0)
+ continue;
+ if (addr + size < chunks[i].addr)
+ continue;
+ if (addr >= chunks[i].addr + chunks[i].size)
+ continue;
+ start = max(addr, chunks[i].addr);
+ end = min(addr + size, chunks[i].addr + chunks[i].size);
+ new_size = end - start;
+ if (new_size == 0)
+ continue;
+ if (start == chunks[i].addr &&
+ end == chunks[i].addr + chunks[i].size) {
+ /* Remove chunk */
+ chunks[i].type = type;
+ } else if (start == chunks[i].addr) {
+ /* Make chunk smaller at start */
+ if (i >= MEMORY_CHUNKS - 1)
+ panic("Unable to create memory hole");
+ memmove(&chunks[i + 1], &chunks[i],
+ sizeof(struct mem_chunk) *
+ (MEMORY_CHUNKS - (i + 1)));
+ chunks[i + 1].addr = chunks[i].addr + new_size;
+ chunks[i + 1].size = chunks[i].size - new_size;
+ chunks[i].size = new_size;
+ chunks[i].type = type;
+ i += 1;
+ } else if (end == chunks[i].addr + chunks[i].size) {
+ /* Make chunk smaller at end */
+ if (i >= MEMORY_CHUNKS - 1)
+ panic("Unable to create memory hole");
+ memmove(&chunks[i + 1], &chunks[i],
+ sizeof(struct mem_chunk) *
+ (MEMORY_CHUNKS - (i + 1)));
+ chunks[i + 1].addr = start;
+ chunks[i + 1].size = new_size;
+ chunks[i + 1].type = type;
+ chunks[i].size -= new_size;
+ i += 1;
+ } else {
+ /* Create memory hole */
+ if (i >= MEMORY_CHUNKS - 2)
+ panic("Unable to create memory hole");
+ memmove(&chunks[i + 2], &chunks[i],
+ sizeof(struct mem_chunk) *
+ (MEMORY_CHUNKS - (i + 2)));
+ chunks[i + 1].addr = addr;
+ chunks[i + 1].size = size;
+ chunks[i + 1].type = type;
+ chunks[i + 2].addr = addr + size;
+ chunks[i + 2].size =
+ chunks[i].addr + chunks[i].size - (addr + size);
+ chunks[i + 2].type = chunks[i].type;
+ chunks[i].size = addr - chunks[i].addr;
+ i += 2;
+ }
+ }
+}
OpenPOWER on IntegriCloud