... | ... | ||
---|---|---|---|
28 | 38620fc4e893. | 28 | 38620fc4e893. |
29 | 29 | ||
30 | Fixes: a6aa4eb994ee ('xen/x86: add extra pages to unpopulated-alloc if available') | 30 | Fixes: a6aa4eb994ee ('xen/x86: add extra pages to unpopulated-alloc if available') |
31 | Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> | 31 | Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> |
32 | --- | 32 | --- |
33 | I think it's easier to unify the PV and PVH/HVM paths here regarding the | 33 | Changes since v1: |
34 | usage of get_num_physpages(), as otherwise the fix needs to add further PV | 34 | - Replace BUG_ON() with a WARN and failure to initialize the balloon |
35 | vs HVM divergences in both balloon_add_regions() and | 35 | driver. |
36 | arch_xen_unpopulated_init(), but it also has a higher risk of breaking PV | ||
37 | in subtle ways. | ||
38 | --- | 36 | --- |
39 | arch/x86/xen/enlighten.c | 7 +++++++ | 37 | arch/x86/xen/enlighten.c | 7 +++++++ |
40 | drivers/xen/balloon.c | 19 +++++++++++-------- | 38 | drivers/xen/balloon.c | 34 ++++++++++++++++++++++++---------- |
41 | 2 files changed, 18 insertions(+), 8 deletions(-) | 39 | 2 files changed, 31 insertions(+), 10 deletions(-) |
42 | 40 | ||
43 | diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c | 41 | diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c |
44 | index XXXXXXX..XXXXXXX 100644 | 42 | index XXXXXXX..XXXXXXX 100644 |
45 | --- a/arch/x86/xen/enlighten.c | 43 | --- a/arch/x86/xen/enlighten.c |
46 | +++ b/arch/x86/xen/enlighten.c | 44 | +++ b/arch/x86/xen/enlighten.c |
... | ... | ||
60 | } | 58 | } |
61 | diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c | 59 | diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c |
62 | index XXXXXXX..XXXXXXX 100644 | 60 | index XXXXXXX..XXXXXXX 100644 |
63 | --- a/drivers/xen/balloon.c | 61 | --- a/drivers/xen/balloon.c |
64 | +++ b/drivers/xen/balloon.c | 62 | +++ b/drivers/xen/balloon.c |
63 | @@ -XXX,XX +XXX,XX @@ void xen_free_ballooned_pages(unsigned int nr_pages, struct page **pages) | ||
64 | } | ||
65 | EXPORT_SYMBOL(xen_free_ballooned_pages); | ||
66 | |||
67 | -static void __init balloon_add_regions(void) | ||
68 | +static int __init balloon_add_regions(void) | ||
69 | { | ||
70 | unsigned long start_pfn, pages; | ||
71 | unsigned long pfn, extra_pfn_end; | ||
65 | @@ -XXX,XX +XXX,XX @@ static void __init balloon_add_regions(void) | 72 | @@ -XXX,XX +XXX,XX @@ static void __init balloon_add_regions(void) |
66 | for (pfn = start_pfn; pfn < extra_pfn_end; pfn++) | 73 | for (pfn = start_pfn; pfn < extra_pfn_end; pfn++) |
67 | balloon_append(pfn_to_page(pfn)); | 74 | balloon_append(pfn_to_page(pfn)); |
68 | 75 | ||
69 | - balloon_stats.total_pages += extra_pfn_end - start_pfn; | 76 | - balloon_stats.total_pages += extra_pfn_end - start_pfn; |
70 | + /* | 77 | + /* |
71 | + * Extra regions are accounted for in the physmap, but need | 78 | + * Extra regions are accounted for in the physmap, but need |
72 | + * decreasing from current_pages to balloon down the initial | 79 | + * decreasing from current_pages to balloon down the initial |
73 | + * allocation, because they are already accounted for in | 80 | + * allocation, because they are already accounted for in |
74 | + * total_pages. | 81 | + * total_pages. |
75 | + */ | 82 | + */ |
76 | + BUG_ON(extra_pfn_end - start_pfn >= | 83 | + if (extra_pfn_end - start_pfn >= balloon_stats.current_pages) { |
77 | + balloon_stats.current_pages); | 84 | + WARN(1, "Extra pages underflow current target"); |
85 | + return -ERANGE; | ||
86 | + } | ||
78 | + balloon_stats.current_pages -= extra_pfn_end - start_pfn; | 87 | + balloon_stats.current_pages -= extra_pfn_end - start_pfn; |
79 | } | 88 | } |
89 | + | ||
90 | + return 0; | ||
80 | } | 91 | } |
81 | 92 | ||
82 | @@ -XXX,XX +XXX,XX @@ static int __init balloon_init(void) | 93 | static int __init balloon_init(void) |
94 | { | ||
95 | struct task_struct *task; | ||
96 | + int rc; | ||
97 | |||
98 | if (!xen_domain()) | ||
99 | return -ENODEV; | ||
83 | 100 | ||
84 | pr_info("Initialising balloon driver\n"); | 101 | pr_info("Initialising balloon driver\n"); |
85 | 102 | ||
86 | -#ifdef CONFIG_XEN_PV | 103 | -#ifdef CONFIG_XEN_PV |
87 | - balloon_stats.current_pages = xen_pv_domain() | 104 | - balloon_stats.current_pages = xen_pv_domain() |
88 | - ? min(xen_start_info->nr_pages - xen_released_pages, max_pfn) | 105 | - ? min(xen_start_info->nr_pages - xen_released_pages, max_pfn) |
89 | - : get_num_physpages(); | 106 | - : get_num_physpages(); |
90 | -#else | 107 | -#else |
91 | - balloon_stats.current_pages = get_num_physpages(); | 108 | - balloon_stats.current_pages = get_num_physpages(); |
92 | -#endif | 109 | -#endif |
93 | + BUG_ON(xen_released_pages >= get_num_physpages()); | 110 | + if (xen_released_pages >= get_num_physpages()) { |
111 | + WARN(1, "Released pages underflow current target"); | ||
112 | + return -ERANGE; | ||
113 | + } | ||
114 | + | ||
94 | + balloon_stats.current_pages = get_num_physpages() - xen_released_pages; | 115 | + balloon_stats.current_pages = get_num_physpages() - xen_released_pages; |
95 | balloon_stats.target_pages = balloon_stats.current_pages; | 116 | balloon_stats.target_pages = balloon_stats.current_pages; |
96 | balloon_stats.balloon_low = 0; | 117 | balloon_stats.balloon_low = 0; |
97 | balloon_stats.balloon_high = 0; | 118 | balloon_stats.balloon_high = 0; |
119 | @@ -XXX,XX +XXX,XX @@ static int __init balloon_init(void) | ||
120 | register_sysctl_init("xen/balloon", balloon_table); | ||
121 | #endif | ||
122 | |||
123 | - balloon_add_regions(); | ||
124 | + rc = balloon_add_regions(); | ||
125 | + if (rc) | ||
126 | + return rc; | ||
127 | |||
128 | task = kthread_run(balloon_thread, NULL, "xen-balloon"); | ||
129 | if (IS_ERR(task)) { | ||
98 | -- | 130 | -- |
99 | 2.48.1 | 131 | 2.48.1 |
100 | 132 | diff view generated by jsdifflib |