aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/e820.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xensource.com>2007-09-27 16:50:52 +0100
committerKeir Fraser <keir@xensource.com>2007-09-27 16:50:52 +0100
commit0d68d7c0fad3f6547413eddcd22bacaa65550d2b (patch)
tree6783d06bf180ba3198fe2c37036877dcd9203c25 /xen/arch/x86/e820.c
parent67c97dc9f7e8bda9947dae8bf5d26f09d895033a (diff)
downloadxen-0d68d7c0fad3f6547413eddcd22bacaa65550d2b.tar.gz
xen-0d68d7c0fad3f6547413eddcd22bacaa65550d2b.tar.bz2
xen-0d68d7c0fad3f6547413eddcd22bacaa65550d2b.zip
x86: If e820 map overflows, leak memory in a safe manner.
Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'xen/arch/x86/e820.c')
-rw-r--r--xen/arch/x86/e820.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/xen/arch/x86/e820.c b/xen/arch/x86/e820.c
index e678a4be52..2fbfa87160 100644
--- a/xen/arch/x86/e820.c
+++ b/xen/arch/x86/e820.c
@@ -416,11 +416,9 @@ int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e)
/* Truncate end. */
e820->map[i].size -= e - s;
}
- else
+ else if ( e820->nr_map < ARRAY_SIZE(e820->map) )
{
/* Split in two. */
- if ( e820->nr_map >= ARRAY_SIZE(e820->map) )
- return 0;
memmove(&e820->map[i+1], &e820->map[i],
(e820->nr_map-i) * sizeof(e820->map[0]));
e820->nr_map++;
@@ -429,6 +427,21 @@ int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e)
e820->map[i].addr = e;
e820->map[i].size = re - e;
}
+ else
+ {
+ /* e820map is at maximum size. We have to leak some space. */
+ if ( (s - rs) > (re - e) )
+ {
+ printk("e820 overflow: leaking RAM %"PRIx64"-%"PRIx64"\n", e, re);
+ e820->map[i].size = s - rs;
+ }
+ else
+ {
+ printk("e820 overflow: leaking RAM %"PRIx64"-%"PRIx64"\n", rs, s);
+ e820->map[i].addr = e;
+ e820->map[i].size = re - e;
+ }
+ }
return 1;
}