0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/init.h>
0009 #include <linux/sched.h>
0010 #include <linux/mm.h>
0011 #include <linux/pm.h>
0012 #include <linux/memblock.h>
0013 #include <linux/cpuidle.h>
0014 #include <linux/cpufreq.h>
0015 #include <linux/memory_hotplug.h>
0016
0017 #include <asm/elf.h>
0018 #include <asm/vdso.h>
0019 #include <asm/e820/api.h>
0020 #include <asm/setup.h>
0021 #include <asm/acpi.h>
0022 #include <asm/numa.h>
0023 #include <asm/idtentry.h>
0024 #include <asm/xen/hypervisor.h>
0025 #include <asm/xen/hypercall.h>
0026
0027 #include <xen/xen.h>
0028 #include <xen/page.h>
0029 #include <xen/interface/callback.h>
0030 #include <xen/interface/memory.h>
0031 #include <xen/interface/physdev.h>
0032 #include <xen/features.h>
0033 #include <xen/hvc-console.h>
0034 #include "xen-ops.h"
0035 #include "mmu.h"
0036
0037 #define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024)
0038
0039
0040 struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
0041
0042
0043 unsigned long xen_released_pages;
0044
0045
0046 static struct e820_table xen_e820_table __initdata;
0047
0048
0049
0050
0051
0052
0053 #define REMAP_SIZE (P2M_PER_PAGE - 3)
0054 static struct {
0055 unsigned long next_area_mfn;
0056 unsigned long target_pfn;
0057 unsigned long size;
0058 unsigned long mfns[REMAP_SIZE];
0059 } xen_remap_buf __initdata __aligned(PAGE_SIZE);
0060 static unsigned long xen_remap_mfn __initdata = INVALID_P2M_ENTRY;
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 #define EXTRA_MEM_RATIO (10)
0073
0074 static bool xen_512gb_limit __initdata = IS_ENABLED(CONFIG_XEN_512GB);
0075
0076 static void __init xen_parse_512gb(void)
0077 {
0078 bool val = false;
0079 char *arg;
0080
0081 arg = strstr(xen_start_info->cmd_line, "xen_512gb_limit");
0082 if (!arg)
0083 return;
0084
0085 arg = strstr(xen_start_info->cmd_line, "xen_512gb_limit=");
0086 if (!arg)
0087 val = true;
0088 else if (strtobool(arg + strlen("xen_512gb_limit="), &val))
0089 return;
0090
0091 xen_512gb_limit = val;
0092 }
0093
0094 static void __init xen_add_extra_mem(unsigned long start_pfn,
0095 unsigned long n_pfns)
0096 {
0097 int i;
0098
0099
0100
0101
0102
0103 for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
0104
0105 if (xen_extra_mem[i].n_pfns == 0) {
0106 xen_extra_mem[i].start_pfn = start_pfn;
0107 xen_extra_mem[i].n_pfns = n_pfns;
0108 break;
0109 }
0110
0111 if (xen_extra_mem[i].start_pfn + xen_extra_mem[i].n_pfns ==
0112 start_pfn) {
0113 xen_extra_mem[i].n_pfns += n_pfns;
0114 break;
0115 }
0116 }
0117 if (i == XEN_EXTRA_MEM_MAX_REGIONS)
0118 printk(KERN_WARNING "Warning: not enough extra memory regions\n");
0119
0120 memblock_reserve(PFN_PHYS(start_pfn), PFN_PHYS(n_pfns));
0121 }
0122
0123 static void __init xen_del_extra_mem(unsigned long start_pfn,
0124 unsigned long n_pfns)
0125 {
0126 int i;
0127 unsigned long start_r, size_r;
0128
0129 for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
0130 start_r = xen_extra_mem[i].start_pfn;
0131 size_r = xen_extra_mem[i].n_pfns;
0132
0133
0134 if (start_r == start_pfn) {
0135 BUG_ON(n_pfns > size_r);
0136 xen_extra_mem[i].start_pfn += n_pfns;
0137 xen_extra_mem[i].n_pfns -= n_pfns;
0138 break;
0139 }
0140
0141 if (start_r + size_r == start_pfn + n_pfns) {
0142 BUG_ON(n_pfns > size_r);
0143 xen_extra_mem[i].n_pfns -= n_pfns;
0144 break;
0145 }
0146
0147 if (start_pfn > start_r && start_pfn < start_r + size_r) {
0148 BUG_ON(start_pfn + n_pfns > start_r + size_r);
0149 xen_extra_mem[i].n_pfns = start_pfn - start_r;
0150
0151 xen_add_extra_mem(start_pfn + n_pfns, start_r + size_r -
0152 (start_pfn + n_pfns));
0153 break;
0154 }
0155 }
0156 memblock_phys_free(PFN_PHYS(start_pfn), PFN_PHYS(n_pfns));
0157 }
0158
0159
0160
0161
0162
0163
0164 unsigned long __ref xen_chk_extra_mem(unsigned long pfn)
0165 {
0166 int i;
0167
0168 for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
0169 if (pfn >= xen_extra_mem[i].start_pfn &&
0170 pfn < xen_extra_mem[i].start_pfn + xen_extra_mem[i].n_pfns)
0171 return INVALID_P2M_ENTRY;
0172 }
0173
0174 return IDENTITY_FRAME(pfn);
0175 }
0176
0177
0178
0179
0180 void __init xen_inv_extra_mem(void)
0181 {
0182 unsigned long pfn, pfn_s, pfn_e;
0183 int i;
0184
0185 for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
0186 if (!xen_extra_mem[i].n_pfns)
0187 continue;
0188 pfn_s = xen_extra_mem[i].start_pfn;
0189 pfn_e = pfn_s + xen_extra_mem[i].n_pfns;
0190 for (pfn = pfn_s; pfn < pfn_e; pfn++)
0191 set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
0192 }
0193 }
0194
0195
0196
0197
0198
0199
0200 static unsigned long __init xen_find_pfn_range(unsigned long *min_pfn)
0201 {
0202 const struct e820_entry *entry = xen_e820_table.entries;
0203 unsigned int i;
0204 unsigned long done = 0;
0205
0206 for (i = 0; i < xen_e820_table.nr_entries; i++, entry++) {
0207 unsigned long s_pfn;
0208 unsigned long e_pfn;
0209
0210 if (entry->type != E820_TYPE_RAM)
0211 continue;
0212
0213 e_pfn = PFN_DOWN(entry->addr + entry->size);
0214
0215
0216 if (e_pfn <= *min_pfn)
0217 continue;
0218
0219 s_pfn = PFN_UP(entry->addr);
0220
0221
0222
0223
0224 if (s_pfn <= *min_pfn) {
0225 done = e_pfn - *min_pfn;
0226 } else {
0227 done = e_pfn - s_pfn;
0228 *min_pfn = s_pfn;
0229 }
0230 break;
0231 }
0232
0233 return done;
0234 }
0235
0236 static int __init xen_free_mfn(unsigned long mfn)
0237 {
0238 struct xen_memory_reservation reservation = {
0239 .address_bits = 0,
0240 .extent_order = 0,
0241 .domid = DOMID_SELF
0242 };
0243
0244 set_xen_guest_handle(reservation.extent_start, &mfn);
0245 reservation.nr_extents = 1;
0246
0247 return HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
0248 }
0249
0250
0251
0252
0253
0254 static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn,
0255 unsigned long end_pfn, unsigned long nr_pages)
0256 {
0257 unsigned long pfn, end;
0258 int ret;
0259
0260 WARN_ON(start_pfn > end_pfn);
0261
0262
0263 end = min(end_pfn, nr_pages);
0264 for (pfn = start_pfn; pfn < end; pfn++) {
0265 unsigned long mfn = pfn_to_mfn(pfn);
0266
0267
0268 if (mfn == INVALID_P2M_ENTRY || mfn_to_pfn(mfn) != pfn)
0269 continue;
0270
0271 ret = xen_free_mfn(mfn);
0272 WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret);
0273
0274 if (ret == 1) {
0275 xen_released_pages++;
0276 if (!__set_phys_to_machine(pfn, INVALID_P2M_ENTRY))
0277 break;
0278 } else
0279 break;
0280 }
0281
0282 set_phys_range_identity(start_pfn, end_pfn);
0283 }
0284
0285
0286
0287
0288 static void __init xen_update_mem_tables(unsigned long pfn, unsigned long mfn)
0289 {
0290 struct mmu_update update = {
0291 .ptr = ((uint64_t)mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE,
0292 .val = pfn
0293 };
0294
0295
0296 if (!set_phys_to_machine(pfn, mfn)) {
0297 WARN(1, "Failed to set p2m mapping for pfn=%ld mfn=%ld\n",
0298 pfn, mfn);
0299 BUG();
0300 }
0301
0302
0303 if (HYPERVISOR_mmu_update(&update, 1, NULL, DOMID_SELF) < 0) {
0304 WARN(1, "Failed to set m2p mapping for mfn=%ld pfn=%ld\n",
0305 mfn, pfn);
0306 BUG();
0307 }
0308
0309 if (HYPERVISOR_update_va_mapping((unsigned long)__va(pfn << PAGE_SHIFT),
0310 mfn_pte(mfn, PAGE_KERNEL), 0)) {
0311 WARN(1, "Failed to update kernel mapping for mfn=%ld pfn=%ld\n",
0312 mfn, pfn);
0313 BUG();
0314 }
0315 }
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329 static void __init xen_do_set_identity_and_remap_chunk(
0330 unsigned long start_pfn, unsigned long size, unsigned long remap_pfn)
0331 {
0332 unsigned long buf = (unsigned long)&xen_remap_buf;
0333 unsigned long mfn_save, mfn;
0334 unsigned long ident_pfn_iter, remap_pfn_iter;
0335 unsigned long ident_end_pfn = start_pfn + size;
0336 unsigned long left = size;
0337 unsigned int i, chunk;
0338
0339 WARN_ON(size == 0);
0340
0341 mfn_save = virt_to_mfn(buf);
0342
0343 for (ident_pfn_iter = start_pfn, remap_pfn_iter = remap_pfn;
0344 ident_pfn_iter < ident_end_pfn;
0345 ident_pfn_iter += REMAP_SIZE, remap_pfn_iter += REMAP_SIZE) {
0346 chunk = (left < REMAP_SIZE) ? left : REMAP_SIZE;
0347
0348
0349 mfn = pfn_to_mfn(ident_pfn_iter);
0350 set_pte_mfn(buf, mfn, PAGE_KERNEL);
0351
0352
0353 xen_remap_buf.next_area_mfn = xen_remap_mfn;
0354 xen_remap_buf.target_pfn = remap_pfn_iter;
0355 xen_remap_buf.size = chunk;
0356 for (i = 0; i < chunk; i++)
0357 xen_remap_buf.mfns[i] = pfn_to_mfn(ident_pfn_iter + i);
0358
0359
0360 xen_remap_mfn = mfn;
0361
0362
0363 set_phys_range_identity(ident_pfn_iter, ident_pfn_iter + chunk);
0364
0365 left -= chunk;
0366 }
0367
0368
0369 set_pte_mfn(buf, mfn_save, PAGE_KERNEL);
0370 }
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383 static unsigned long __init xen_set_identity_and_remap_chunk(
0384 unsigned long start_pfn, unsigned long end_pfn, unsigned long nr_pages,
0385 unsigned long remap_pfn)
0386 {
0387 unsigned long pfn;
0388 unsigned long i = 0;
0389 unsigned long n = end_pfn - start_pfn;
0390
0391 if (remap_pfn == 0)
0392 remap_pfn = nr_pages;
0393
0394 while (i < n) {
0395 unsigned long cur_pfn = start_pfn + i;
0396 unsigned long left = n - i;
0397 unsigned long size = left;
0398 unsigned long remap_range_size;
0399
0400
0401 if (cur_pfn >= nr_pages) {
0402
0403 set_phys_range_identity(cur_pfn, cur_pfn + size);
0404 break;
0405 }
0406 if (cur_pfn + size > nr_pages)
0407 size = nr_pages - cur_pfn;
0408
0409 remap_range_size = xen_find_pfn_range(&remap_pfn);
0410 if (!remap_range_size) {
0411 pr_warn("Unable to find available pfn range, not remapping identity pages\n");
0412 xen_set_identity_and_release_chunk(cur_pfn,
0413 cur_pfn + left, nr_pages);
0414 break;
0415 }
0416
0417 if (size > remap_range_size)
0418 size = remap_range_size;
0419
0420 xen_do_set_identity_and_remap_chunk(cur_pfn, size, remap_pfn);
0421
0422
0423 i += size;
0424 remap_pfn += size;
0425 }
0426
0427
0428
0429
0430
0431 for (pfn = start_pfn; pfn <= max_pfn_mapped && pfn < end_pfn; pfn++)
0432 (void)HYPERVISOR_update_va_mapping(
0433 (unsigned long)__va(pfn << PAGE_SHIFT),
0434 native_make_pte(0), 0);
0435
0436 return remap_pfn;
0437 }
0438
0439 static unsigned long __init xen_count_remap_pages(
0440 unsigned long start_pfn, unsigned long end_pfn, unsigned long nr_pages,
0441 unsigned long remap_pages)
0442 {
0443 if (start_pfn >= nr_pages)
0444 return remap_pages;
0445
0446 return remap_pages + min(end_pfn, nr_pages) - start_pfn;
0447 }
0448
0449 static unsigned long __init xen_foreach_remap_area(unsigned long nr_pages,
0450 unsigned long (*func)(unsigned long start_pfn, unsigned long end_pfn,
0451 unsigned long nr_pages, unsigned long last_val))
0452 {
0453 phys_addr_t start = 0;
0454 unsigned long ret_val = 0;
0455 const struct e820_entry *entry = xen_e820_table.entries;
0456 int i;
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469 for (i = 0; i < xen_e820_table.nr_entries; i++, entry++) {
0470 phys_addr_t end = entry->addr + entry->size;
0471 if (entry->type == E820_TYPE_RAM || i == xen_e820_table.nr_entries - 1) {
0472 unsigned long start_pfn = PFN_DOWN(start);
0473 unsigned long end_pfn = PFN_UP(end);
0474
0475 if (entry->type == E820_TYPE_RAM)
0476 end_pfn = PFN_UP(entry->addr);
0477
0478 if (start_pfn < end_pfn)
0479 ret_val = func(start_pfn, end_pfn, nr_pages,
0480 ret_val);
0481 start = end;
0482 }
0483 }
0484
0485 return ret_val;
0486 }
0487
0488
0489
0490
0491
0492
0493
0494
0495 void __init xen_remap_memory(void)
0496 {
0497 unsigned long buf = (unsigned long)&xen_remap_buf;
0498 unsigned long mfn_save, pfn;
0499 unsigned long remapped = 0;
0500 unsigned int i;
0501 unsigned long pfn_s = ~0UL;
0502 unsigned long len = 0;
0503
0504 mfn_save = virt_to_mfn(buf);
0505
0506 while (xen_remap_mfn != INVALID_P2M_ENTRY) {
0507
0508 set_pte_mfn(buf, xen_remap_mfn, PAGE_KERNEL);
0509
0510 BUG_ON(xen_remap_mfn != xen_remap_buf.mfns[0]);
0511
0512 pfn = xen_remap_buf.target_pfn;
0513 for (i = 0; i < xen_remap_buf.size; i++) {
0514 xen_update_mem_tables(pfn, xen_remap_buf.mfns[i]);
0515 remapped++;
0516 pfn++;
0517 }
0518 if (pfn_s == ~0UL || pfn == pfn_s) {
0519 pfn_s = xen_remap_buf.target_pfn;
0520 len += xen_remap_buf.size;
0521 } else if (pfn_s + len == xen_remap_buf.target_pfn) {
0522 len += xen_remap_buf.size;
0523 } else {
0524 xen_del_extra_mem(pfn_s, len);
0525 pfn_s = xen_remap_buf.target_pfn;
0526 len = xen_remap_buf.size;
0527 }
0528 xen_remap_mfn = xen_remap_buf.next_area_mfn;
0529 }
0530
0531 if (pfn_s != ~0UL && len)
0532 xen_del_extra_mem(pfn_s, len);
0533
0534 set_pte_mfn(buf, mfn_save, PAGE_KERNEL);
0535
0536 pr_info("Remapped %ld page(s)\n", remapped);
0537 }
0538
0539 static unsigned long __init xen_get_pages_limit(void)
0540 {
0541 unsigned long limit;
0542
0543 limit = MAXMEM / PAGE_SIZE;
0544 if (!xen_initial_domain() && xen_512gb_limit)
0545 limit = GB(512) / PAGE_SIZE;
0546
0547 return limit;
0548 }
0549
0550 static unsigned long __init xen_get_max_pages(void)
0551 {
0552 unsigned long max_pages, limit;
0553 domid_t domid = DOMID_SELF;
0554 long ret;
0555
0556 limit = xen_get_pages_limit();
0557 max_pages = limit;
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568 if (xen_initial_domain()) {
0569 ret = HYPERVISOR_memory_op(XENMEM_maximum_reservation, &domid);
0570 if (ret > 0)
0571 max_pages = ret;
0572 }
0573
0574 return min(max_pages, limit);
0575 }
0576
0577 static void __init xen_align_and_add_e820_region(phys_addr_t start,
0578 phys_addr_t size, int type)
0579 {
0580 phys_addr_t end = start + size;
0581
0582
0583 if (type == E820_TYPE_RAM) {
0584 start = PAGE_ALIGN(start);
0585 end &= ~((phys_addr_t)PAGE_SIZE - 1);
0586 #ifdef CONFIG_MEMORY_HOTPLUG
0587
0588
0589
0590
0591
0592 max_mem_size = end;
0593 #endif
0594 }
0595
0596 e820__range_add(start, end - start, type);
0597 }
0598
0599 static void __init xen_ignore_unusable(void)
0600 {
0601 struct e820_entry *entry = xen_e820_table.entries;
0602 unsigned int i;
0603
0604 for (i = 0; i < xen_e820_table.nr_entries; i++, entry++) {
0605 if (entry->type == E820_TYPE_UNUSABLE)
0606 entry->type = E820_TYPE_RAM;
0607 }
0608 }
0609
0610 bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
0611 {
0612 struct e820_entry *entry;
0613 unsigned mapcnt;
0614 phys_addr_t end;
0615
0616 if (!size)
0617 return false;
0618
0619 end = start + size;
0620 entry = xen_e820_table.entries;
0621
0622 for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++) {
0623 if (entry->type == E820_TYPE_RAM && entry->addr <= start &&
0624 (entry->addr + entry->size) >= end)
0625 return false;
0626
0627 entry++;
0628 }
0629
0630 return true;
0631 }
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641 phys_addr_t __init xen_find_free_area(phys_addr_t size)
0642 {
0643 unsigned mapcnt;
0644 phys_addr_t addr, start;
0645 struct e820_entry *entry = xen_e820_table.entries;
0646
0647 for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++, entry++) {
0648 if (entry->type != E820_TYPE_RAM || entry->size < size)
0649 continue;
0650 start = entry->addr;
0651 for (addr = start; addr < start + size; addr += PAGE_SIZE) {
0652 if (!memblock_is_reserved(addr))
0653 continue;
0654 start = addr + PAGE_SIZE;
0655 if (start + size > entry->addr + entry->size)
0656 break;
0657 }
0658 if (addr >= start + size) {
0659 memblock_reserve(start, size);
0660 return start;
0661 }
0662 }
0663
0664 return 0;
0665 }
0666
0667
0668
0669
0670 static void __init xen_phys_memcpy(phys_addr_t dest, phys_addr_t src,
0671 phys_addr_t n)
0672 {
0673 phys_addr_t dest_off, src_off, dest_len, src_len, len;
0674 void *from, *to;
0675
0676 while (n) {
0677 dest_off = dest & ~PAGE_MASK;
0678 src_off = src & ~PAGE_MASK;
0679 dest_len = n;
0680 if (dest_len > (NR_FIX_BTMAPS << PAGE_SHIFT) - dest_off)
0681 dest_len = (NR_FIX_BTMAPS << PAGE_SHIFT) - dest_off;
0682 src_len = n;
0683 if (src_len > (NR_FIX_BTMAPS << PAGE_SHIFT) - src_off)
0684 src_len = (NR_FIX_BTMAPS << PAGE_SHIFT) - src_off;
0685 len = min(dest_len, src_len);
0686 to = early_memremap(dest - dest_off, dest_len + dest_off);
0687 from = early_memremap(src - src_off, src_len + src_off);
0688 memcpy(to, from, len);
0689 early_memunmap(to, dest_len + dest_off);
0690 early_memunmap(from, src_len + src_off);
0691 n -= len;
0692 dest += len;
0693 src += len;
0694 }
0695 }
0696
0697
0698
0699
0700 static void __init xen_reserve_xen_mfnlist(void)
0701 {
0702 phys_addr_t start, size;
0703
0704 if (xen_start_info->mfn_list >= __START_KERNEL_map) {
0705 start = __pa(xen_start_info->mfn_list);
0706 size = PFN_ALIGN(xen_start_info->nr_pages *
0707 sizeof(unsigned long));
0708 } else {
0709 start = PFN_PHYS(xen_start_info->first_p2m_pfn);
0710 size = PFN_PHYS(xen_start_info->nr_p2m_frames);
0711 }
0712
0713 memblock_reserve(start, size);
0714 if (!xen_is_e820_reserved(start, size))
0715 return;
0716
0717 xen_relocate_p2m();
0718 memblock_phys_free(start, size);
0719 }
0720
0721
0722
0723
0724 char * __init xen_memory_setup(void)
0725 {
0726 unsigned long max_pfn, pfn_s, n_pfns;
0727 phys_addr_t mem_end, addr, size, chunk_size;
0728 u32 type;
0729 int rc;
0730 struct xen_memory_map memmap;
0731 unsigned long max_pages;
0732 unsigned long extra_pages = 0;
0733 int i;
0734 int op;
0735
0736 xen_parse_512gb();
0737 max_pfn = xen_get_pages_limit();
0738 max_pfn = min(max_pfn, xen_start_info->nr_pages);
0739 mem_end = PFN_PHYS(max_pfn);
0740
0741 memmap.nr_entries = ARRAY_SIZE(xen_e820_table.entries);
0742 set_xen_guest_handle(memmap.buffer, xen_e820_table.entries);
0743
0744 #if defined(CONFIG_MEMORY_HOTPLUG) && defined(CONFIG_XEN_BALLOON)
0745 xen_saved_max_mem_size = max_mem_size;
0746 #endif
0747
0748 op = xen_initial_domain() ?
0749 XENMEM_machine_memory_map :
0750 XENMEM_memory_map;
0751 rc = HYPERVISOR_memory_op(op, &memmap);
0752 if (rc == -ENOSYS) {
0753 BUG_ON(xen_initial_domain());
0754 memmap.nr_entries = 1;
0755 xen_e820_table.entries[0].addr = 0ULL;
0756 xen_e820_table.entries[0].size = mem_end;
0757
0758 xen_e820_table.entries[0].size += 8ULL << 20;
0759 xen_e820_table.entries[0].type = E820_TYPE_RAM;
0760 rc = 0;
0761 }
0762 BUG_ON(rc);
0763 BUG_ON(memmap.nr_entries == 0);
0764 xen_e820_table.nr_entries = memmap.nr_entries;
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774 if (xen_initial_domain())
0775 xen_ignore_unusable();
0776
0777
0778 e820__update_table(&xen_e820_table);
0779
0780 max_pages = xen_get_max_pages();
0781
0782
0783 max_pages += xen_foreach_remap_area(max_pfn, xen_count_remap_pages);
0784
0785 if (max_pages > max_pfn)
0786 extra_pages += max_pages - max_pfn;
0787
0788
0789
0790
0791
0792
0793
0794
0795 extra_pages = min3(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)),
0796 extra_pages, max_pages - max_pfn);
0797 i = 0;
0798 addr = xen_e820_table.entries[0].addr;
0799 size = xen_e820_table.entries[0].size;
0800 while (i < xen_e820_table.nr_entries) {
0801 bool discard = false;
0802
0803 chunk_size = size;
0804 type = xen_e820_table.entries[i].type;
0805
0806 if (type == E820_TYPE_RAM) {
0807 if (addr < mem_end) {
0808 chunk_size = min(size, mem_end - addr);
0809 } else if (extra_pages) {
0810 chunk_size = min(size, PFN_PHYS(extra_pages));
0811 pfn_s = PFN_UP(addr);
0812 n_pfns = PFN_DOWN(addr + chunk_size) - pfn_s;
0813 extra_pages -= n_pfns;
0814 xen_add_extra_mem(pfn_s, n_pfns);
0815 xen_max_p2m_pfn = pfn_s + n_pfns;
0816 } else
0817 discard = true;
0818 }
0819
0820 if (!discard)
0821 xen_align_and_add_e820_region(addr, chunk_size, type);
0822
0823 addr += chunk_size;
0824 size -= chunk_size;
0825 if (size == 0) {
0826 i++;
0827 if (i < xen_e820_table.nr_entries) {
0828 addr = xen_e820_table.entries[i].addr;
0829 size = xen_e820_table.entries[i].size;
0830 }
0831 }
0832 }
0833
0834
0835
0836
0837
0838 set_phys_range_identity(addr / PAGE_SIZE, ~0ul);
0839
0840
0841
0842
0843
0844
0845 e820__range_add(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, E820_TYPE_RESERVED);
0846
0847 e820__update_table(e820_table);
0848
0849
0850
0851
0852
0853
0854 if (xen_is_e820_reserved(__pa_symbol(_text),
0855 __pa_symbol(__bss_stop) - __pa_symbol(_text))) {
0856 xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n");
0857 BUG();
0858 }
0859
0860
0861
0862
0863
0864 xen_pt_check_e820();
0865
0866 xen_reserve_xen_mfnlist();
0867
0868
0869 if (xen_is_e820_reserved(boot_params.hdr.ramdisk_image,
0870 boot_params.hdr.ramdisk_size)) {
0871 phys_addr_t new_area, start, size;
0872
0873 new_area = xen_find_free_area(boot_params.hdr.ramdisk_size);
0874 if (!new_area) {
0875 xen_raw_console_write("Can't find new memory area for initrd needed due to E820 map conflict\n");
0876 BUG();
0877 }
0878
0879 start = boot_params.hdr.ramdisk_image;
0880 size = boot_params.hdr.ramdisk_size;
0881 xen_phys_memcpy(new_area, start, size);
0882 pr_info("initrd moved from [mem %#010llx-%#010llx] to [mem %#010llx-%#010llx]\n",
0883 start, start + size, new_area, new_area + size);
0884 memblock_phys_free(start, size);
0885 boot_params.hdr.ramdisk_image = new_area;
0886 boot_params.ext_ramdisk_image = new_area >> 32;
0887 }
0888
0889
0890
0891
0892
0893 xen_foreach_remap_area(max_pfn, xen_set_identity_and_remap_chunk);
0894
0895 pr_info("Released %ld page(s)\n", xen_released_pages);
0896
0897 return "Xen";
0898 }
0899
0900 static int register_callback(unsigned type, const void *func)
0901 {
0902 struct callback_register callback = {
0903 .type = type,
0904 .address = XEN_CALLBACK(__KERNEL_CS, func),
0905 .flags = CALLBACKF_mask_events,
0906 };
0907
0908 return HYPERVISOR_callback_op(CALLBACKOP_register, &callback);
0909 }
0910
0911 void xen_enable_sysenter(void)
0912 {
0913 int ret;
0914 unsigned sysenter_feature;
0915
0916 sysenter_feature = X86_FEATURE_SYSENTER32;
0917
0918 if (!boot_cpu_has(sysenter_feature))
0919 return;
0920
0921 ret = register_callback(CALLBACKTYPE_sysenter, xen_entry_SYSENTER_compat);
0922 if(ret != 0)
0923 setup_clear_cpu_cap(sysenter_feature);
0924 }
0925
0926 void xen_enable_syscall(void)
0927 {
0928 int ret;
0929
0930 ret = register_callback(CALLBACKTYPE_syscall, xen_entry_SYSCALL_64);
0931 if (ret != 0) {
0932 printk(KERN_ERR "Failed to set syscall callback: %d\n", ret);
0933
0934
0935 }
0936
0937 if (boot_cpu_has(X86_FEATURE_SYSCALL32)) {
0938 ret = register_callback(CALLBACKTYPE_syscall32,
0939 xen_entry_SYSCALL_compat);
0940 if (ret != 0)
0941 setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
0942 }
0943 }
0944
0945 static void __init xen_pvmmu_arch_setup(void)
0946 {
0947 HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
0948 HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
0949
0950 HYPERVISOR_vm_assist(VMASST_CMD_enable,
0951 VMASST_TYPE_pae_extended_cr3);
0952
0953 if (register_callback(CALLBACKTYPE_event,
0954 xen_asm_exc_xen_hypervisor_callback) ||
0955 register_callback(CALLBACKTYPE_failsafe, xen_failsafe_callback))
0956 BUG();
0957
0958 xen_enable_sysenter();
0959 xen_enable_syscall();
0960 }
0961
0962
0963 void __init xen_arch_setup(void)
0964 {
0965 xen_panic_handler_init();
0966 xen_pvmmu_arch_setup();
0967
0968 #ifdef CONFIG_ACPI
0969 if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
0970 printk(KERN_INFO "ACPI in unprivileged domain disabled\n");
0971 disable_acpi();
0972 }
0973 #endif
0974
0975 memcpy(boot_command_line, xen_start_info->cmd_line,
0976 MAX_GUEST_CMDLINE > COMMAND_LINE_SIZE ?
0977 COMMAND_LINE_SIZE : MAX_GUEST_CMDLINE);
0978
0979
0980 disable_cpuidle();
0981 disable_cpufreq();
0982 WARN_ON(xen_set_default_idle());
0983 #ifdef CONFIG_NUMA
0984 numa_off = 1;
0985 #endif
0986 }