Skip to content

Commit e514181

Browse files
committed
Merge tag 'for-linus-5.9-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen updates from Juergen Gross: - two trivial comment fixes - a small series for the Xen balloon driver fixing some issues - a series of the Xen privcmd driver targeting elimination of using get_user_pages*() in this driver - a series for the Xen swiotlb driver cleaning it up and adding support for letting the kernel run as dom0 on Rpi4 * tag 'for-linus-5.9-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen/arm: call dma_to_phys on the dma_addr_t parameter of dma_cache_maint xen/arm: introduce phys/dma translations in xen_dma_sync_for_* swiotlb-xen: introduce phys_to_dma/dma_to_phys translations swiotlb-xen: remove XEN_PFN_PHYS swiotlb-xen: add struct device * parameter to is_xen_swiotlb_buffer swiotlb-xen: add struct device * parameter to xen_dma_sync_for_device swiotlb-xen: add struct device * parameter to xen_dma_sync_for_cpu swiotlb-xen: add struct device * parameter to xen_bus_to_phys swiotlb-xen: add struct device * parameter to xen_phys_to_bus swiotlb-xen: remove start_dma_addr swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses Revert "xen/balloon: Fix crash when ballooning on x86 32 bit PAE" xen/balloon: make the balloon wait interruptible xen/balloon: fix accounting in alloc_xenballooned_pages error path xen: hypercall.h: fix duplicated word xen/gntdev: gntdev.h: drop a duplicated word xen/privcmd: Convert get_user_pages*() to pin_user_pages*() xen/privcmd: Mark pages as dirty xen/privcmd: Corrected error handling path
2 parents 25d8d4e + d7b461c commit e514181

File tree

8 files changed

+119
-105
lines changed

8 files changed

+119
-105
lines changed

arch/arm/xen/mm.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
#include <linux/cpu.h>
3+
#include <linux/dma-direct.h>
34
#include <linux/dma-noncoherent.h>
45
#include <linux/gfp.h>
56
#include <linux/highmem.h>
@@ -42,15 +43,18 @@ unsigned long xen_get_swiotlb_free_pages(unsigned int order)
4243
static bool hypercall_cflush = false;
4344

4445
/* buffers in highmem or foreign pages cannot cross page boundaries */
45-
static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op)
46+
static void dma_cache_maint(struct device *dev, dma_addr_t handle,
47+
size_t size, u32 op)
4648
{
4749
struct gnttab_cache_flush cflush;
4850

49-
cflush.a.dev_bus_addr = handle & XEN_PAGE_MASK;
5051
cflush.offset = xen_offset_in_page(handle);
5152
cflush.op = op;
53+
handle &= XEN_PAGE_MASK;
5254

5355
do {
56+
cflush.a.dev_bus_addr = dma_to_phys(dev, handle);
57+
5458
if (size + cflush.offset > XEN_PAGE_SIZE)
5559
cflush.length = XEN_PAGE_SIZE - cflush.offset;
5660
else
@@ -59,7 +63,7 @@ static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op)
5963
HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1);
6064

6165
cflush.offset = 0;
62-
cflush.a.dev_bus_addr += cflush.length;
66+
handle += cflush.length;
6367
size -= cflush.length;
6468
} while (size);
6569
}
@@ -71,32 +75,28 @@ static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op)
7175
* pfn_valid returns true the pages is local and we can use the native
7276
* dma-direct functions, otherwise we call the Xen specific version.
7377
*/
74-
void xen_dma_sync_for_cpu(dma_addr_t handle, phys_addr_t paddr, size_t size,
75-
enum dma_data_direction dir)
78+
void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle,
79+
size_t size, enum dma_data_direction dir)
7680
{
77-
if (pfn_valid(PFN_DOWN(handle)))
78-
arch_sync_dma_for_cpu(paddr, size, dir);
79-
else if (dir != DMA_TO_DEVICE)
80-
dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
81+
if (dir != DMA_TO_DEVICE)
82+
dma_cache_maint(dev, handle, size, GNTTAB_CACHE_INVAL);
8183
}
8284

83-
void xen_dma_sync_for_device(dma_addr_t handle, phys_addr_t paddr, size_t size,
84-
enum dma_data_direction dir)
85+
void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle,
86+
size_t size, enum dma_data_direction dir)
8587
{
86-
if (pfn_valid(PFN_DOWN(handle)))
87-
arch_sync_dma_for_device(paddr, size, dir);
88-
else if (dir == DMA_FROM_DEVICE)
89-
dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
88+
if (dir == DMA_FROM_DEVICE)
89+
dma_cache_maint(dev, handle, size, GNTTAB_CACHE_INVAL);
9090
else
91-
dma_cache_maint(handle, size, GNTTAB_CACHE_CLEAN);
91+
dma_cache_maint(dev, handle, size, GNTTAB_CACHE_CLEAN);
9292
}
9393

9494
bool xen_arch_need_swiotlb(struct device *dev,
9595
phys_addr_t phys,
9696
dma_addr_t dev_addr)
9797
{
9898
unsigned int xen_pfn = XEN_PFN_DOWN(phys);
99-
unsigned int bfn = XEN_PFN_DOWN(dev_addr);
99+
unsigned int bfn = XEN_PFN_DOWN(dma_to_phys(dev, dev_addr));
100100

101101
/*
102102
* The swiotlb buffer should be used if

arch/x86/include/asm/xen/hypercall.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ struct xen_dm_op_buf;
8282
* - clobber the rest
8383
*
8484
* The result certainly isn't pretty, and it really shows up cpp's
85-
* weakness as as macro language. Sorry. (But let's just give thanks
85+
* weakness as a macro language. Sorry. (But let's just give thanks
8686
* there aren't more than 5 arguments...)
8787
*/
8888

drivers/xen/balloon.c

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -266,20 +266,6 @@ static struct resource *additional_memory_resource(phys_addr_t size)
266266
return NULL;
267267
}
268268

269-
#ifdef CONFIG_SPARSEMEM
270-
{
271-
unsigned long limit = 1UL << (MAX_PHYSMEM_BITS - PAGE_SHIFT);
272-
unsigned long pfn = res->start >> PAGE_SHIFT;
273-
274-
if (pfn > limit) {
275-
pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n",
276-
pfn, limit);
277-
release_memory_resource(res);
278-
return NULL;
279-
}
280-
}
281-
#endif
282-
283269
return res;
284270
}
285271

@@ -568,11 +554,13 @@ static int add_ballooned_pages(int nr_pages)
568554
if (xen_hotplug_unpopulated) {
569555
st = reserve_additional_memory();
570556
if (st != BP_ECANCELED) {
557+
int rc;
558+
571559
mutex_unlock(&balloon_mutex);
572-
wait_event(balloon_wq,
560+
rc = wait_event_interruptible(balloon_wq,
573561
!list_empty(&ballooned_pages));
574562
mutex_lock(&balloon_mutex);
575-
return 0;
563+
return rc ? -ENOMEM : 0;
576564
}
577565
}
578566

@@ -630,6 +618,12 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages)
630618
out_undo:
631619
mutex_unlock(&balloon_mutex);
632620
free_xenballooned_pages(pgno, pages);
621+
/*
622+
* NB: free_xenballooned_pages will only subtract pgno pages, but since
623+
* target_unpopulated is incremented with nr_pages at the start we need
624+
* to remove the remaining ones also, or accounting will be screwed.
625+
*/
626+
balloon_stats.target_unpopulated -= nr_pages - pgno;
633627
return ret;
634628
}
635629
EXPORT_SYMBOL(alloc_xenballooned_pages);

drivers/xen/privcmd.c

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -580,44 +580,37 @@ static long privcmd_ioctl_mmap_batch(
580580

581581
static int lock_pages(
582582
struct privcmd_dm_op_buf kbufs[], unsigned int num,
583-
struct page *pages[], unsigned int nr_pages)
583+
struct page *pages[], unsigned int nr_pages, unsigned int *pinned)
584584
{
585585
unsigned int i;
586586

587587
for (i = 0; i < num; i++) {
588588
unsigned int requested;
589-
int pinned;
589+
int page_count;
590590

591591
requested = DIV_ROUND_UP(
592592
offset_in_page(kbufs[i].uptr) + kbufs[i].size,
593593
PAGE_SIZE);
594594
if (requested > nr_pages)
595595
return -ENOSPC;
596596

597-
pinned = get_user_pages_fast(
597+
page_count = pin_user_pages_fast(
598598
(unsigned long) kbufs[i].uptr,
599599
requested, FOLL_WRITE, pages);
600-
if (pinned < 0)
601-
return pinned;
600+
if (page_count < 0)
601+
return page_count;
602602

603-
nr_pages -= pinned;
604-
pages += pinned;
603+
*pinned += page_count;
604+
nr_pages -= page_count;
605+
pages += page_count;
605606
}
606607

607608
return 0;
608609
}
609610

610611
static void unlock_pages(struct page *pages[], unsigned int nr_pages)
611612
{
612-
unsigned int i;
613-
614-
if (!pages)
615-
return;
616-
617-
for (i = 0; i < nr_pages; i++) {
618-
if (pages[i])
619-
put_page(pages[i]);
620-
}
613+
unpin_user_pages_dirty_lock(pages, nr_pages, true);
621614
}
622615

623616
static long privcmd_ioctl_dm_op(struct file *file, void __user *udata)
@@ -630,6 +623,7 @@ static long privcmd_ioctl_dm_op(struct file *file, void __user *udata)
630623
struct xen_dm_op_buf *xbufs = NULL;
631624
unsigned int i;
632625
long rc;
626+
unsigned int pinned = 0;
633627

634628
if (copy_from_user(&kdata, udata, sizeof(kdata)))
635629
return -EFAULT;
@@ -683,9 +677,11 @@ static long privcmd_ioctl_dm_op(struct file *file, void __user *udata)
683677
goto out;
684678
}
685679

686-
rc = lock_pages(kbufs, kdata.num, pages, nr_pages);
687-
if (rc)
680+
rc = lock_pages(kbufs, kdata.num, pages, nr_pages, &pinned);
681+
if (rc < 0) {
682+
nr_pages = pinned;
688683
goto out;
684+
}
689685

690686
for (i = 0; i < kdata.num; i++) {
691687
set_xen_guest_handle(xbufs[i].h, kbufs[i].uptr);

0 commit comments

Comments
 (0)