aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-05-26 18:31:19 -0400
committerThomas Gleixner <tglx@linutronix.de>2008-05-27 04:11:37 -0400
commit8006ec3e911f93d702e1d4a4e387e244ab434924 (patch)
tree87c4a8648ff2f559ce039bf606fa40e033c48b3c /arch/x86/xen
parentd451bb7aa852627bdf7be7937dc3d9d9f261b235 (diff)
xen: add configurable max domain size
Add a config option to set the max size of a Xen domain. This is used to scale the size of the physical-to-machine array; it ends up using around 1 page/GByte, so there's no reason to be very restrictive. For a 32-bit guest, the default value of 8GB is probably sufficient; there's not much point in giving a 32-bit machine much more memory than that. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/xen')
-rw-r--r--arch/x86/xen/Kconfig10
-rw-r--r--arch/x86/xen/mmu.c25
-rw-r--r--arch/x86/xen/setup.c3
3 files changed, 25 insertions, 13 deletions
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index 525b108411bd..d0f1c7c5dc3d 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -11,3 +11,13 @@ config XEN
11 This is the Linux Xen port. Enabling this will allow the 11 This is the Linux Xen port. Enabling this will allow the
12 kernel to boot in a paravirtualized environment under the 12 kernel to boot in a paravirtualized environment under the
13 Xen hypervisor. 13 Xen hypervisor.
14
15config XEN_MAX_DOMAIN_MEMORY
16 int "Maximum allowed size of a domain in gigabytes"
17 default 8
18 depends on XEN
19 help
20 The pseudo-physical to machine address array is sized
21 according to the maximum possible memory size of a Xen
22 domain. This array uses 1 page per gigabyte, so there's no
23 need to be too stingy here. \ No newline at end of file
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index c3b27dec6f03..644232aa7bfb 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -56,19 +56,13 @@
56#include "multicalls.h" 56#include "multicalls.h"
57#include "mmu.h" 57#include "mmu.h"
58 58
59/*
60 * This should probably be a config option. On 32-bit, it costs 1
61 * page/gig of memory; on 64-bit its 2 pages/gig. If we want it to be
62 * completely unbounded we can add another level to the p2m structure.
63 */
64#define MAX_GUEST_PAGES (16ull * 1024*1024*1024 / PAGE_SIZE)
65#define P2M_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(unsigned long)) 59#define P2M_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(unsigned long))
66 60
67static unsigned long *p2m_top[MAX_GUEST_PAGES / P2M_ENTRIES_PER_PAGE]; 61static unsigned long *p2m_top[MAX_DOMAIN_PAGES / P2M_ENTRIES_PER_PAGE];
68 62
69static inline unsigned p2m_top_index(unsigned long pfn) 63static inline unsigned p2m_top_index(unsigned long pfn)
70{ 64{
71 BUG_ON(pfn >= MAX_GUEST_PAGES); 65 BUG_ON(pfn >= MAX_DOMAIN_PAGES);
72 return pfn / P2M_ENTRIES_PER_PAGE; 66 return pfn / P2M_ENTRIES_PER_PAGE;
73} 67}
74 68
@@ -81,12 +75,9 @@ void __init xen_build_dynamic_phys_to_machine(void)
81{ 75{
82 unsigned pfn; 76 unsigned pfn;
83 unsigned long *mfn_list = (unsigned long *)xen_start_info->mfn_list; 77 unsigned long *mfn_list = (unsigned long *)xen_start_info->mfn_list;
78 unsigned long max_pfn = min(MAX_DOMAIN_PAGES, xen_start_info->nr_pages);
84 79
85 BUG_ON(xen_start_info->nr_pages >= MAX_GUEST_PAGES); 80 for(pfn = 0; pfn < max_pfn; pfn += P2M_ENTRIES_PER_PAGE) {
86
87 for(pfn = 0;
88 pfn < xen_start_info->nr_pages;
89 pfn += P2M_ENTRIES_PER_PAGE) {
90 unsigned topidx = p2m_top_index(pfn); 81 unsigned topidx = p2m_top_index(pfn);
91 82
92 p2m_top[topidx] = &mfn_list[pfn]; 83 p2m_top[topidx] = &mfn_list[pfn];
@@ -97,6 +88,9 @@ unsigned long get_phys_to_machine(unsigned long pfn)
97{ 88{
98 unsigned topidx, idx; 89 unsigned topidx, idx;
99 90
91 if (unlikely(pfn >= MAX_DOMAIN_PAGES))
92 return INVALID_P2M_ENTRY;
93
100 topidx = p2m_top_index(pfn); 94 topidx = p2m_top_index(pfn);
101 if (p2m_top[topidx] == NULL) 95 if (p2m_top[topidx] == NULL)
102 return INVALID_P2M_ENTRY; 96 return INVALID_P2M_ENTRY;
@@ -129,6 +123,11 @@ void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
129 return; 123 return;
130 } 124 }
131 125
126 if (unlikely(pfn >= MAX_DOMAIN_PAGES)) {
127 BUG_ON(mfn != INVALID_P2M_ENTRY);
128 return;
129 }
130
132 topidx = p2m_top_index(pfn); 131 topidx = p2m_top_index(pfn);
133 if (p2m_top[topidx] == NULL) { 132 if (p2m_top[topidx] == NULL) {
134 /* no need to allocate a page to store an invalid entry */ 133 /* no need to allocate a page to store an invalid entry */
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 37f8f0b8f743..488447878a9d 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -16,6 +16,7 @@
16#include <asm/xen/hypervisor.h> 16#include <asm/xen/hypervisor.h>
17#include <asm/xen/hypercall.h> 17#include <asm/xen/hypercall.h>
18 18
19#include <xen/page.h>
19#include <xen/interface/callback.h> 20#include <xen/interface/callback.h>
20#include <xen/interface/physdev.h> 21#include <xen/interface/physdev.h>
21#include <xen/features.h> 22#include <xen/features.h>
@@ -36,6 +37,8 @@ char * __init xen_memory_setup(void)
36{ 37{
37 unsigned long max_pfn = xen_start_info->nr_pages; 38 unsigned long max_pfn = xen_start_info->nr_pages;
38 39
40 max_pfn = min(MAX_DOMAIN_PAGES, max_pfn);
41
39 e820.nr_map = 0; 42 e820.nr_map = 0;
40 add_memory_region(0, LOWMEMSIZE(), E820_RAM); 43 add_memory_region(0, LOWMEMSIZE(), E820_RAM);
41 add_memory_region(HIGH_MEMORY, PFN_PHYS(max_pfn)-HIGH_MEMORY, E820_RAM); 44 add_memory_region(HIGH_MEMORY, PFN_PHYS(max_pfn)-HIGH_MEMORY, E820_RAM);