Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] master from torvalds:master #92

Merged
merged 15 commits into from
Jul 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion arch/arm/xen/enlighten.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,6 @@ static int __init fdt_find_hyper_node(unsigned long node, const char *uname,
* see Documentation/devicetree/bindings/arm/xen.txt for the
* documentation of the Xen Device Tree format.
*/
#define GRANT_TABLE_PHYSADDR 0
void __init xen_early_init(void)
{
of_scan_flat_dt(fdt_find_hyper_node, NULL);
Expand Down
167 changes: 81 additions & 86 deletions drivers/xen/xenbus/xenbus_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,27 @@ struct xenbus_map_node {
unsigned int nr_handles;
};

struct map_ring_valloc {
struct xenbus_map_node *node;

/* Why do we need two arrays? See comment of __xenbus_map_ring */
union {
unsigned long addrs[XENBUS_MAX_RING_GRANTS];
pte_t *ptes[XENBUS_MAX_RING_GRANTS];
};
phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS];

struct gnttab_map_grant_ref map[XENBUS_MAX_RING_GRANTS];
struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_GRANTS];

unsigned int idx; /* HVM only. */
};

static DEFINE_SPINLOCK(xenbus_valloc_lock);
static LIST_HEAD(xenbus_valloc_pages);

struct xenbus_ring_ops {
int (*map)(struct xenbus_device *dev,
int (*map)(struct xenbus_device *dev, struct map_ring_valloc *info,
grant_ref_t *gnt_refs, unsigned int nr_grefs,
void **vaddr);
int (*unmap)(struct xenbus_device *dev, void *vaddr);
Expand Down Expand Up @@ -440,21 +456,33 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn);
* Map @nr_grefs pages of memory into this domain from another
* domain's grant table. xenbus_map_ring_valloc allocates @nr_grefs
* pages of virtual address space, maps the pages to that address, and
* sets *vaddr to that address. Returns 0 on success, and GNTST_*
* (see xen/include/interface/grant_table.h) or -ENOMEM / -EINVAL on
* sets *vaddr to that address. Returns 0 on success, and -errno on
* error. If an error is returned, device will switch to
* XenbusStateClosing and the error message will be saved in XenStore.
*/
int xenbus_map_ring_valloc(struct xenbus_device *dev, grant_ref_t *gnt_refs,
unsigned int nr_grefs, void **vaddr)
{
int err;
struct map_ring_valloc *info;

*vaddr = NULL;

if (nr_grefs > XENBUS_MAX_RING_GRANTS)
return -EINVAL;

info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;

err = ring_ops->map(dev, gnt_refs, nr_grefs, vaddr);
/* Some hypervisors are buggy and can return 1. */
if (err > 0)
err = GNTST_general_error;
info->node = kzalloc(sizeof(*info->node), GFP_KERNEL);
if (!info->node)
err = -ENOMEM;
else
err = ring_ops->map(dev, info, gnt_refs, nr_grefs, vaddr);

kfree(info->node);
kfree(info);
return err;
}
EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc);
Expand All @@ -466,62 +494,57 @@ static int __xenbus_map_ring(struct xenbus_device *dev,
grant_ref_t *gnt_refs,
unsigned int nr_grefs,
grant_handle_t *handles,
phys_addr_t *addrs,
struct map_ring_valloc *info,
unsigned int flags,
bool *leaked)
{
struct gnttab_map_grant_ref map[XENBUS_MAX_RING_GRANTS];
struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_GRANTS];
int i, j;
int err = GNTST_okay;

if (nr_grefs > XENBUS_MAX_RING_GRANTS)
return -EINVAL;

for (i = 0; i < nr_grefs; i++) {
memset(&map[i], 0, sizeof(map[i]));
gnttab_set_map_op(&map[i], addrs[i], flags, gnt_refs[i],
dev->otherend_id);
gnttab_set_map_op(&info->map[i], info->phys_addrs[i], flags,
gnt_refs[i], dev->otherend_id);
handles[i] = INVALID_GRANT_HANDLE;
}

gnttab_batch_map(map, i);
gnttab_batch_map(info->map, i);

for (i = 0; i < nr_grefs; i++) {
if (map[i].status != GNTST_okay) {
err = map[i].status;
xenbus_dev_fatal(dev, map[i].status,
if (info->map[i].status != GNTST_okay) {
xenbus_dev_fatal(dev, info->map[i].status,
"mapping in shared page %d from domain %d",
gnt_refs[i], dev->otherend_id);
goto fail;
} else
handles[i] = map[i].handle;
handles[i] = info->map[i].handle;
}

return GNTST_okay;
return 0;

fail:
for (i = j = 0; i < nr_grefs; i++) {
if (handles[i] != INVALID_GRANT_HANDLE) {
memset(&unmap[j], 0, sizeof(unmap[j]));
gnttab_set_unmap_op(&unmap[j], (phys_addr_t)addrs[i],
gnttab_set_unmap_op(&info->unmap[j],
info->phys_addrs[i],
GNTMAP_host_map, handles[i]);
j++;
}
}

if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap, j))
if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, info->unmap, j))
BUG();

*leaked = false;
for (i = 0; i < j; i++) {
if (unmap[i].status != GNTST_okay) {
if (info->unmap[i].status != GNTST_okay) {
*leaked = true;
break;
}
}

return err;
return -ENOENT;
}

/**
Expand Down Expand Up @@ -566,21 +589,12 @@ static int xenbus_unmap_ring(struct xenbus_device *dev, grant_handle_t *handles,
return err;
}

struct map_ring_valloc_hvm
{
unsigned int idx;

/* Why do we need two arrays? See comment of __xenbus_map_ring */
phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS];
unsigned long addrs[XENBUS_MAX_RING_GRANTS];
};

static void xenbus_map_ring_setup_grant_hvm(unsigned long gfn,
unsigned int goffset,
unsigned int len,
void *data)
{
struct map_ring_valloc_hvm *info = data;
struct map_ring_valloc *info = data;
unsigned long vaddr = (unsigned long)gfn_to_virt(gfn);

info->phys_addrs[info->idx] = vaddr;
Expand All @@ -589,39 +603,28 @@ static void xenbus_map_ring_setup_grant_hvm(unsigned long gfn,
info->idx++;
}

static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
grant_ref_t *gnt_ref,
unsigned int nr_grefs,
void **vaddr)
static int xenbus_map_ring_hvm(struct xenbus_device *dev,
struct map_ring_valloc *info,
grant_ref_t *gnt_ref,
unsigned int nr_grefs,
void **vaddr)
{
struct xenbus_map_node *node;
struct xenbus_map_node *node = info->node;
int err;
void *addr;
bool leaked = false;
struct map_ring_valloc_hvm info = {
.idx = 0,
};
unsigned int nr_pages = XENBUS_PAGES(nr_grefs);

if (nr_grefs > XENBUS_MAX_RING_GRANTS)
return -EINVAL;

*vaddr = NULL;

node = kzalloc(sizeof(*node), GFP_KERNEL);
if (!node)
return -ENOMEM;

err = alloc_xenballooned_pages(nr_pages, node->hvm.pages);
if (err)
goto out_err;

gnttab_foreach_grant(node->hvm.pages, nr_grefs,
xenbus_map_ring_setup_grant_hvm,
&info);
info);

err = __xenbus_map_ring(dev, gnt_ref, nr_grefs, node->handles,
info.phys_addrs, GNTMAP_host_map, &leaked);
info, GNTMAP_host_map, &leaked);
node->nr_handles = nr_grefs;

if (err)
Expand All @@ -641,19 +644,20 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
spin_unlock(&xenbus_valloc_lock);

*vaddr = addr;
info->node = NULL;

return 0;

out_xenbus_unmap_ring:
if (!leaked)
xenbus_unmap_ring(dev, node->handles, nr_grefs, info.addrs);
xenbus_unmap_ring(dev, node->handles, nr_grefs, info->addrs);
else
pr_alert("leaking %p size %u page(s)",
addr, nr_pages);
out_free_ballooned_pages:
if (!leaked)
free_xenballooned_pages(nr_pages, node->hvm.pages);
out_err:
kfree(node);
return err;
}

Expand All @@ -676,40 +680,30 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree);

#ifdef CONFIG_XEN_PV
static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev,
grant_ref_t *gnt_refs,
unsigned int nr_grefs,
void **vaddr)
static int xenbus_map_ring_pv(struct xenbus_device *dev,
struct map_ring_valloc *info,
grant_ref_t *gnt_refs,
unsigned int nr_grefs,
void **vaddr)
{
struct xenbus_map_node *node;
struct xenbus_map_node *node = info->node;
struct vm_struct *area;
pte_t *ptes[XENBUS_MAX_RING_GRANTS];
phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS];
int err = GNTST_okay;
int i;
bool leaked;

*vaddr = NULL;

if (nr_grefs > XENBUS_MAX_RING_GRANTS)
return -EINVAL;

node = kzalloc(sizeof(*node), GFP_KERNEL);
if (!node)
return -ENOMEM;

area = alloc_vm_area(XEN_PAGE_SIZE * nr_grefs, ptes);
area = alloc_vm_area(XEN_PAGE_SIZE * nr_grefs, info->ptes);
if (!area) {
kfree(node);
return -ENOMEM;
}

for (i = 0; i < nr_grefs; i++)
phys_addrs[i] = arbitrary_virt_to_machine(ptes[i]).maddr;
info->phys_addrs[i] =
arbitrary_virt_to_machine(info->ptes[i]).maddr;

err = __xenbus_map_ring(dev, gnt_refs, nr_grefs, node->handles,
phys_addrs,
GNTMAP_host_map | GNTMAP_contains_pte,
info, GNTMAP_host_map | GNTMAP_contains_pte,
&leaked);
if (err)
goto failed;
Expand All @@ -722,6 +716,8 @@ static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev,
spin_unlock(&xenbus_valloc_lock);

*vaddr = area->addr;
info->node = NULL;

return 0;

failed:
Expand All @@ -730,11 +726,10 @@ static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev,
else
pr_alert("leaking VM area %p size %u page(s)", area, nr_grefs);

kfree(node);
return err;
}

static int xenbus_unmap_ring_vfree_pv(struct xenbus_device *dev, void *vaddr)
static int xenbus_unmap_ring_pv(struct xenbus_device *dev, void *vaddr)
{
struct xenbus_map_node *node;
struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_GRANTS];
Expand Down Expand Up @@ -798,12 +793,12 @@ static int xenbus_unmap_ring_vfree_pv(struct xenbus_device *dev, void *vaddr)
}

static const struct xenbus_ring_ops ring_ops_pv = {
.map = xenbus_map_ring_valloc_pv,
.unmap = xenbus_unmap_ring_vfree_pv,
.map = xenbus_map_ring_pv,
.unmap = xenbus_unmap_ring_pv,
};
#endif

struct unmap_ring_vfree_hvm
struct unmap_ring_hvm
{
unsigned int idx;
unsigned long addrs[XENBUS_MAX_RING_GRANTS];
Expand All @@ -814,19 +809,19 @@ static void xenbus_unmap_ring_setup_grant_hvm(unsigned long gfn,
unsigned int len,
void *data)
{
struct unmap_ring_vfree_hvm *info = data;
struct unmap_ring_hvm *info = data;

info->addrs[info->idx] = (unsigned long)gfn_to_virt(gfn);

info->idx++;
}

static int xenbus_unmap_ring_vfree_hvm(struct xenbus_device *dev, void *vaddr)
static int xenbus_unmap_ring_hvm(struct xenbus_device *dev, void *vaddr)
{
int rv;
struct xenbus_map_node *node;
void *addr;
struct unmap_ring_vfree_hvm info = {
struct unmap_ring_hvm info = {
.idx = 0,
};
unsigned int nr_pages;
Expand Down Expand Up @@ -887,8 +882,8 @@ enum xenbus_state xenbus_read_driver_state(const char *path)
EXPORT_SYMBOL_GPL(xenbus_read_driver_state);

static const struct xenbus_ring_ops ring_ops_hvm = {
.map = xenbus_map_ring_valloc_hvm,
.unmap = xenbus_unmap_ring_vfree_hvm,
.map = xenbus_map_ring_hvm,
.unmap = xenbus_unmap_ring_hvm,
};

void __init xenbus_ring_ops_init(void)
Expand Down
6 changes: 5 additions & 1 deletion fs/cifs/cifs_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,14 +399,18 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
if (ses->sign)
seq_puts(m, " signed");

seq_printf(m, "\n\tUser: %d Cred User: %d",
from_kuid(&init_user_ns, ses->linux_uid),
from_kuid(&init_user_ns, ses->cred_uid));

if (ses->chan_count > 1) {
seq_printf(m, "\n\n\tExtra Channels: %zu\n",
ses->chan_count-1);
for (j = 1; j < ses->chan_count; j++)
cifs_dump_channel(m, j, &ses->chans[j]);
}

seq_puts(m, "\n\tShares:");
seq_puts(m, "\n\n\tShares:");
j = 0;

seq_printf(m, "\n\t%d) IPC: ", j);
Expand Down
Loading