... | ... | ||
---|---|---|---|
16 | dom0 memory target is later adjusted from the toolstack. | 16 | dom0 memory target is later adjusted from the toolstack. |
17 | 17 | ||
18 | Fix this by using xen_released_pages to account for any pages that are part | 18 | Fix this by using xen_released_pages to account for any pages that are part |
19 | of the memory map, but are already unpopulated when the balloon driver is | 19 | of the memory map, but are already unpopulated when the balloon driver is |
20 | initialized. This accounts for any regions used for scratch remote | 20 | initialized. This accounts for any regions used for scratch remote |
21 | mappings. | 21 | mappings. Note on x86 xen_released_pages definition is moved to |
22 | enlighten.c so it's uniformly available for all Xen-enabled builds. | ||
22 | 23 | ||
23 | Take the opportunity to unify PV with PVH/HVM guests regarding the usage of | 24 | Take the opportunity to unify PV with PVH/HVM guests regarding the usage of |
24 | get_num_physpages(), as that avoids having to add different logic for PV vs | 25 | get_num_physpages(), as that avoids having to add different logic for PV vs |
25 | PVH in both balloon_add_regions() and arch_xen_unpopulated_init(). | 26 | PVH in both balloon_add_regions() and arch_xen_unpopulated_init(). |
26 | 27 | ||
27 | Much like a6aa4eb994ee, the code in this changeset should have been part of | 28 | Much like a6aa4eb994ee, the code in this changeset should have been part of |
28 | 38620fc4e893. | 29 | 38620fc4e893. |
29 | 30 | ||
30 | Fixes: a6aa4eb994ee ('xen/x86: add extra pages to unpopulated-alloc if available') | 31 | Fixes: a6aa4eb994ee ('xen/x86: add extra pages to unpopulated-alloc if available') |
31 | Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> | 32 | Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> |
33 | Reviewed-by: Juergen Gross <jgross@suse.com> | ||
34 | Cc: stable@vger.kernel.org | ||
32 | --- | 35 | --- |
33 | I think it's easier to unify the PV and PVH/HVM paths here regarding the | 36 | Changes since v2: |
34 | usage of get_num_physpages(), as otherwise the fix needs to add further PV | 37 | - For x86: Move xen_released_pages definition from setup.c (PV specific) |
35 | vs HVM divergences in both balloon_add_regions() and | 38 | to enlighten.c (shared between all guest modes). |
36 | arch_xen_unpopulated_init(), but it also has a higher risk of breaking PV | 39 | |
37 | in subtle ways. | 40 | Changes since v1: |
41 | - Replace BUG_ON() with a WARN and failure to initialize the balloon | ||
42 | driver. | ||
38 | --- | 43 | --- |
39 | arch/x86/xen/enlighten.c | 7 +++++++ | 44 | arch/x86/xen/enlighten.c | 10 ++++++++++ |
40 | drivers/xen/balloon.c | 19 +++++++++++-------- | 45 | arch/x86/xen/setup.c | 3 --- |
41 | 2 files changed, 18 insertions(+), 8 deletions(-) | 46 | drivers/xen/balloon.c | 34 ++++++++++++++++++++++++---------- |
47 | 3 files changed, 34 insertions(+), 13 deletions(-) | ||
42 | 48 | ||
43 | diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c | 49 | diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c |
44 | index XXXXXXX..XXXXXXX 100644 | 50 | index XXXXXXX..XXXXXXX 100644 |
45 | --- a/arch/x86/xen/enlighten.c | 51 | --- a/arch/x86/xen/enlighten.c |
46 | +++ b/arch/x86/xen/enlighten.c | 52 | +++ b/arch/x86/xen/enlighten.c |
53 | @@ -XXX,XX +XXX,XX @@ EXPORT_SYMBOL(xen_start_flags); | ||
54 | */ | ||
55 | struct shared_info *HYPERVISOR_shared_info = &xen_dummy_shared_info; | ||
56 | |||
57 | +/* Number of pages released from the initial allocation. */ | ||
58 | +unsigned long xen_released_pages; | ||
59 | + | ||
60 | static __ref void xen_get_vendor(void) | ||
61 | { | ||
62 | init_cpu_devs(); | ||
47 | @@ -XXX,XX +XXX,XX @@ int __init arch_xen_unpopulated_init(struct resource **res) | 63 | @@ -XXX,XX +XXX,XX @@ int __init arch_xen_unpopulated_init(struct resource **res) |
48 | xen_free_unpopulated_pages(1, &pg); | 64 | xen_free_unpopulated_pages(1, &pg); |
49 | } | 65 | } |
50 | 66 | ||
51 | + /* | 67 | + /* |
... | ... | ||
56 | + */ | 72 | + */ |
57 | + xen_released_pages += xen_extra_mem[i].n_pfns; | 73 | + xen_released_pages += xen_extra_mem[i].n_pfns; |
58 | /* Zero so region is not also added to the balloon driver. */ | 74 | /* Zero so region is not also added to the balloon driver. */ |
59 | xen_extra_mem[i].n_pfns = 0; | 75 | xen_extra_mem[i].n_pfns = 0; |
60 | } | 76 | } |
77 | diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c | ||
78 | index XXXXXXX..XXXXXXX 100644 | ||
79 | --- a/arch/x86/xen/setup.c | ||
80 | +++ b/arch/x86/xen/setup.c | ||
81 | @@ -XXX,XX +XXX,XX @@ | ||
82 | |||
83 | #define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024) | ||
84 | |||
85 | -/* Number of pages released from the initial allocation. */ | ||
86 | -unsigned long xen_released_pages; | ||
87 | - | ||
88 | /* Memory map would allow PCI passthrough. */ | ||
89 | bool xen_pv_pci_possible; | ||
90 | |||
61 | diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c | 91 | diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c |
62 | index XXXXXXX..XXXXXXX 100644 | 92 | index XXXXXXX..XXXXXXX 100644 |
63 | --- a/drivers/xen/balloon.c | 93 | --- a/drivers/xen/balloon.c |
64 | +++ b/drivers/xen/balloon.c | 94 | +++ b/drivers/xen/balloon.c |
95 | @@ -XXX,XX +XXX,XX @@ void xen_free_ballooned_pages(unsigned int nr_pages, struct page **pages) | ||
96 | } | ||
97 | EXPORT_SYMBOL(xen_free_ballooned_pages); | ||
98 | |||
99 | -static void __init balloon_add_regions(void) | ||
100 | +static int __init balloon_add_regions(void) | ||
101 | { | ||
102 | unsigned long start_pfn, pages; | ||
103 | unsigned long pfn, extra_pfn_end; | ||
65 | @@ -XXX,XX +XXX,XX @@ static void __init balloon_add_regions(void) | 104 | @@ -XXX,XX +XXX,XX @@ static void __init balloon_add_regions(void) |
66 | for (pfn = start_pfn; pfn < extra_pfn_end; pfn++) | 105 | for (pfn = start_pfn; pfn < extra_pfn_end; pfn++) |
67 | balloon_append(pfn_to_page(pfn)); | 106 | balloon_append(pfn_to_page(pfn)); |
68 | 107 | ||
69 | - balloon_stats.total_pages += extra_pfn_end - start_pfn; | 108 | - balloon_stats.total_pages += extra_pfn_end - start_pfn; |
70 | + /* | 109 | + /* |
71 | + * Extra regions are accounted for in the physmap, but need | 110 | + * Extra regions are accounted for in the physmap, but need |
72 | + * decreasing from current_pages to balloon down the initial | 111 | + * decreasing from current_pages to balloon down the initial |
73 | + * allocation, because they are already accounted for in | 112 | + * allocation, because they are already accounted for in |
74 | + * total_pages. | 113 | + * total_pages. |
75 | + */ | 114 | + */ |
76 | + BUG_ON(extra_pfn_end - start_pfn >= | 115 | + if (extra_pfn_end - start_pfn >= balloon_stats.current_pages) { |
77 | + balloon_stats.current_pages); | 116 | + WARN(1, "Extra pages underflow current target"); |
117 | + return -ERANGE; | ||
118 | + } | ||
78 | + balloon_stats.current_pages -= extra_pfn_end - start_pfn; | 119 | + balloon_stats.current_pages -= extra_pfn_end - start_pfn; |
79 | } | 120 | } |
121 | + | ||
122 | + return 0; | ||
80 | } | 123 | } |
81 | 124 | ||
82 | @@ -XXX,XX +XXX,XX @@ static int __init balloon_init(void) | 125 | static int __init balloon_init(void) |
126 | { | ||
127 | struct task_struct *task; | ||
128 | + int rc; | ||
129 | |||
130 | if (!xen_domain()) | ||
131 | return -ENODEV; | ||
83 | 132 | ||
84 | pr_info("Initialising balloon driver\n"); | 133 | pr_info("Initialising balloon driver\n"); |
85 | 134 | ||
86 | -#ifdef CONFIG_XEN_PV | 135 | -#ifdef CONFIG_XEN_PV |
87 | - balloon_stats.current_pages = xen_pv_domain() | 136 | - balloon_stats.current_pages = xen_pv_domain() |
88 | - ? min(xen_start_info->nr_pages - xen_released_pages, max_pfn) | 137 | - ? min(xen_start_info->nr_pages - xen_released_pages, max_pfn) |
89 | - : get_num_physpages(); | 138 | - : get_num_physpages(); |
90 | -#else | 139 | -#else |
91 | - balloon_stats.current_pages = get_num_physpages(); | 140 | - balloon_stats.current_pages = get_num_physpages(); |
92 | -#endif | 141 | -#endif |
93 | + BUG_ON(xen_released_pages >= get_num_physpages()); | 142 | + if (xen_released_pages >= get_num_physpages()) { |
143 | + WARN(1, "Released pages underflow current target"); | ||
144 | + return -ERANGE; | ||
145 | + } | ||
146 | + | ||
94 | + balloon_stats.current_pages = get_num_physpages() - xen_released_pages; | 147 | + balloon_stats.current_pages = get_num_physpages() - xen_released_pages; |
95 | balloon_stats.target_pages = balloon_stats.current_pages; | 148 | balloon_stats.target_pages = balloon_stats.current_pages; |
96 | balloon_stats.balloon_low = 0; | 149 | balloon_stats.balloon_low = 0; |
97 | balloon_stats.balloon_high = 0; | 150 | balloon_stats.balloon_high = 0; |
151 | @@ -XXX,XX +XXX,XX @@ static int __init balloon_init(void) | ||
152 | register_sysctl_init("xen/balloon", balloon_table); | ||
153 | #endif | ||
154 | |||
155 | - balloon_add_regions(); | ||
156 | + rc = balloon_add_regions(); | ||
157 | + if (rc) | ||
158 | + return rc; | ||
159 | |||
160 | task = kthread_run(balloon_thread, NULL, "xen-balloon"); | ||
161 | if (IS_ERR(task)) { | ||
98 | -- | 162 | -- |
99 | 2.48.1 | 163 | 2.48.1 |
100 | 164 | diff view generated by jsdifflib |