On 04/20/2010 04:18 AM, Thomas Schwinge wrote:
> Hello!
>
> On Sat, Apr 10, 2010 at 03:52:45PM -0700, Jeremy Fitzhardinge wrote:
>
>> On 04/10/2010 03:13 PM, Thomas Schwinge wrote:
>>
>>>> Normally that would be OK, because it uses:
>>>>
>>>> __get_user(pfn, &machine_to_phys_mapping[mfn]);
>>>>
>>>> to dereference the array. But at this early stage, none of the kernel's
>>>> exception handlers have been set up, so this will just fault into Xen.
>>>>
>>>> It would be interesting to confirm this by building your kernel with
>>>> CONFIG_DEBUG_INFO=y in the .config, and verify that the faulting
>>>> instruction is actually this line.
>>>>
>>>>
>>> Bingo!
>>>
>> Excellent. Now I just need to work out how to do a proper manual limit
>> check on the mfn. (I've always been a bit suspicious of this code,
>> because there's no guarantee that a random invalid mfn *won't* happen to
>> return the pfn we're looking for...)
>>
> Any news already about this one?
>
Does this help?
J
From: Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx>
Subject: [PATCH] xen/core: don't bother trying to free pages beyond the ones
Xen gave us
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx>
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 8dc1635..9deb6ba 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -78,18 +78,24 @@ static unsigned long __init xen_release_chunk(phys_addr_t
start_addr,
return len;
}
-static unsigned long __init xen_return_unused_memory(const struct e820map
*e820)
+static unsigned long __init xen_return_unused_memory(unsigned long max_pfn,
+ const struct e820map *e820)
{
+ phys_addr_t max_addr = PFN_PHYS(max_pfn);
phys_addr_t last_end = 0;
unsigned long released = 0;
int i;
- for (i = 0; i < e820->nr_map; i++) {
- released += xen_release_chunk(last_end, e820->map[i].addr);
+ for (i = 0; i < e820->nr_map && last_end < max_addr; i++) {
+ phys_addr_t end = e820->map[i].addr;
+ end = min(max_addr, end);
+
+ released += xen_release_chunk(last_end, end);
last_end = e820->map[i].addr + e820->map[i].size;
}
- released += xen_release_chunk(last_end,
PFN_PHYS(xen_start_info->nr_pages));
+ if (last_end < max_addr)
+ released += xen_release_chunk(last_end, max_addr);
printk(KERN_INFO "released %ld pages of unused memory\n", released);
return released;
@@ -129,7 +135,7 @@ char * __init xen_memory_setup(void)
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
- xen_return_unused_memory(&e820);
+ xen_return_unused_memory(xen_start_info->nr_pages, &e820);
return "Xen";
}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|