[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] linux: Fix mem= kernel parameter when it is smaller than initial memory allocation.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1180000017 -3600
# Node ID 297d98f057e83f37e9aee1177d32eb5fe971710d
# Parent  cc60c18247f1ac16010379b5ee4d1378f705bfc4
linux: Fix mem= kernel parameter when it is smaller than initial memory 
allocation.
From: Chris Lalancette <clalance@xxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c   |   29 +++++++++++++++++++-
 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c |   29 +++++++++++++++++++-
 2 files changed, 56 insertions(+), 2 deletions(-)

diff -r cc60c18247f1 -r 297d98f057e8 
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Thu May 24 10:44:01 
2007 +0100
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Thu May 24 10:46:57 
2007 +0100
@@ -1583,6 +1583,7 @@ void __init setup_arch(char **cmdline_p)
        int i, j, k, fpp;
        struct physdev_set_iopl set_iopl;
        unsigned long max_low_pfn;
+       unsigned long p2m_pages;
 
        /* Force a quick death if the kernel panics (not domain 0). */
        extern int panic_timeout;
@@ -1725,6 +1726,32 @@ void __init setup_arch(char **cmdline_p)
        find_smp_config();
 #endif
 
+       p2m_pages = max_pfn;
+       if (xen_start_info->nr_pages > max_pfn) {
+               /*
+                * the max_pfn was shrunk (probably by mem= or highmem=
+                * kernel parameter); shrink reservation with the HV
+                */
+               struct xen_memory_reservation reservation = {
+                       .address_bits = 0,
+                       .extent_order = 0,
+                       .domid = DOMID_SELF
+               };
+               unsigned int difference;
+               int ret;
+
+               difference = xen_start_info->nr_pages - max_pfn;
+
+               set_xen_guest_handle(reservation.extent_start,
+                                    ((unsigned long 
*)xen_start_info->mfn_list) + max_pfn);
+               reservation.nr_extents = difference;
+               ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+                                          &reservation);
+               BUG_ON (ret != difference);
+       }
+       else if (max_pfn > xen_start_info->nr_pages)
+               p2m_pages = xen_start_info->nr_pages;
+
        /* Make sure we have a correctly sized P->M table. */
        if (!xen_feature(XENFEAT_auto_translated_physmap)) {
                phys_to_machine_mapping = alloc_bootmem_low_pages(
@@ -1733,7 +1760,7 @@ void __init setup_arch(char **cmdline_p)
                       max_pfn * sizeof(unsigned long));
                memcpy(phys_to_machine_mapping,
                       (unsigned long *)xen_start_info->mfn_list,
-                      xen_start_info->nr_pages * sizeof(unsigned long));
+                      p2m_pages * sizeof(unsigned long));
                free_bootmem(
                     __pa(xen_start_info->mfn_list),
                     PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
diff -r cc60c18247f1 -r 297d98f057e8 
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Thu May 24 
10:44:01 2007 +0100
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Thu May 24 
10:46:57 2007 +0100
@@ -792,6 +792,33 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_XEN
        {
                int i, j, k, fpp;
+               unsigned long p2m_pages;
+
+               p2m_pages = end_pfn;
+               if (xen_start_info->nr_pages > end_pfn) {
+                       /*
+                        * the end_pfn was shrunk (probably by mem= or highmem=
+                        * kernel parameter); shrink reservation with the HV
+                        */
+                       struct xen_memory_reservation reservation = {
+                               .address_bits = 0,
+                               .extent_order = 0,
+                               .domid = DOMID_SELF
+                       };
+                       unsigned int difference;
+                       int ret;
+                       
+                       difference = xen_start_info->nr_pages - end_pfn;
+                       
+                       set_xen_guest_handle(reservation.extent_start,
+                                            ((unsigned long 
*)xen_start_info->mfn_list) + end_pfn);
+                       reservation.nr_extents = difference;
+                       ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+                                                  &reservation);
+                       BUG_ON (ret != difference);
+               }
+               else if (end_pfn > xen_start_info->nr_pages)
+                       p2m_pages = xen_start_info->nr_pages;
 
                if (!xen_feature(XENFEAT_auto_translated_physmap)) {
                        /* Make sure we have a large enough P->M table. */
@@ -801,7 +828,7 @@ void __init setup_arch(char **cmdline_p)
                               end_pfn * sizeof(unsigned long));
                        memcpy(phys_to_machine_mapping,
                               (unsigned long *)xen_start_info->mfn_list,
-                              xen_start_info->nr_pages * sizeof(unsigned 
long));
+                              p2m_pages * sizeof(unsigned long));
                        free_bootmem(
                                __pa(xen_start_info->mfn_list),
                                PFN_PHYS(PFN_UP(xen_start_info->nr_pages *

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.