...
...
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