summaryrefslogtreecommitdiff
path: root/drivers/xen
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-02-09 20:38:27 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2026-02-09 20:38:27 -0800
commit33120a2f8fc47f388506b7df1209bd5ac85dd584 (patch)
tree41ec6df5bbcd871e6010f29dbf24104c7adc6579 /drivers/xen
parent45bf4bc87c46856c5cf4ac39a0c25c83ccbf3209 (diff)
parentc307b6dc9c4f68d00524ec10899cdf21466b5c1e (diff)
Merge tag 'for-linus-7.0-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen updates from Juergen Gross: - fix running as Xen PVH guest in 32-bit mode without PAE - fix PV device handling for suspend/resume when running as a Xen guest - clean up workqueue usage - fix the Xen balloon driver for PVH dom0 - introduce the possibility to use hypercalls for console messages in unprivileged guests - enable Xen dom0 use of virtio devices in nested virtualization setups - simplify the xen-mcelog driver * tag 'for-linus-7.0-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xenbus: Rename helpers to freeze/thaw/restore xenbus: Use .freeze/.thaw to handle xenbus devices xen/mcelog: simplify MCE_GETCLEAR_FLAGS using xchg() xen/balloon: improve accuracy of initial balloon target for dom0 Partial revert "x86/xen: fix balloon target initialization for PVH dom0" xen: introduce xen_console_io option xen/virtio: Don't use grant-dma-ops when running as Dom0 x86/xen/pvh: Enable PAE mode for 32-bit guest only when CONFIG_X86_PAE is set xen: privcmd: WQ_PERCPU added to alloc_workqueue users xen/events: replace use of system_wq with system_percpu_wq
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/balloon.c26
-rw-r--r--drivers/xen/events/events_base.c6
-rw-r--r--drivers/xen/grant-dma-ops.c3
-rw-r--r--drivers/xen/mcelog.c4
-rw-r--r--drivers/xen/privcmd.c3
-rw-r--r--drivers/xen/unpopulated-alloc.c3
-rw-r--r--drivers/xen/xenbus/xenbus.h6
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c22
-rw-r--r--drivers/xen/xenbus/xenbus_probe_frontend.c18
9 files changed, 55 insertions, 36 deletions
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 49c3f9926394..9b6531eb28b6 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -724,6 +724,8 @@ static int __init balloon_add_regions(void)
static int __init balloon_init(void)
{
struct task_struct *task;
+ long current_pages = 0;
+ domid_t domid = DOMID_SELF;
int rc;
if (!xen_domain())
@@ -731,12 +733,24 @@ static int __init balloon_init(void)
pr_info("Initialising balloon driver\n");
- if (xen_released_pages >= get_num_physpages()) {
- WARN(1, "Released pages underflow current target");
- return -ERANGE;
+ if (xen_initial_domain())
+ current_pages = HYPERVISOR_memory_op(XENMEM_current_reservation,
+ &domid);
+ if (current_pages <= 0) {
+ if (xen_pv_domain()) {
+ if (xen_released_pages >= xen_start_info->nr_pages)
+ goto underflow;
+ current_pages = min(xen_start_info->nr_pages -
+ xen_released_pages, max_pfn);
+ } else {
+ if (xen_unpopulated_pages >= get_num_physpages())
+ goto underflow;
+ current_pages = get_num_physpages() -
+ xen_unpopulated_pages;
+ }
}
- balloon_stats.current_pages = get_num_physpages() - xen_released_pages;
+ balloon_stats.current_pages = current_pages;
balloon_stats.target_pages = balloon_stats.current_pages;
balloon_stats.balloon_low = 0;
balloon_stats.balloon_high = 0;
@@ -767,6 +781,10 @@ static int __init balloon_init(void)
xen_balloon_init();
return 0;
+
+ underflow:
+ WARN(1, "Released pages underflow current target");
+ return -ERANGE;
}
subsys_initcall(balloon_init);
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 9478fae014e5..663df17776fd 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -581,7 +581,7 @@ static void lateeoi_list_add(struct irq_info *info)
eoi_list);
if (!elem || info->eoi_time < elem->eoi_time) {
list_add(&info->eoi_list, &eoi->eoi_list);
- mod_delayed_work_on(info->eoi_cpu, system_wq,
+ mod_delayed_work_on(info->eoi_cpu, system_percpu_wq,
&eoi->delayed, delay);
} else {
list_for_each_entry_reverse(elem, &eoi->eoi_list, eoi_list) {
@@ -666,7 +666,7 @@ static void xen_irq_lateeoi_worker(struct work_struct *work)
break;
if (now < info->eoi_time) {
- mod_delayed_work_on(info->eoi_cpu, system_wq,
+ mod_delayed_work_on(info->eoi_cpu, system_percpu_wq,
&eoi->delayed,
info->eoi_time - now);
break;
@@ -782,7 +782,7 @@ static void xen_free_irq(struct irq_info *info)
WARN_ON(info->refcnt > 0);
- queue_rcu_work(system_wq, &info->rwork);
+ queue_rcu_work(system_percpu_wq, &info->rwork);
}
/* Not called for lateeoi events. */
diff --git a/drivers/xen/grant-dma-ops.c b/drivers/xen/grant-dma-ops.c
index 14077d23f2a1..c2603e700178 100644
--- a/drivers/xen/grant-dma-ops.c
+++ b/drivers/xen/grant-dma-ops.c
@@ -366,7 +366,8 @@ static int xen_grant_init_backend_domid(struct device *dev,
if (np) {
ret = xen_dt_grant_init_backend_domid(dev, np, backend_domid);
of_node_put(np);
- } else if (IS_ENABLED(CONFIG_XEN_VIRTIO_FORCE_GRANT) || xen_pv_domain()) {
+ } else if (!xen_initial_domain() &&
+ (IS_ENABLED(CONFIG_XEN_VIRTIO_FORCE_GRANT) || xen_pv_domain())) {
dev_info(dev, "Using dom0 as backend\n");
*backend_domid = 0;
ret = 0;
diff --git a/drivers/xen/mcelog.c b/drivers/xen/mcelog.c
index 4f65b641c054..abe658c73b7b 100644
--- a/drivers/xen/mcelog.c
+++ b/drivers/xen/mcelog.c
@@ -165,9 +165,7 @@ static long xen_mce_chrdev_ioctl(struct file *f, unsigned int cmd,
case MCE_GETCLEAR_FLAGS: {
unsigned flags;
- do {
- flags = xen_mcelog.flags;
- } while (cmpxchg(&xen_mcelog.flags, flags, 0) != flags);
+ flags = xchg(&xen_mcelog.flags, 0);
return put_user(flags, p);
}
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index f52a457b302d..402be080ad2c 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -1091,7 +1091,8 @@ static long privcmd_ioctl_irqfd(struct file *file, void __user *udata)
static int privcmd_irqfd_init(void)
{
- irqfd_cleanup_wq = alloc_workqueue("privcmd-irqfd-cleanup", 0, 0);
+ irqfd_cleanup_wq = alloc_workqueue("privcmd-irqfd-cleanup", WQ_PERCPU,
+ 0);
if (!irqfd_cleanup_wq)
return -ENOMEM;
diff --git a/drivers/xen/unpopulated-alloc.c b/drivers/xen/unpopulated-alloc.c
index d6fc2aefe264..1dc0b495c8e5 100644
--- a/drivers/xen/unpopulated-alloc.c
+++ b/drivers/xen/unpopulated-alloc.c
@@ -18,6 +18,9 @@ static unsigned int list_count;
static struct resource *target_resource;
+/* Pages to subtract from the memory count when setting balloon target. */
+unsigned long xen_unpopulated_pages __initdata;
+
/*
* If arch is not happy with system "iomem_resource" being used for
* the region allocation it can provide it's own view by creating specific
diff --git a/drivers/xen/xenbus/xenbus.h b/drivers/xen/xenbus/xenbus.h
index 9ac0427724a3..daba7f5e05c4 100644
--- a/drivers/xen/xenbus/xenbus.h
+++ b/drivers/xen/xenbus/xenbus.h
@@ -120,9 +120,9 @@ int xenbus_probe_devices(struct xen_bus_type *bus);
void xenbus_dev_changed(const char *node, struct xen_bus_type *bus);
-int xenbus_dev_suspend(struct device *dev);
-int xenbus_dev_resume(struct device *dev);
-int xenbus_dev_cancel(struct device *dev);
+int xenbus_dev_freeze(struct device *dev);
+int xenbus_dev_restore(struct device *dev);
+int xenbus_dev_thaw(struct device *dev);
void xenbus_otherend_changed(struct xenbus_watch *watch,
const char *path, const char *token,
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 86fe6e779056..9f9011cd7447 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -668,7 +668,7 @@ void xenbus_dev_changed(const char *node, struct xen_bus_type *bus)
}
EXPORT_SYMBOL_GPL(xenbus_dev_changed);
-int xenbus_dev_suspend(struct device *dev)
+int xenbus_dev_freeze(struct device *dev)
{
int err = 0;
struct xenbus_driver *drv;
@@ -683,12 +683,12 @@ int xenbus_dev_suspend(struct device *dev)
if (drv->suspend)
err = drv->suspend(xdev);
if (err)
- dev_warn(dev, "suspend failed: %i\n", err);
+ dev_warn(dev, "freeze failed: %i\n", err);
return 0;
}
-EXPORT_SYMBOL_GPL(xenbus_dev_suspend);
+EXPORT_SYMBOL_GPL(xenbus_dev_freeze);
-int xenbus_dev_resume(struct device *dev)
+int xenbus_dev_restore(struct device *dev)
{
int err;
struct xenbus_driver *drv;
@@ -702,7 +702,7 @@ int xenbus_dev_resume(struct device *dev)
drv = to_xenbus_driver(dev->driver);
err = talk_to_otherend(xdev);
if (err) {
- dev_warn(dev, "resume (talk_to_otherend) failed: %i\n", err);
+ dev_warn(dev, "restore (talk_to_otherend) failed: %i\n", err);
return err;
}
@@ -711,28 +711,28 @@ int xenbus_dev_resume(struct device *dev)
if (drv->resume) {
err = drv->resume(xdev);
if (err) {
- dev_warn(dev, "resume failed: %i\n", err);
+ dev_warn(dev, "restore failed: %i\n", err);
return err;
}
}
err = watch_otherend(xdev);
if (err) {
- dev_warn(dev, "resume (watch_otherend) failed: %d\n", err);
+ dev_warn(dev, "restore (watch_otherend) failed: %d\n", err);
return err;
}
return 0;
}
-EXPORT_SYMBOL_GPL(xenbus_dev_resume);
+EXPORT_SYMBOL_GPL(xenbus_dev_restore);
-int xenbus_dev_cancel(struct device *dev)
+int xenbus_dev_thaw(struct device *dev)
{
/* Do nothing */
- DPRINTK("cancel");
+ DPRINTK("thaw");
return 0;
}
-EXPORT_SYMBOL_GPL(xenbus_dev_cancel);
+EXPORT_SYMBOL_GPL(xenbus_dev_thaw);
/* A flag to determine if xenstored is 'ready' (i.e. has started) */
int xenstored_ready;
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c
index 6d1819269cbe..f04707d1f667 100644
--- a/drivers/xen/xenbus/xenbus_probe_frontend.c
+++ b/drivers/xen/xenbus/xenbus_probe_frontend.c
@@ -91,14 +91,14 @@ static void backend_changed(struct xenbus_watch *watch,
xenbus_otherend_changed(watch, path, token, 1);
}
-static void xenbus_frontend_delayed_resume(struct work_struct *w)
+static void xenbus_frontend_delayed_restore(struct work_struct *w)
{
struct xenbus_device *xdev = container_of(w, struct xenbus_device, work);
- xenbus_dev_resume(&xdev->dev);
+ xenbus_dev_restore(&xdev->dev);
}
-static int xenbus_frontend_dev_resume(struct device *dev)
+static int xenbus_frontend_dev_restore(struct device *dev)
{
/*
* If xenstored is running in this domain, we cannot access the backend
@@ -112,14 +112,14 @@ static int xenbus_frontend_dev_resume(struct device *dev)
return 0;
}
- return xenbus_dev_resume(dev);
+ return xenbus_dev_restore(dev);
}
static int xenbus_frontend_dev_probe(struct device *dev)
{
if (xen_store_domain_type == XS_LOCAL) {
struct xenbus_device *xdev = to_xenbus_device(dev);
- INIT_WORK(&xdev->work, xenbus_frontend_delayed_resume);
+ INIT_WORK(&xdev->work, xenbus_frontend_delayed_restore);
}
return xenbus_dev_probe(dev);
@@ -148,11 +148,9 @@ static void xenbus_frontend_dev_shutdown(struct device *_dev)
}
static const struct dev_pm_ops xenbus_pm_ops = {
- .suspend = xenbus_dev_suspend,
- .resume = xenbus_frontend_dev_resume,
- .freeze = xenbus_dev_suspend,
- .thaw = xenbus_dev_cancel,
- .restore = xenbus_dev_resume,
+ .freeze = xenbus_dev_freeze,
+ .thaw = xenbus_dev_thaw,
+ .restore = xenbus_frontend_dev_restore,
};
static struct xen_bus_type xenbus_frontend = {