mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 20:46:48 +02:00
xen: branch for v6.17-rc1
-----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRTLbB6QfY48x44uB6AXGG7T9hjvgUCaIcSAAAKCRCAXGG7T9hj vkIzAP9Vj3dbVO/VPkI95youc1mDyHGDU0CqaATi53IBMsFCeAEA3Rrp4L685UOF kI/YesO/T5XhRGEEMkZi2nqyLFErNgY= =9zFJ -----END PGP SIGNATURE----- Merge tag 'for-linus-6.17-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip Pull xen updates from Juergen Gross: - fix for a UAF in the xen gntdev-dmabuf driver - fix in the xen netfront driver avoiding spurious interrupts - fix in the gntdev driver avoiding a large stack allocation - cleanup removing some dead code - build warning fix - cleanup of the sysfs code in the xen-pciback driver * tag 'for-linus-6.17-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen/netfront: Fix TX response spurious interrupts xen/gntdev: remove struct gntdev_copy_batch from stack xen: fix UAF in dmabuf_exp_from_pages() xen: Remove some deadcode (x) xen-pciback: Replace scnprintf() with sysfs_emit_at() xen/xenbus: fix W=1 build warning in xenbus_va_dev_error function
This commit is contained in:
commit
7d767a9528
|
|
@ -638,8 +638,6 @@ static int xennet_xdp_xmit_one(struct net_device *dev,
|
|||
tx_stats->packets++;
|
||||
u64_stats_update_end(&tx_stats->syncp);
|
||||
|
||||
xennet_tx_buf_gc(queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -849,9 +847,6 @@ static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev
|
|||
tx_stats->packets++;
|
||||
u64_stats_update_end(&tx_stats->syncp);
|
||||
|
||||
/* Note: It is not safe to access skb after xennet_tx_buf_gc()! */
|
||||
xennet_tx_buf_gc(queue);
|
||||
|
||||
if (!netfront_tx_slot_available(queue))
|
||||
netif_tx_stop_queue(netdev_get_tx_queue(dev, queue->id));
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ struct gntdev_priv {
|
|||
/* lock protects maps and freeable_maps. */
|
||||
struct mutex lock;
|
||||
|
||||
/* Free instances of struct gntdev_copy_batch. */
|
||||
struct gntdev_copy_batch *batch;
|
||||
struct mutex batch_lock;
|
||||
|
||||
#ifdef CONFIG_XEN_GRANT_DMA_ALLOC
|
||||
/* Device for which DMA memory is allocated. */
|
||||
struct device *dma_dev;
|
||||
|
|
|
|||
|
|
@ -357,8 +357,11 @@ struct gntdev_dmabuf_export_args {
|
|||
static int dmabuf_exp_from_pages(struct gntdev_dmabuf_export_args *args)
|
||||
{
|
||||
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
|
||||
struct gntdev_dmabuf *gntdev_dmabuf;
|
||||
int ret;
|
||||
struct gntdev_dmabuf *gntdev_dmabuf __free(kfree) = NULL;
|
||||
CLASS(get_unused_fd, ret)(O_CLOEXEC);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
gntdev_dmabuf = kzalloc(sizeof(*gntdev_dmabuf), GFP_KERNEL);
|
||||
if (!gntdev_dmabuf)
|
||||
|
|
@ -383,32 +386,21 @@ static int dmabuf_exp_from_pages(struct gntdev_dmabuf_export_args *args)
|
|||
exp_info.priv = gntdev_dmabuf;
|
||||
|
||||
gntdev_dmabuf->dmabuf = dma_buf_export(&exp_info);
|
||||
if (IS_ERR(gntdev_dmabuf->dmabuf)) {
|
||||
ret = PTR_ERR(gntdev_dmabuf->dmabuf);
|
||||
gntdev_dmabuf->dmabuf = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = dma_buf_fd(gntdev_dmabuf->dmabuf, O_CLOEXEC);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
if (IS_ERR(gntdev_dmabuf->dmabuf))
|
||||
return PTR_ERR(gntdev_dmabuf->dmabuf);
|
||||
|
||||
gntdev_dmabuf->fd = ret;
|
||||
args->fd = ret;
|
||||
|
||||
pr_debug("Exporting DMA buffer with fd %d\n", ret);
|
||||
|
||||
get_file(gntdev_dmabuf->priv->filp);
|
||||
mutex_lock(&args->dmabuf_priv->lock);
|
||||
list_add(&gntdev_dmabuf->next, &args->dmabuf_priv->exp_list);
|
||||
mutex_unlock(&args->dmabuf_priv->lock);
|
||||
get_file(gntdev_dmabuf->priv->filp);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (gntdev_dmabuf->dmabuf)
|
||||
dma_buf_put(gntdev_dmabuf->dmabuf);
|
||||
kfree(gntdev_dmabuf);
|
||||
return ret;
|
||||
fd_install(take_fd(ret), no_free_ptr(gntdev_dmabuf)->dmabuf->file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct gntdev_grant_map *
|
||||
|
|
|
|||
|
|
@ -56,6 +56,18 @@ MODULE_AUTHOR("Derek G. Murray <Derek.Murray@cl.cam.ac.uk>, "
|
|||
"Gerd Hoffmann <kraxel@redhat.com>");
|
||||
MODULE_DESCRIPTION("User-space granted page access driver");
|
||||
|
||||
#define GNTDEV_COPY_BATCH 16
|
||||
|
||||
struct gntdev_copy_batch {
|
||||
struct gnttab_copy ops[GNTDEV_COPY_BATCH];
|
||||
struct page *pages[GNTDEV_COPY_BATCH];
|
||||
s16 __user *status[GNTDEV_COPY_BATCH];
|
||||
unsigned int nr_ops;
|
||||
unsigned int nr_pages;
|
||||
bool writeable;
|
||||
struct gntdev_copy_batch *next;
|
||||
};
|
||||
|
||||
static unsigned int limit = 64*1024;
|
||||
module_param(limit, uint, 0644);
|
||||
MODULE_PARM_DESC(limit,
|
||||
|
|
@ -584,6 +596,8 @@ static int gntdev_open(struct inode *inode, struct file *flip)
|
|||
INIT_LIST_HEAD(&priv->maps);
|
||||
mutex_init(&priv->lock);
|
||||
|
||||
mutex_init(&priv->batch_lock);
|
||||
|
||||
#ifdef CONFIG_XEN_GNTDEV_DMABUF
|
||||
priv->dmabuf_priv = gntdev_dmabuf_init(flip);
|
||||
if (IS_ERR(priv->dmabuf_priv)) {
|
||||
|
|
@ -608,6 +622,7 @@ static int gntdev_release(struct inode *inode, struct file *flip)
|
|||
{
|
||||
struct gntdev_priv *priv = flip->private_data;
|
||||
struct gntdev_grant_map *map;
|
||||
struct gntdev_copy_batch *batch;
|
||||
|
||||
pr_debug("priv %p\n", priv);
|
||||
|
||||
|
|
@ -620,6 +635,14 @@ static int gntdev_release(struct inode *inode, struct file *flip)
|
|||
}
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
mutex_lock(&priv->batch_lock);
|
||||
while (priv->batch) {
|
||||
batch = priv->batch;
|
||||
priv->batch = batch->next;
|
||||
kfree(batch);
|
||||
}
|
||||
mutex_unlock(&priv->batch_lock);
|
||||
|
||||
#ifdef CONFIG_XEN_GNTDEV_DMABUF
|
||||
gntdev_dmabuf_fini(priv->dmabuf_priv);
|
||||
#endif
|
||||
|
|
@ -785,17 +808,6 @@ static long gntdev_ioctl_notify(struct gntdev_priv *priv, void __user *u)
|
|||
return rc;
|
||||
}
|
||||
|
||||
#define GNTDEV_COPY_BATCH 16
|
||||
|
||||
struct gntdev_copy_batch {
|
||||
struct gnttab_copy ops[GNTDEV_COPY_BATCH];
|
||||
struct page *pages[GNTDEV_COPY_BATCH];
|
||||
s16 __user *status[GNTDEV_COPY_BATCH];
|
||||
unsigned int nr_ops;
|
||||
unsigned int nr_pages;
|
||||
bool writeable;
|
||||
};
|
||||
|
||||
static int gntdev_get_page(struct gntdev_copy_batch *batch, void __user *virt,
|
||||
unsigned long *gfn)
|
||||
{
|
||||
|
|
@ -953,36 +965,53 @@ static int gntdev_grant_copy_seg(struct gntdev_copy_batch *batch,
|
|||
static long gntdev_ioctl_grant_copy(struct gntdev_priv *priv, void __user *u)
|
||||
{
|
||||
struct ioctl_gntdev_grant_copy copy;
|
||||
struct gntdev_copy_batch batch;
|
||||
struct gntdev_copy_batch *batch;
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
|
||||
if (copy_from_user(©, u, sizeof(copy)))
|
||||
return -EFAULT;
|
||||
|
||||
batch.nr_ops = 0;
|
||||
batch.nr_pages = 0;
|
||||
mutex_lock(&priv->batch_lock);
|
||||
if (!priv->batch) {
|
||||
batch = kmalloc(sizeof(*batch), GFP_KERNEL);
|
||||
} else {
|
||||
batch = priv->batch;
|
||||
priv->batch = batch->next;
|
||||
}
|
||||
mutex_unlock(&priv->batch_lock);
|
||||
if (!batch)
|
||||
return -ENOMEM;
|
||||
|
||||
batch->nr_ops = 0;
|
||||
batch->nr_pages = 0;
|
||||
|
||||
for (i = 0; i < copy.count; i++) {
|
||||
struct gntdev_grant_copy_segment seg;
|
||||
|
||||
if (copy_from_user(&seg, ©.segments[i], sizeof(seg))) {
|
||||
ret = -EFAULT;
|
||||
gntdev_put_pages(batch);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = gntdev_grant_copy_seg(&batch, &seg, ©.segments[i].status);
|
||||
if (ret < 0)
|
||||
ret = gntdev_grant_copy_seg(batch, &seg, ©.segments[i].status);
|
||||
if (ret < 0) {
|
||||
gntdev_put_pages(batch);
|
||||
goto out;
|
||||
}
|
||||
|
||||
cond_resched();
|
||||
}
|
||||
if (batch.nr_ops)
|
||||
ret = gntdev_copy(&batch);
|
||||
return ret;
|
||||
if (batch->nr_ops)
|
||||
ret = gntdev_copy(batch);
|
||||
|
||||
out:
|
||||
mutex_lock(&priv->batch_lock);
|
||||
batch->next = priv->batch;
|
||||
priv->batch = batch;
|
||||
mutex_unlock(&priv->batch_lock);
|
||||
|
||||
out:
|
||||
gntdev_put_pages(&batch);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,12 +52,6 @@ void xen_resume_notifier_register(struct notifier_block *nb)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(xen_resume_notifier_register);
|
||||
|
||||
void xen_resume_notifier_unregister(struct notifier_block *nb)
|
||||
{
|
||||
raw_notifier_chain_unregister(&xen_resume_notifier, nb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister);
|
||||
|
||||
#ifdef CONFIG_HIBERNATE_CALLBACKS
|
||||
static int xen_suspend(void *data)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -136,14 +136,6 @@ void xen_manage_runstate_time(int action)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Runstate accounting
|
||||
*/
|
||||
void xen_get_runstate_snapshot(struct vcpu_runstate_info *res)
|
||||
{
|
||||
xen_get_runstate_snapshot_cpu(res, smp_processor_id());
|
||||
}
|
||||
|
||||
/* return true when a vcpu could run but has no real cpu to run on */
|
||||
bool xen_vcpu_stolen(int vcpu)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1261,7 +1261,7 @@ static ssize_t slots_show(struct device_driver *drv, char *buf)
|
|||
if (count >= PAGE_SIZE)
|
||||
break;
|
||||
|
||||
count += scnprintf(buf + count, PAGE_SIZE - count,
|
||||
count += sysfs_emit_at(buf, count,
|
||||
"%04x:%02x:%02x.%d\n",
|
||||
pci_dev_id->domain, pci_dev_id->bus,
|
||||
PCI_SLOT(pci_dev_id->devfn),
|
||||
|
|
@ -1290,7 +1290,7 @@ static ssize_t irq_handlers_show(struct device_driver *drv, char *buf)
|
|||
if (!dev_data)
|
||||
continue;
|
||||
count +=
|
||||
scnprintf(buf + count, PAGE_SIZE - count,
|
||||
sysfs_emit_at(buf, count,
|
||||
"%s:%s:%sing:%ld\n",
|
||||
pci_name(psdev->dev),
|
||||
dev_data->isr_on ? "on" : "off",
|
||||
|
|
@ -1375,7 +1375,7 @@ static ssize_t quirks_show(struct device_driver *drv, char *buf)
|
|||
if (count >= PAGE_SIZE)
|
||||
goto out;
|
||||
|
||||
count += scnprintf(buf + count, PAGE_SIZE - count,
|
||||
count += sysfs_emit_at(buf, count,
|
||||
"%02x:%02x.%01x\n\t%04x:%04x:%04x:%04x\n",
|
||||
quirk->pdev->bus->number,
|
||||
PCI_SLOT(quirk->pdev->devfn),
|
||||
|
|
@ -1391,7 +1391,7 @@ static ssize_t quirks_show(struct device_driver *drv, char *buf)
|
|||
if (count >= PAGE_SIZE)
|
||||
goto out;
|
||||
|
||||
count += scnprintf(buf + count, PAGE_SIZE - count,
|
||||
count += sysfs_emit_at(buf, count,
|
||||
"\t\t%08x:%01x:%08x\n",
|
||||
cfg_entry->base_offset +
|
||||
field->offset, field->size,
|
||||
|
|
@ -1462,7 +1462,7 @@ static ssize_t permissive_show(struct device_driver *drv, char *buf)
|
|||
if (!dev_data || !dev_data->permissive)
|
||||
continue;
|
||||
count +=
|
||||
scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
|
||||
sysfs_emit_at(buf, count, "%s\n",
|
||||
pci_name(psdev->dev));
|
||||
}
|
||||
spin_unlock_irqrestore(&pcistub_devices_lock, flags);
|
||||
|
|
@ -1521,7 +1521,7 @@ static ssize_t allow_interrupt_control_show(struct device_driver *drv,
|
|||
if (!dev_data || !dev_data->allow_interrupt_control)
|
||||
continue;
|
||||
count +=
|
||||
scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
|
||||
sysfs_emit_at(buf, count, "%s\n",
|
||||
pci_name(psdev->dev));
|
||||
}
|
||||
spin_unlock_irqrestore(&pcistub_devices_lock, flags);
|
||||
|
|
|
|||
|
|
@ -202,6 +202,7 @@ int xenbus_watch_pathfmt(struct xenbus_device *dev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(xenbus_watch_pathfmt);
|
||||
|
||||
__printf(4, 5)
|
||||
static void xenbus_switch_fatal(struct xenbus_device *, int, int,
|
||||
const char *, ...);
|
||||
|
||||
|
|
@ -287,6 +288,7 @@ int xenbus_frontend_closed(struct xenbus_device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(xenbus_frontend_closed);
|
||||
|
||||
__printf(3, 0)
|
||||
static void xenbus_va_dev_error(struct xenbus_device *dev, int err,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -512,23 +512,6 @@ int xenbus_write(struct xenbus_transaction t,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(xenbus_write);
|
||||
|
||||
/* Create a new directory. */
|
||||
int xenbus_mkdir(struct xenbus_transaction t,
|
||||
const char *dir, const char *node)
|
||||
{
|
||||
char *path;
|
||||
int ret;
|
||||
|
||||
path = join(dir, node);
|
||||
if (IS_ERR(path))
|
||||
return PTR_ERR(path);
|
||||
|
||||
ret = xs_error(xs_single(t, XS_MKDIR, path, NULL));
|
||||
kfree(path);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xenbus_mkdir);
|
||||
|
||||
/* Destroy a file or directory (directories must be empty). */
|
||||
int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,13 +30,11 @@ void xen_arch_suspend(void);
|
|||
void xen_reboot(int reason);
|
||||
|
||||
void xen_resume_notifier_register(struct notifier_block *nb);
|
||||
void xen_resume_notifier_unregister(struct notifier_block *nb);
|
||||
|
||||
bool xen_vcpu_stolen(int vcpu);
|
||||
void xen_setup_runstate_info(int cpu);
|
||||
void xen_time_setup_guest(void);
|
||||
void xen_manage_runstate_time(int action);
|
||||
void xen_get_runstate_snapshot(struct vcpu_runstate_info *res);
|
||||
u64 xen_steal_clock(int cpu);
|
||||
|
||||
int xen_setup_shutdown_event(void);
|
||||
|
|
|
|||
|
|
@ -154,8 +154,6 @@ void *xenbus_read(struct xenbus_transaction t,
|
|||
const char *dir, const char *node, unsigned int *len);
|
||||
int xenbus_write(struct xenbus_transaction t,
|
||||
const char *dir, const char *node, const char *string);
|
||||
int xenbus_mkdir(struct xenbus_transaction t,
|
||||
const char *dir, const char *node);
|
||||
int xenbus_exists(struct xenbus_transaction t,
|
||||
const char *dir, const char *node);
|
||||
int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user