mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
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
This commit is contained in:
@@ -8437,6 +8437,11 @@ Kernel parameters
|
||||
save/restore/migration must be enabled to handle larger
|
||||
domains.
|
||||
|
||||
xen_console_io [XEN,EARLY]
|
||||
Boolean option to enable/disable the usage of the Xen
|
||||
console_io hypercalls to read and write to the console.
|
||||
Mostly useful for debugging and development.
|
||||
|
||||
xen_emul_unplug= [HW,X86,XEN,EARLY]
|
||||
Unplug Xen emulated devices
|
||||
Format: [unplug0,][unplug1]
|
||||
|
||||
@@ -91,10 +91,12 @@ SYM_CODE_START(pvh_start_xen)
|
||||
|
||||
leal rva(early_stack_end)(%ebp), %esp
|
||||
|
||||
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
|
||||
/* Enable PAE mode. */
|
||||
mov %cr4, %eax
|
||||
orl $X86_CR4_PAE, %eax
|
||||
mov %eax, %cr4
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/* Enable Long mode. */
|
||||
|
||||
@@ -470,7 +470,7 @@ int __init arch_xen_unpopulated_init(struct resource **res)
|
||||
* driver to know how much of the physmap is unpopulated and
|
||||
* set an accurate initial memory target.
|
||||
*/
|
||||
xen_released_pages += xen_extra_mem[i].n_pfns;
|
||||
xen_unpopulated_pages += xen_extra_mem[i].n_pfns;
|
||||
/* Zero so region is not also added to the balloon driver. */
|
||||
xen_extra_mem[i].n_pfns = 0;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,22 @@ static DEFINE_SPINLOCK(xencons_lock);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static bool xen_console_io = false;
|
||||
static int __initdata opt_console_io = -1;
|
||||
|
||||
static int __init parse_xen_console_io(char *arg)
|
||||
{
|
||||
bool val;
|
||||
int ret;
|
||||
|
||||
ret = kstrtobool(arg, &val);
|
||||
if (ret == 0)
|
||||
opt_console_io = (int)val;
|
||||
|
||||
return ret;
|
||||
}
|
||||
early_param("xen_console_io", parse_xen_console_io);
|
||||
|
||||
static struct xencons_info *vtermno_to_xencons(int vtermno)
|
||||
{
|
||||
struct xencons_info *entry, *ret = NULL;
|
||||
@@ -331,7 +347,7 @@ static int xen_initial_domain_console_init(void)
|
||||
struct xencons_info *info;
|
||||
unsigned long flags;
|
||||
|
||||
if (!xen_initial_domain())
|
||||
if (!xen_console_io)
|
||||
return -ENODEV;
|
||||
|
||||
info = vtermno_to_xencons(HVC_COOKIE);
|
||||
@@ -369,7 +385,7 @@ void xen_console_resume(void)
|
||||
{
|
||||
struct xencons_info *info = vtermno_to_xencons(HVC_COOKIE);
|
||||
if (info != NULL && info->irq) {
|
||||
if (!xen_initial_domain())
|
||||
if (!xen_console_io)
|
||||
xen_console_update_evtchn(info);
|
||||
rebind_evtchn_irq(info->evtchn, info->irq);
|
||||
}
|
||||
@@ -601,7 +617,7 @@ static int __init xen_hvc_init(void)
|
||||
if (!xen_domain())
|
||||
return -ENODEV;
|
||||
|
||||
if (xen_initial_domain()) {
|
||||
if (xen_console_io) {
|
||||
ops = &dom0_hvc_ops;
|
||||
r = xen_initial_domain_console_init();
|
||||
if (r < 0)
|
||||
@@ -647,14 +663,17 @@ static int __init xen_hvc_init(void)
|
||||
}
|
||||
device_initcall(xen_hvc_init);
|
||||
|
||||
static int xen_cons_init(void)
|
||||
static int __init xen_cons_init(void)
|
||||
{
|
||||
const struct hv_ops *ops;
|
||||
|
||||
xen_console_io = opt_console_io >= 0 ? opt_console_io :
|
||||
xen_initial_domain();
|
||||
|
||||
if (!xen_domain())
|
||||
return 0;
|
||||
|
||||
if (xen_initial_domain())
|
||||
if (xen_console_io)
|
||||
ops = &dom0_hvc_ops;
|
||||
else {
|
||||
int r;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -69,11 +69,13 @@ extern u64 xen_saved_max_mem_size;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XEN_UNPOPULATED_ALLOC
|
||||
extern unsigned long xen_unpopulated_pages;
|
||||
int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page **pages);
|
||||
void xen_free_unpopulated_pages(unsigned int nr_pages, struct page **pages);
|
||||
#include <linux/ioport.h>
|
||||
int arch_xen_unpopulated_init(struct resource **res);
|
||||
#else
|
||||
#define xen_unpopulated_pages 0UL
|
||||
#include <xen/balloon.h>
|
||||
static inline int xen_alloc_unpopulated_pages(unsigned int nr_pages,
|
||||
struct page **pages)
|
||||
|
||||
Reference in New Issue
Block a user