xen: branch for v7.0-rc3

-----BEGIN PGP SIGNATURE-----
 
 iJEEABYKADkWIQRTLbB6QfY48x44uB6AXGG7T9hjvgUCaav3pBsUgAAAAAAEAA5t
 YW51MiwyLjUrMS4xMSwyLDIACgkQgFxhu0/YY75xWwD+NO/7WX01zcYSFMHTjHRx
 okbOkBwFzcZK+p/L4iTtVv0BAIYPUpa+RBLR2RtYN7mQEw8KO5yVgiLP2nlQYwIf
 wZcH
 =DrUe
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2026-03-07 07:44:32 -08:00
commit 0f912c8917
14 changed files with 97 additions and 77 deletions

View file

@ -19,10 +19,8 @@
extern p4d_t level4_kernel_pgt[512];
extern p4d_t level4_ident_pgt[512];
extern pud_t level3_kernel_pgt[512];
extern pud_t level3_ident_pgt[512];
extern pmd_t level2_kernel_pgt[512];
extern pmd_t level2_fixmap_pgt[512];
extern pmd_t level2_ident_pgt[512];
extern pte_t level1_fixmap_pgt[512 * FIXMAP_PMD_NUM];
extern pgd_t init_top_pgt[];

View file

@ -616,38 +616,10 @@ SYM_DATA(early_recursion_flag, .long 0)
.data
#if defined(CONFIG_XEN_PV) || defined(CONFIG_PVH)
SYM_DATA_START_PTI_ALIGNED(init_top_pgt)
.quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
.org init_top_pgt + L4_PAGE_OFFSET*8, 0
.quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
.org init_top_pgt + L4_START_KERNEL*8, 0
/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
.quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC
.fill PTI_USER_PGD_FILL,8,0
SYM_DATA_END(init_top_pgt)
SYM_DATA_START_PAGE_ALIGNED(level3_ident_pgt)
.quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
.fill 511, 8, 0
SYM_DATA_END(level3_ident_pgt)
SYM_DATA_START_PAGE_ALIGNED(level2_ident_pgt)
/*
* Since I easily can, map the first 1G.
* Don't set NX because code runs from these pages.
*
* Note: This sets _PAGE_GLOBAL despite whether
* the CPU supports it or it is enabled. But,
* the CPU should ignore the bit.
*/
PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD)
SYM_DATA_END(level2_ident_pgt)
#else
SYM_DATA_START_PTI_ALIGNED(init_top_pgt)
.fill 512,8,0
.fill PTI_USER_PGD_FILL,8,0
SYM_DATA_END(init_top_pgt)
#endif
SYM_DATA_START_PAGE_ALIGNED(level4_kernel_pgt)
.fill 511,8,0

View file

@ -25,11 +25,6 @@ struct hvm_start_info __initdata pvh_start_info;
const unsigned int __initconst pvh_start_info_sz = sizeof(pvh_start_info);
static u64 __init pvh_get_root_pointer(void)
{
return pvh_start_info.rsdp_paddr;
}
/*
* Xen guests are able to obtain the memory map from the hypervisor via the
* HYPERVISOR_memory_op hypercall.
@ -95,7 +90,7 @@ static void __init init_pvh_bootparams(bool xen_guest)
pvh_bootparams.hdr.version = (2 << 8) | 12;
pvh_bootparams.hdr.type_of_loader = ((xen_guest ? 0x9 : 0xb) << 4) | 0;
x86_init.acpi.get_root_pointer = pvh_get_root_pointer;
pvh_bootparams.acpi_rsdp_addr = pvh_start_info.rsdp_paddr;
}
/*

View file

@ -392,7 +392,7 @@ static void __init xen_init_capabilities(void)
/*
* Xen PV would need some work to support PCID: CR3 handling as well
* as xen_flush_tlb_others() would need updating.
* as xen_flush_tlb_multi() would need updating.
*/
setup_clear_cpu_cap(X86_FEATURE_PCID);

View file

@ -105,6 +105,9 @@ pte_t xen_make_pte_init(pteval_t pte);
static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss;
#endif
static pud_t level3_ident_pgt[PTRS_PER_PUD] __page_aligned_bss;
static pmd_t level2_ident_pgt[PTRS_PER_PMD] __page_aligned_bss;
/*
* Protects atomic reservation decrease/increase against concurrent increases.
* Also protects non-atomic updates of current_pages and balloon lists.
@ -1777,6 +1780,12 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
/* Zap identity mapping */
init_top_pgt[0] = __pgd(0);
init_top_pgt[pgd_index(__PAGE_OFFSET_BASE_L4)].pgd =
__pa_symbol(level3_ident_pgt) + _KERNPG_TABLE_NOENC;
init_top_pgt[pgd_index(__START_KERNEL_map)].pgd =
__pa_symbol(level3_kernel_pgt) + _PAGE_TABLE_NOENC;
level3_ident_pgt[0].pud = __pa_symbol(level2_ident_pgt) + _KERNPG_TABLE_NOENC;
/* Pre-constructed entries are in pfn, so convert to mfn */
/* L4[273] -> level3_ident_pgt */
/* L4[511] -> level3_kernel_pgt */

View file

@ -1646,7 +1646,7 @@ static int xennet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
/* avoid the race with XDP headroom adjustment */
wait_event(module_wq,
xenbus_read_driver_state(np->xbdev->otherend) ==
xenbus_read_driver_state(np->xbdev, np->xbdev->otherend) ==
XenbusStateReconfigured);
np->netfront_xdp_enabled = true;
@ -1764,9 +1764,9 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
do {
xenbus_switch_state(dev, XenbusStateInitialising);
err = wait_event_timeout(module_wq,
xenbus_read_driver_state(dev->otherend) !=
xenbus_read_driver_state(dev, dev->otherend) !=
XenbusStateClosed &&
xenbus_read_driver_state(dev->otherend) !=
xenbus_read_driver_state(dev, dev->otherend) !=
XenbusStateUnknown, XENNET_TIMEOUT);
} while (!err);
@ -2626,29 +2626,29 @@ static void xennet_bus_close(struct xenbus_device *dev)
{
int ret;
if (xenbus_read_driver_state(dev->otherend) == XenbusStateClosed)
if (xenbus_read_driver_state(dev, dev->otherend) == XenbusStateClosed)
return;
do {
xenbus_switch_state(dev, XenbusStateClosing);
ret = wait_event_timeout(module_wq,
xenbus_read_driver_state(dev->otherend) ==
xenbus_read_driver_state(dev, dev->otherend) ==
XenbusStateClosing ||
xenbus_read_driver_state(dev->otherend) ==
xenbus_read_driver_state(dev, dev->otherend) ==
XenbusStateClosed ||
xenbus_read_driver_state(dev->otherend) ==
xenbus_read_driver_state(dev, dev->otherend) ==
XenbusStateUnknown,
XENNET_TIMEOUT);
} while (!ret);
if (xenbus_read_driver_state(dev->otherend) == XenbusStateClosed)
if (xenbus_read_driver_state(dev, dev->otherend) == XenbusStateClosed)
return;
do {
xenbus_switch_state(dev, XenbusStateClosed);
ret = wait_event_timeout(module_wq,
xenbus_read_driver_state(dev->otherend) ==
xenbus_read_driver_state(dev, dev->otherend) ==
XenbusStateClosed ||
xenbus_read_driver_state(dev->otherend) ==
xenbus_read_driver_state(dev, dev->otherend) ==
XenbusStateUnknown,
XENNET_TIMEOUT);
} while (!ret);

View file

@ -856,7 +856,7 @@ static void pcifront_try_connect(struct pcifront_device *pdev)
int err;
/* Only connect once */
if (xenbus_read_driver_state(pdev->xdev->nodename) !=
if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) !=
XenbusStateInitialised)
return;
@ -876,7 +876,7 @@ static int pcifront_try_disconnect(struct pcifront_device *pdev)
enum xenbus_state prev_state;
prev_state = xenbus_read_driver_state(pdev->xdev->nodename);
prev_state = xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename);
if (prev_state >= XenbusStateClosing)
goto out;
@ -895,7 +895,7 @@ out:
static void pcifront_attach_devices(struct pcifront_device *pdev)
{
if (xenbus_read_driver_state(pdev->xdev->nodename) ==
if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) ==
XenbusStateReconfiguring)
pcifront_connect(pdev);
}
@ -909,7 +909,7 @@ static int pcifront_detach_devices(struct pcifront_device *pdev)
struct pci_dev *pci_dev;
char str[64];
state = xenbus_read_driver_state(pdev->xdev->nodename);
state = xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename);
if (state == XenbusStateInitialised) {
dev_dbg(&pdev->xdev->dev, "Handle skipped connect.\n");
/* We missed Connected and need to initialize. */

View file

@ -1175,7 +1175,7 @@ static void scsifront_backend_changed(struct xenbus_device *dev,
return;
}
if (xenbus_read_driver_state(dev->nodename) ==
if (xenbus_read_driver_state(dev, dev->nodename) ==
XenbusStateInitialised)
scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN);

View file

@ -378,11 +378,8 @@ read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv)
acpi_psd[acpi_id].domain);
}
status = acpi_evaluate_object(handle, "_CST", NULL, &buffer);
if (ACPI_FAILURE(status)) {
if (!pblk)
if (!pblk && !acpi_has_method(handle, "_CST"))
return AE_OK;
}
/* .. and it has a C-state */
__set_bit(acpi_id, acpi_id_cst_present);

View file

@ -149,12 +149,12 @@ static int xen_pcibk_attach(struct xen_pcibk_device *pdev)
mutex_lock(&pdev->dev_lock);
/* Make sure we only do this setup once */
if (xenbus_read_driver_state(pdev->xdev->nodename) !=
if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) !=
XenbusStateInitialised)
goto out;
/* Wait for frontend to state that it has published the configuration */
if (xenbus_read_driver_state(pdev->xdev->otherend) !=
if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->otherend) !=
XenbusStateInitialised)
goto out;
@ -374,7 +374,7 @@ static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev,
dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n");
mutex_lock(&pdev->dev_lock);
if (xenbus_read_driver_state(pdev->xdev->nodename) != state)
if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) != state)
goto out;
err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d",
@ -572,7 +572,7 @@ static int xen_pcibk_setup_backend(struct xen_pcibk_device *pdev)
/* It's possible we could get the call to setup twice, so make sure
* we're not already connected.
*/
if (xenbus_read_driver_state(pdev->xdev->nodename) !=
if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) !=
XenbusStateInitWait)
goto out;
@ -662,7 +662,7 @@ static void xen_pcibk_be_watch(struct xenbus_watch *watch,
struct xen_pcibk_device *pdev =
container_of(watch, struct xen_pcibk_device, be_watch);
switch (xenbus_read_driver_state(pdev->xdev->nodename)) {
switch (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename)) {
case XenbusStateInitWait:
xen_pcibk_setup_backend(pdev);
break;

View file

@ -226,8 +226,9 @@ __xenbus_switch_state(struct xenbus_device *dev,
struct xenbus_transaction xbt;
int current_state;
int err, abort;
bool vanished = false;
if (state == dev->state)
if (state == dev->state || dev->vanished)
return 0;
again:
@ -242,6 +243,10 @@ again:
err = xenbus_scanf(xbt, dev->nodename, "state", "%d", &current_state);
if (err != 1)
goto abort;
if (current_state != dev->state && current_state == XenbusStateInitialising) {
vanished = true;
goto abort;
}
err = xenbus_printf(xbt, dev->nodename, "state", "%d", state);
if (err) {
@ -256,7 +261,7 @@ abort:
if (err == -EAGAIN && !abort)
goto again;
xenbus_switch_fatal(dev, depth, err, "ending transaction");
} else
} else if (!vanished)
dev->state = state;
return 0;
@ -931,14 +936,20 @@ static int xenbus_unmap_ring_hvm(struct xenbus_device *dev, void *vaddr)
/**
* xenbus_read_driver_state - read state from a store path
* @dev: xenbus device pointer
* @path: path for driver
*
* Returns: the state of the driver rooted at the given store path, or
* XenbusStateUnknown if no state can be read.
*/
enum xenbus_state xenbus_read_driver_state(const char *path)
enum xenbus_state xenbus_read_driver_state(const struct xenbus_device *dev,
const char *path)
{
enum xenbus_state result;
if (dev && dev->vanished)
return XenbusStateUnknown;
int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
if (err)
result = XenbusStateUnknown;

View file

@ -191,7 +191,7 @@ void xenbus_otherend_changed(struct xenbus_watch *watch,
return;
}
state = xenbus_read_driver_state(dev->otherend);
state = xenbus_read_driver_state(dev, dev->otherend);
dev_dbg(&dev->dev, "state is %d, (%s), %s, %s\n",
state, xenbus_strstate(state), dev->otherend_watch.node, path);
@ -364,7 +364,7 @@ void xenbus_dev_remove(struct device *_dev)
* closed.
*/
if (!drv->allow_rebind ||
xenbus_read_driver_state(dev->nodename) == XenbusStateClosing)
xenbus_read_driver_state(dev, dev->nodename) == XenbusStateClosing)
xenbus_switch_state(dev, XenbusStateClosed);
}
EXPORT_SYMBOL_GPL(xenbus_dev_remove);
@ -444,6 +444,9 @@ static void xenbus_cleanup_devices(const char *path, struct bus_type *bus)
info.dev = NULL;
bus_for_each_dev(bus, NULL, &info, cleanup_dev);
if (info.dev) {
dev_warn(&info.dev->dev,
"device forcefully removed from xenstore\n");
info.dev->vanished = true;
device_unregister(&info.dev->dev);
put_device(&info.dev->dev);
}
@ -514,7 +517,7 @@ int xenbus_probe_node(struct xen_bus_type *bus,
size_t stringlen;
char *tmpstring;
enum xenbus_state state = xenbus_read_driver_state(nodename);
enum xenbus_state state = xenbus_read_driver_state(NULL, nodename);
if (state != XenbusStateInitialising) {
/* Device is not new, so ignore it. This can happen if a
@ -659,6 +662,39 @@ void xenbus_dev_changed(const char *node, struct xen_bus_type *bus)
return;
dev = xenbus_device_find(root, &bus->bus);
/*
* Backend domain crash results in not coordinated frontend removal,
* without going through XenbusStateClosing. If this is a new instance
* of the same device Xen tools will have reset the state to
* XenbusStateInitializing.
* It might be that the backend crashed early during the init phase of
* device setup, in which case the known state would have been
* XenbusStateInitializing. So test the backend domid to match the
* saved one. In case the new backend happens to have the same domid as
* the old one, we can just carry on, as there is no inconsistency
* resulting in this case.
*/
if (dev && !strcmp(bus->root, "device")) {
enum xenbus_state state = xenbus_read_driver_state(dev, dev->nodename);
unsigned int backend = xenbus_read_unsigned(root, "backend-id",
dev->otherend_id);
if (state == XenbusStateInitialising &&
(state != dev->state || backend != dev->otherend_id)) {
/*
* State has been reset, assume the old one vanished
* and new one needs to be probed.
*/
dev_warn(&dev->dev,
"state reset occurred, reconnecting\n");
dev->vanished = true;
}
if (dev->vanished) {
device_unregister(&dev->dev);
put_device(&dev->dev);
dev = NULL;
}
}
if (!dev)
xenbus_probe_node(bus, type, root);
else

View file

@ -253,7 +253,7 @@ static int print_device_status(struct device *dev, void *data)
} else if (xendev->state < XenbusStateConnected) {
enum xenbus_state rstate = XenbusStateUnknown;
if (xendev->otherend)
rstate = xenbus_read_driver_state(xendev->otherend);
rstate = xenbus_read_driver_state(xendev, xendev->otherend);
pr_warn("Timeout connecting to device: %s (local state %d, remote state %d)\n",
xendev->nodename, xendev->state, rstate);
}

View file

@ -80,6 +80,7 @@ struct xenbus_device {
const char *devicetype;
const char *nodename;
const char *otherend;
bool vanished;
int otherend_id;
struct xenbus_watch otherend_watch;
struct device dev;
@ -228,7 +229,8 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr);
int xenbus_alloc_evtchn(struct xenbus_device *dev, evtchn_port_t *port);
int xenbus_free_evtchn(struct xenbus_device *dev, evtchn_port_t port);
enum xenbus_state xenbus_read_driver_state(const char *path);
enum xenbus_state xenbus_read_driver_state(const struct xenbus_device *dev,
const char *path);
__printf(3, 4)
void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...);