Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-linus-7.0-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen fixes from Juergen Gross:

- a cleanup of arch/x86/kernel/head_64.S removing the pre-built page
tables for Xen guests

- a small comment update

- another cleanup for Xen PVH guests mode

- fix an issue with Xen PV-devices backed by driver domains

* tag 'for-linus-7.0-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
xen/xenbus: better handle backend crash
xenbus: add xenbus_device parameter to xenbus_read_driver_state()
x86/PVH: Use boot params to pass RSDP address in start_info page
x86/xen: update outdated comment
xen/acpi-processor: fix _CST detection using undersized evaluation buffer
x86/xen: Build identity mapping page tables dynamically for XENPV

+97 -77
-2
arch/x86/include/asm/pgtable_64.h
··· 19 19 extern p4d_t level4_kernel_pgt[512]; 20 20 extern p4d_t level4_ident_pgt[512]; 21 21 extern pud_t level3_kernel_pgt[512]; 22 - extern pud_t level3_ident_pgt[512]; 23 22 extern pmd_t level2_kernel_pgt[512]; 24 23 extern pmd_t level2_fixmap_pgt[512]; 25 - extern pmd_t level2_ident_pgt[512]; 26 24 extern pte_t level1_fixmap_pgt[512 * FIXMAP_PMD_NUM]; 27 25 extern pgd_t init_top_pgt[]; 28 26
-28
arch/x86/kernel/head_64.S
··· 616 616 617 617 .data 618 618 619 - #if defined(CONFIG_XEN_PV) || defined(CONFIG_PVH) 620 - SYM_DATA_START_PTI_ALIGNED(init_top_pgt) 621 - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC 622 - .org init_top_pgt + L4_PAGE_OFFSET*8, 0 623 - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC 624 - .org init_top_pgt + L4_START_KERNEL*8, 0 625 - /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ 626 - .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC 627 - .fill PTI_USER_PGD_FILL,8,0 628 - SYM_DATA_END(init_top_pgt) 629 - 630 - SYM_DATA_START_PAGE_ALIGNED(level3_ident_pgt) 631 - .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC 632 - .fill 511, 8, 0 633 - SYM_DATA_END(level3_ident_pgt) 634 - SYM_DATA_START_PAGE_ALIGNED(level2_ident_pgt) 635 - /* 636 - * Since I easily can, map the first 1G. 637 - * Don't set NX because code runs from these pages. 638 - * 639 - * Note: This sets _PAGE_GLOBAL despite whether 640 - * the CPU supports it or it is enabled. But, 641 - * the CPU should ignore the bit. 642 - */ 643 - PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD) 644 - SYM_DATA_END(level2_ident_pgt) 645 - #else 646 619 SYM_DATA_START_PTI_ALIGNED(init_top_pgt) 647 620 .fill 512,8,0 648 621 .fill PTI_USER_PGD_FILL,8,0 649 622 SYM_DATA_END(init_top_pgt) 650 - #endif 651 623 652 624 SYM_DATA_START_PAGE_ALIGNED(level4_kernel_pgt) 653 625 .fill 511,8,0
+1 -6
arch/x86/platform/pvh/enlighten.c
··· 25 25 26 26 const unsigned int __initconst pvh_start_info_sz = sizeof(pvh_start_info); 27 27 28 - static u64 __init pvh_get_root_pointer(void) 29 - { 30 - return pvh_start_info.rsdp_paddr; 31 - } 32 - 33 28 /* 34 29 * Xen guests are able to obtain the memory map from the hypervisor via the 35 30 * HYPERVISOR_memory_op hypercall. ··· 90 95 pvh_bootparams.hdr.version = (2 << 8) | 12; 91 96 pvh_bootparams.hdr.type_of_loader = ((xen_guest ? 0x9 : 0xb) << 4) | 0; 92 97 93 - x86_init.acpi.get_root_pointer = pvh_get_root_pointer; 98 + pvh_bootparams.acpi_rsdp_addr = pvh_start_info.rsdp_paddr; 94 99 } 95 100 96 101 /*
+1 -1
arch/x86/xen/enlighten_pv.c
··· 392 392 393 393 /* 394 394 * Xen PV would need some work to support PCID: CR3 handling as well 395 - * as xen_flush_tlb_others() would need updating. 395 + * as xen_flush_tlb_multi() would need updating. 396 396 */ 397 397 setup_clear_cpu_cap(X86_FEATURE_PCID); 398 398
+9
arch/x86/xen/mmu_pv.c
··· 105 105 static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss; 106 106 #endif 107 107 108 + static pud_t level3_ident_pgt[PTRS_PER_PUD] __page_aligned_bss; 109 + static pmd_t level2_ident_pgt[PTRS_PER_PMD] __page_aligned_bss; 110 + 108 111 /* 109 112 * Protects atomic reservation decrease/increase against concurrent increases. 110 113 * Also protects non-atomic updates of current_pages and balloon lists. ··· 1779 1776 1780 1777 /* Zap identity mapping */ 1781 1778 init_top_pgt[0] = __pgd(0); 1779 + 1780 + init_top_pgt[pgd_index(__PAGE_OFFSET_BASE_L4)].pgd = 1781 + __pa_symbol(level3_ident_pgt) + _KERNPG_TABLE_NOENC; 1782 + init_top_pgt[pgd_index(__START_KERNEL_map)].pgd = 1783 + __pa_symbol(level3_kernel_pgt) + _PAGE_TABLE_NOENC; 1784 + level3_ident_pgt[0].pud = __pa_symbol(level2_ident_pgt) + _KERNPG_TABLE_NOENC; 1782 1785 1783 1786 /* Pre-constructed entries are in pfn, so convert to mfn */ 1784 1787 /* L4[273] -> level3_ident_pgt */
+17 -17
drivers/net/xen-netfront.c
··· 1646 1646 1647 1647 /* avoid the race with XDP headroom adjustment */ 1648 1648 wait_event(module_wq, 1649 - xenbus_read_driver_state(np->xbdev->otherend) == 1649 + xenbus_read_driver_state(np->xbdev, np->xbdev->otherend) == 1650 1650 XenbusStateReconfigured); 1651 1651 np->netfront_xdp_enabled = true; 1652 1652 ··· 1764 1764 do { 1765 1765 xenbus_switch_state(dev, XenbusStateInitialising); 1766 1766 err = wait_event_timeout(module_wq, 1767 - xenbus_read_driver_state(dev->otherend) != 1767 + xenbus_read_driver_state(dev, dev->otherend) != 1768 1768 XenbusStateClosed && 1769 - xenbus_read_driver_state(dev->otherend) != 1769 + xenbus_read_driver_state(dev, dev->otherend) != 1770 1770 XenbusStateUnknown, XENNET_TIMEOUT); 1771 1771 } while (!err); 1772 1772 ··· 2626 2626 { 2627 2627 int ret; 2628 2628 2629 - if (xenbus_read_driver_state(dev->otherend) == XenbusStateClosed) 2629 + if (xenbus_read_driver_state(dev, dev->otherend) == XenbusStateClosed) 2630 2630 return; 2631 2631 do { 2632 2632 xenbus_switch_state(dev, XenbusStateClosing); 2633 2633 ret = wait_event_timeout(module_wq, 2634 - xenbus_read_driver_state(dev->otherend) == 2635 - XenbusStateClosing || 2636 - xenbus_read_driver_state(dev->otherend) == 2637 - XenbusStateClosed || 2638 - xenbus_read_driver_state(dev->otherend) == 2639 - XenbusStateUnknown, 2640 - XENNET_TIMEOUT); 2634 + xenbus_read_driver_state(dev, dev->otherend) == 2635 + XenbusStateClosing || 2636 + xenbus_read_driver_state(dev, dev->otherend) == 2637 + XenbusStateClosed || 2638 + xenbus_read_driver_state(dev, dev->otherend) == 2639 + XenbusStateUnknown, 2640 + XENNET_TIMEOUT); 2641 2641 } while (!ret); 2642 2642 2643 - if (xenbus_read_driver_state(dev->otherend) == XenbusStateClosed) 2643 + if (xenbus_read_driver_state(dev, dev->otherend) == XenbusStateClosed) 2644 2644 return; 2645 2645 2646 2646 do { 2647 2647 xenbus_switch_state(dev, XenbusStateClosed); 2648 2648 ret = wait_event_timeout(module_wq, 2649 - xenbus_read_driver_state(dev->otherend) == 2650 - XenbusStateClosed || 2651 - xenbus_read_driver_state(dev->otherend) == 2652 - XenbusStateUnknown, 2653 - XENNET_TIMEOUT); 2649 + xenbus_read_driver_state(dev, dev->otherend) == 2650 + XenbusStateClosed || 2651 + xenbus_read_driver_state(dev, dev->otherend) == 2652 + XenbusStateUnknown, 2653 + XENNET_TIMEOUT); 2654 2654 } while (!ret); 2655 2655 } 2656 2656
+4 -4
drivers/pci/xen-pcifront.c
··· 856 856 int err; 857 857 858 858 /* Only connect once */ 859 - if (xenbus_read_driver_state(pdev->xdev->nodename) != 859 + if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) != 860 860 XenbusStateInitialised) 861 861 return; 862 862 ··· 876 876 enum xenbus_state prev_state; 877 877 878 878 879 - prev_state = xenbus_read_driver_state(pdev->xdev->nodename); 879 + prev_state = xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename); 880 880 881 881 if (prev_state >= XenbusStateClosing) 882 882 goto out; ··· 895 895 896 896 static void pcifront_attach_devices(struct pcifront_device *pdev) 897 897 { 898 - if (xenbus_read_driver_state(pdev->xdev->nodename) == 898 + if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) == 899 899 XenbusStateReconfiguring) 900 900 pcifront_connect(pdev); 901 901 } ··· 909 909 struct pci_dev *pci_dev; 910 910 char str[64]; 911 911 912 - state = xenbus_read_driver_state(pdev->xdev->nodename); 912 + state = xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename); 913 913 if (state == XenbusStateInitialised) { 914 914 dev_dbg(&pdev->xdev->dev, "Handle skipped connect.\n"); 915 915 /* We missed Connected and need to initialize. */
+1 -1
drivers/scsi/xen-scsifront.c
··· 1175 1175 return; 1176 1176 } 1177 1177 1178 - if (xenbus_read_driver_state(dev->nodename) == 1178 + if (xenbus_read_driver_state(dev, dev->nodename) == 1179 1179 XenbusStateInitialised) 1180 1180 scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN); 1181 1181
+2 -5
drivers/xen/xen-acpi-processor.c
··· 378 378 acpi_psd[acpi_id].domain); 379 379 } 380 380 381 - status = acpi_evaluate_object(handle, "_CST", NULL, &buffer); 382 - if (ACPI_FAILURE(status)) { 383 - if (!pblk) 384 - return AE_OK; 385 - } 381 + if (!pblk && !acpi_has_method(handle, "_CST")) 382 + return AE_OK; 386 383 /* .. and it has a C-state */ 387 384 __set_bit(acpi_id, acpi_id_cst_present); 388 385
+5 -5
drivers/xen/xen-pciback/xenbus.c
··· 149 149 150 150 mutex_lock(&pdev->dev_lock); 151 151 /* Make sure we only do this setup once */ 152 - if (xenbus_read_driver_state(pdev->xdev->nodename) != 152 + if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) != 153 153 XenbusStateInitialised) 154 154 goto out; 155 155 156 156 /* Wait for frontend to state that it has published the configuration */ 157 - if (xenbus_read_driver_state(pdev->xdev->otherend) != 157 + if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->otherend) != 158 158 XenbusStateInitialised) 159 159 goto out; 160 160 ··· 374 374 dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n"); 375 375 376 376 mutex_lock(&pdev->dev_lock); 377 - if (xenbus_read_driver_state(pdev->xdev->nodename) != state) 377 + if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) != state) 378 378 goto out; 379 379 380 380 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d", ··· 572 572 /* It's possible we could get the call to setup twice, so make sure 573 573 * we're not already connected. 574 574 */ 575 - if (xenbus_read_driver_state(pdev->xdev->nodename) != 575 + if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) != 576 576 XenbusStateInitWait) 577 577 goto out; 578 578 ··· 662 662 struct xen_pcibk_device *pdev = 663 663 container_of(watch, struct xen_pcibk_device, be_watch); 664 664 665 - switch (xenbus_read_driver_state(pdev->xdev->nodename)) { 665 + switch (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename)) { 666 666 case XenbusStateInitWait: 667 667 xen_pcibk_setup_backend(pdev); 668 668 break;
+14 -3
drivers/xen/xenbus/xenbus_client.c
··· 226 226 struct xenbus_transaction xbt; 227 227 int current_state; 228 228 int err, abort; 229 + bool vanished = false; 229 230 230 - if (state == dev->state) 231 + if (state == dev->state || dev->vanished) 231 232 return 0; 232 233 233 234 again: ··· 243 242 err = xenbus_scanf(xbt, dev->nodename, "state", "%d", &current_state); 244 243 if (err != 1) 245 244 goto abort; 245 + if (current_state != dev->state && current_state == XenbusStateInitialising) { 246 + vanished = true; 247 + goto abort; 248 + } 246 249 247 250 err = xenbus_printf(xbt, dev->nodename, "state", "%d", state); 248 251 if (err) { ··· 261 256 if (err == -EAGAIN && !abort) 262 257 goto again; 263 258 xenbus_switch_fatal(dev, depth, err, "ending transaction"); 264 - } else 259 + } else if (!vanished) 265 260 dev->state = state; 266 261 267 262 return 0; ··· 936 931 937 932 /** 938 933 * xenbus_read_driver_state - read state from a store path 934 + * @dev: xenbus device pointer 939 935 * @path: path for driver 940 936 * 941 937 * Returns: the state of the driver rooted at the given store path, or 942 938 * XenbusStateUnknown if no state can be read. 943 939 */ 944 - enum xenbus_state xenbus_read_driver_state(const char *path) 940 + enum xenbus_state xenbus_read_driver_state(const struct xenbus_device *dev, 941 + const char *path) 945 942 { 946 943 enum xenbus_state result; 944 + 945 + if (dev && dev->vanished) 946 + return XenbusStateUnknown; 947 + 947 948 int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL); 948 949 if (err) 949 950 result = XenbusStateUnknown;
+39 -3
drivers/xen/xenbus/xenbus_probe.c
··· 191 191 return; 192 192 } 193 193 194 - state = xenbus_read_driver_state(dev->otherend); 194 + state = xenbus_read_driver_state(dev, dev->otherend); 195 195 196 196 dev_dbg(&dev->dev, "state is %d, (%s), %s, %s\n", 197 197 state, xenbus_strstate(state), dev->otherend_watch.node, path); ··· 364 364 * closed. 365 365 */ 366 366 if (!drv->allow_rebind || 367 - xenbus_read_driver_state(dev->nodename) == XenbusStateClosing) 367 + xenbus_read_driver_state(dev, dev->nodename) == XenbusStateClosing) 368 368 xenbus_switch_state(dev, XenbusStateClosed); 369 369 } 370 370 EXPORT_SYMBOL_GPL(xenbus_dev_remove); ··· 444 444 info.dev = NULL; 445 445 bus_for_each_dev(bus, NULL, &info, cleanup_dev); 446 446 if (info.dev) { 447 + dev_warn(&info.dev->dev, 448 + "device forcefully removed from xenstore\n"); 449 + info.dev->vanished = true; 447 450 device_unregister(&info.dev->dev); 448 451 put_device(&info.dev->dev); 449 452 } ··· 517 514 size_t stringlen; 518 515 char *tmpstring; 519 516 520 - enum xenbus_state state = xenbus_read_driver_state(nodename); 517 + enum xenbus_state state = xenbus_read_driver_state(NULL, nodename); 521 518 522 519 if (state != XenbusStateInitialising) { 523 520 /* Device is not new, so ignore it. This can happen if a ··· 662 659 return; 663 660 664 661 dev = xenbus_device_find(root, &bus->bus); 662 + /* 663 + * Backend domain crash results in not coordinated frontend removal, 664 + * without going through XenbusStateClosing. If this is a new instance 665 + * of the same device Xen tools will have reset the state to 666 + * XenbusStateInitializing. 667 + * It might be that the backend crashed early during the init phase of 668 + * device setup, in which case the known state would have been 669 + * XenbusStateInitializing. So test the backend domid to match the 670 + * saved one. In case the new backend happens to have the same domid as 671 + * the old one, we can just carry on, as there is no inconsistency 672 + * resulting in this case. 673 + */ 674 + if (dev && !strcmp(bus->root, "device")) { 675 + enum xenbus_state state = xenbus_read_driver_state(dev, dev->nodename); 676 + unsigned int backend = xenbus_read_unsigned(root, "backend-id", 677 + dev->otherend_id); 678 + 679 + if (state == XenbusStateInitialising && 680 + (state != dev->state || backend != dev->otherend_id)) { 681 + /* 682 + * State has been reset, assume the old one vanished 683 + * and new one needs to be probed. 684 + */ 685 + dev_warn(&dev->dev, 686 + "state reset occurred, reconnecting\n"); 687 + dev->vanished = true; 688 + } 689 + if (dev->vanished) { 690 + device_unregister(&dev->dev); 691 + put_device(&dev->dev); 692 + dev = NULL; 693 + } 694 + } 665 695 if (!dev) 666 696 xenbus_probe_node(bus, type, root); 667 697 else
+1 -1
drivers/xen/xenbus/xenbus_probe_frontend.c
··· 253 253 } else if (xendev->state < XenbusStateConnected) { 254 254 enum xenbus_state rstate = XenbusStateUnknown; 255 255 if (xendev->otherend) 256 - rstate = xenbus_read_driver_state(xendev->otherend); 256 + rstate = xenbus_read_driver_state(xendev, xendev->otherend); 257 257 pr_warn("Timeout connecting to device: %s (local state %d, remote state %d)\n", 258 258 xendev->nodename, xendev->state, rstate); 259 259 }
+3 -1
include/xen/xenbus.h
··· 80 80 const char *devicetype; 81 81 const char *nodename; 82 82 const char *otherend; 83 + bool vanished; 83 84 int otherend_id; 84 85 struct xenbus_watch otherend_watch; 85 86 struct device dev; ··· 229 228 int xenbus_alloc_evtchn(struct xenbus_device *dev, evtchn_port_t *port); 230 229 int xenbus_free_evtchn(struct xenbus_device *dev, evtchn_port_t port); 231 230 232 - enum xenbus_state xenbus_read_driver_state(const char *path); 231 + enum xenbus_state xenbus_read_driver_state(const struct xenbus_device *dev, 232 + const char *path); 233 233 234 234 __printf(3, 4) 235 235 void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...);