+81
arch/x86/xen/enlighten.c
+81
arch/x86/xen/enlighten.c
···
1
+
#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
2
+
#include <linux/bootmem.h>
3
+
#endif
1
4
#include <linux/cpu.h>
2
5
#include <linux/kexec.h>
3
6
4
7
#include <xen/features.h>
5
8
#include <xen/page.h>
9
+
#include <xen/interface/memory.h>
6
10
7
11
#include <asm/xen/hypercall.h>
8
12
#include <asm/xen/hypervisor.h>
···
335
331
}
336
332
EXPORT_SYMBOL(xen_arch_unregister_cpu);
337
333
#endif
334
+
335
+
#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
336
+
void __init arch_xen_balloon_init(struct resource *hostmem_resource)
337
+
{
338
+
struct xen_memory_map memmap;
339
+
int rc;
340
+
unsigned int i, last_guest_ram;
341
+
phys_addr_t max_addr = PFN_PHYS(max_pfn);
342
+
struct e820_table *xen_e820_table;
343
+
const struct e820_entry *entry;
344
+
struct resource *res;
345
+
346
+
if (!xen_initial_domain())
347
+
return;
348
+
349
+
xen_e820_table = kmalloc(sizeof(*xen_e820_table), GFP_KERNEL);
350
+
if (!xen_e820_table)
351
+
return;
352
+
353
+
memmap.nr_entries = ARRAY_SIZE(xen_e820_table->entries);
354
+
set_xen_guest_handle(memmap.buffer, xen_e820_table->entries);
355
+
rc = HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap);
356
+
if (rc) {
357
+
pr_warn("%s: Can't read host e820 (%d)\n", __func__, rc);
358
+
goto out;
359
+
}
360
+
361
+
last_guest_ram = 0;
362
+
for (i = 0; i < memmap.nr_entries; i++) {
363
+
if (xen_e820_table->entries[i].addr >= max_addr)
364
+
break;
365
+
if (xen_e820_table->entries[i].type == E820_TYPE_RAM)
366
+
last_guest_ram = i;
367
+
}
368
+
369
+
entry = &xen_e820_table->entries[last_guest_ram];
370
+
if (max_addr >= entry->addr + entry->size)
371
+
goto out; /* No unallocated host RAM. */
372
+
373
+
hostmem_resource->start = max_addr;
374
+
hostmem_resource->end = entry->addr + entry->size;
375
+
376
+
/*
377
+
* Mark non-RAM regions between the end of dom0 RAM and end of host RAM
378
+
* as unavailable. The rest of that region can be used for hotplug-based
379
+
* ballooning.
380
+
*/
381
+
for (; i < memmap.nr_entries; i++) {
382
+
entry = &xen_e820_table->entries[i];
383
+
384
+
if (entry->type == E820_TYPE_RAM)
385
+
continue;
386
+
387
+
if (entry->addr >= hostmem_resource->end)
388
+
break;
389
+
390
+
res = kzalloc(sizeof(*res), GFP_KERNEL);
391
+
if (!res)
392
+
goto out;
393
+
394
+
res->name = "Unavailable host RAM";
395
+
res->start = entry->addr;
396
+
res->end = (entry->addr + entry->size < hostmem_resource->end) ?
397
+
entry->addr + entry->size : hostmem_resource->end;
398
+
rc = insert_resource(hostmem_resource, res);
399
+
if (rc) {
400
+
pr_warn("%s: Can't insert [%llx - %llx) (%d)\n",
401
+
__func__, res->start, res->end, rc);
402
+
kfree(res);
403
+
goto out;
404
+
}
405
+
}
406
+
407
+
out:
408
+
kfree(xen_e820_table);
409
+
}
410
+
#endif /* CONFIG_XEN_BALLOON_MEMORY_HOTPLUG */
+3
arch/x86/xen/enlighten_pv.c
+3
arch/x86/xen/enlighten_pv.c
···
88
88
#include "multicalls.h"
89
89
#include "pmu.h"
90
90
91
+
#include "../kernel/cpu/cpu.h" /* get_cpu_cap() */
92
+
91
93
void *xen_initial_gdt;
92
94
93
95
static int xen_cpu_up_prepare_pv(unsigned int cpu);
···
1260
1258
__userpte_alloc_gfp &= ~__GFP_HIGHMEM;
1261
1259
1262
1260
/* Work out if we support NX */
1261
+
get_cpu_cap(&boot_cpu_data);
1263
1262
x86_configure_nx();
1264
1263
1265
1264
/* Get mfn list */
+12
arch/x86/xen/mmu_pv.c
+12
arch/x86/xen/mmu_pv.c
···
1902
1902
/* Graft it onto L4[511][510] */
1903
1903
copy_page(level2_kernel_pgt, l2);
1904
1904
1905
+
/*
1906
+
* Zap execute permission from the ident map. Due to the sharing of
1907
+
* L1 entries we need to do this in the L2.
1908
+
*/
1909
+
if (__supported_pte_mask & _PAGE_NX) {
1910
+
for (i = 0; i < PTRS_PER_PMD; ++i) {
1911
+
if (pmd_none(level2_ident_pgt[i]))
1912
+
continue;
1913
+
level2_ident_pgt[i] = pmd_set_flags(level2_ident_pgt[i], _PAGE_NX);
1914
+
}
1915
+
}
1916
+
1905
1917
/* Copy the initial P->M table mappings if necessary. */
1906
1918
i = pgd_index(xen_start_info->mfn_list);
1907
1919
if (i && i < pgd_index(__START_KERNEL_map))
+2
-4
arch/x86/xen/setup.c
+2
-4
arch/x86/xen/setup.c
···
808
808
addr = xen_e820_table.entries[0].addr;
809
809
size = xen_e820_table.entries[0].size;
810
810
while (i < xen_e820_table.nr_entries) {
811
-
bool discard = false;
812
811
813
812
chunk_size = size;
814
813
type = xen_e820_table.entries[i].type;
···
823
824
xen_add_extra_mem(pfn_s, n_pfns);
824
825
xen_max_p2m_pfn = pfn_s + n_pfns;
825
826
} else
826
-
discard = true;
827
+
type = E820_TYPE_UNUSABLE;
827
828
}
828
829
829
-
if (!discard)
830
-
xen_align_and_add_e820_region(addr, chunk_size, type);
830
+
xen_align_and_add_e820_region(addr, chunk_size, type);
831
831
832
832
addr += chunk_size;
833
833
size -= chunk_size;
+56
-9
drivers/xen/balloon.c
+56
-9
drivers/xen/balloon.c
···
257
257
kfree(resource);
258
258
}
259
259
260
+
/*
261
+
* Host memory not allocated to dom0. We can use this range for hotplug-based
262
+
* ballooning.
263
+
*
264
+
* It's a type-less resource. Setting IORESOURCE_MEM will make resource
265
+
* management algorithms (arch_remove_reservations()) look into guest e820,
266
+
* which we don't want.
267
+
*/
268
+
static struct resource hostmem_resource = {
269
+
.name = "Host RAM",
270
+
};
271
+
272
+
void __attribute__((weak)) __init arch_xen_balloon_init(struct resource *res)
273
+
{}
274
+
260
275
static struct resource *additional_memory_resource(phys_addr_t size)
261
276
{
262
-
struct resource *res;
263
-
int ret;
277
+
struct resource *res, *res_hostmem;
278
+
int ret = -ENOMEM;
264
279
265
280
res = kzalloc(sizeof(*res), GFP_KERNEL);
266
281
if (!res)
···
284
269
res->name = "System RAM";
285
270
res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
286
271
287
-
ret = allocate_resource(&iomem_resource, res,
288
-
size, 0, -1,
289
-
PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL);
290
-
if (ret < 0) {
291
-
pr_err("Cannot allocate new System RAM resource\n");
292
-
kfree(res);
293
-
return NULL;
272
+
res_hostmem = kzalloc(sizeof(*res), GFP_KERNEL);
273
+
if (res_hostmem) {
274
+
/* Try to grab a range from hostmem */
275
+
res_hostmem->name = "Host memory";
276
+
ret = allocate_resource(&hostmem_resource, res_hostmem,
277
+
size, 0, -1,
278
+
PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL);
279
+
}
280
+
281
+
if (!ret) {
282
+
/*
283
+
* Insert this resource into iomem. Because hostmem_resource
284
+
* tracks portion of guest e820 marked as UNUSABLE noone else
285
+
* should try to use it.
286
+
*/
287
+
res->start = res_hostmem->start;
288
+
res->end = res_hostmem->end;
289
+
ret = insert_resource(&iomem_resource, res);
290
+
if (ret < 0) {
291
+
pr_err("Can't insert iomem_resource [%llx - %llx]\n",
292
+
res->start, res->end);
293
+
release_memory_resource(res_hostmem);
294
+
res_hostmem = NULL;
295
+
res->start = res->end = 0;
296
+
}
297
+
}
298
+
299
+
if (ret) {
300
+
ret = allocate_resource(&iomem_resource, res,
301
+
size, 0, -1,
302
+
PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL);
303
+
if (ret < 0) {
304
+
pr_err("Cannot allocate new System RAM resource\n");
305
+
kfree(res);
306
+
return NULL;
307
+
}
294
308
}
295
309
296
310
#ifdef CONFIG_SPARSEMEM
···
331
287
pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n",
332
288
pfn, limit);
333
289
release_memory_resource(res);
290
+
release_memory_resource(res_hostmem);
334
291
return NULL;
335
292
}
336
293
}
···
810
765
set_online_page_callback(&xen_online_page);
811
766
register_memory_notifier(&xen_memory_nb);
812
767
register_sysctl_table(xen_root);
768
+
769
+
arch_xen_balloon_init(&hostmem_resource);
813
770
#endif
814
771
815
772
#ifdef CONFIG_XEN_PV