Skip to content

Commit ab6e1f3

Browse files
committed
Merge tag 'for-linus-4.20a-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen fixes from Juergen Gross: "Several fixes, mostly for rather recent regressions when running under Xen" * tag 'for-linus-4.20a-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen: remove size limit of privcmd-buf mapping interface xen: fix xen_qlock_wait() x86/xen: fix pv boot xen-blkfront: fix kernel panic with negotiate_mq error path xen/grant-table: Fix incorrect gnttab_dma_free_pages() pr_debug message CONFIG_XEN_PV breaks xen_create_contiguous_region on ARM
2 parents 35c5568 + 3941552 commit ab6e1f3

File tree

7 files changed

+53
-36
lines changed

7 files changed

+53
-36
lines changed

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

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include <linux/mm.h>
1010
#include <linux/device.h>
1111

12-
#include <linux/uaccess.h>
12+
#include <asm/extable.h>
1313
#include <asm/page.h>
1414
#include <asm/pgtable.h>
1515

@@ -93,12 +93,39 @@ clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
9393
*/
9494
static inline int xen_safe_write_ulong(unsigned long *addr, unsigned long val)
9595
{
96-
return __put_user(val, (unsigned long __user *)addr);
96+
int ret = 0;
97+
98+
asm volatile("1: mov %[val], %[ptr]\n"
99+
"2:\n"
100+
".section .fixup, \"ax\"\n"
101+
"3: sub $1, %[ret]\n"
102+
" jmp 2b\n"
103+
".previous\n"
104+
_ASM_EXTABLE(1b, 3b)
105+
: [ret] "+r" (ret), [ptr] "=m" (*addr)
106+
: [val] "r" (val));
107+
108+
return ret;
97109
}
98110

99-
static inline int xen_safe_read_ulong(unsigned long *addr, unsigned long *val)
111+
static inline int xen_safe_read_ulong(const unsigned long *addr,
112+
unsigned long *val)
100113
{
101-
return __get_user(*val, (unsigned long __user *)addr);
114+
int ret = 0;
115+
unsigned long rval = ~0ul;
116+
117+
asm volatile("1: mov %[ptr], %[rval]\n"
118+
"2:\n"
119+
".section .fixup, \"ax\"\n"
120+
"3: sub $1, %[ret]\n"
121+
" jmp 2b\n"
122+
".previous\n"
123+
_ASM_EXTABLE(1b, 3b)
124+
: [ret] "+r" (ret), [rval] "+r" (rval)
125+
: [ptr] "m" (*addr));
126+
*val = rval;
127+
128+
return ret;
102129
}
103130

104131
#ifdef CONFIG_XEN_PV

arch/x86/xen/p2m.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -656,8 +656,7 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
656656

657657
/*
658658
* The interface requires atomic updates on p2m elements.
659-
* xen_safe_write_ulong() is using __put_user which does an atomic
660-
* store via asm().
659+
* xen_safe_write_ulong() is using an atomic store via asm().
661660
*/
662661
if (likely(!xen_safe_write_ulong(xen_p2m_addr + pfn, mfn)))
663662
return true;

arch/x86/xen/spinlock.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/log2.h>
1010
#include <linux/gfp.h>
1111
#include <linux/slab.h>
12+
#include <linux/atomic.h>
1213

1314
#include <asm/paravirt.h>
1415
#include <asm/qspinlock.h>
@@ -21,6 +22,7 @@
2122

2223
static DEFINE_PER_CPU(int, lock_kicker_irq) = -1;
2324
static DEFINE_PER_CPU(char *, irq_name);
25+
static DEFINE_PER_CPU(atomic_t, xen_qlock_wait_nest);
2426
static bool xen_pvspin = true;
2527

2628
static void xen_qlock_kick(int cpu)
@@ -39,25 +41,25 @@ static void xen_qlock_kick(int cpu)
3941
*/
4042
static void xen_qlock_wait(u8 *byte, u8 val)
4143
{
42-
unsigned long flags;
4344
int irq = __this_cpu_read(lock_kicker_irq);
45+
atomic_t *nest_cnt = this_cpu_ptr(&xen_qlock_wait_nest);
4446

4547
/* If kicker interrupts not initialized yet, just spin */
4648
if (irq == -1 || in_nmi())
4749
return;
4850

49-
/* Guard against reentry. */
50-
local_irq_save(flags);
51+
/* Detect reentry. */
52+
atomic_inc(nest_cnt);
5153

52-
/* If irq pending already clear it. */
53-
if (xen_test_irq_pending(irq)) {
54+
/* If irq pending already and no nested call clear it. */
55+
if (atomic_read(nest_cnt) == 1 && xen_test_irq_pending(irq)) {
5456
xen_clear_irq_pending(irq);
5557
} else if (READ_ONCE(*byte) == val) {
5658
/* Block until irq becomes pending (or a spurious wakeup) */
5759
xen_poll_irq(irq);
5860
}
5961

60-
local_irq_restore(flags);
62+
atomic_dec(nest_cnt);
6163
}
6264

6365
static irqreturn_t dummy_handler(int irq, void *dev_id)

drivers/block/xen-blkfront.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,6 +1919,7 @@ static int negotiate_mq(struct blkfront_info *info)
19191919
GFP_KERNEL);
19201920
if (!info->rinfo) {
19211921
xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure");
1922+
info->nr_rings = 0;
19221923
return -ENOMEM;
19231924
}
19241925

drivers/xen/grant-table.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,7 @@ int gnttab_dma_free_pages(struct gnttab_dma_alloc_args *args)
914914

915915
ret = xenmem_reservation_increase(args->nr_pages, args->frames);
916916
if (ret != args->nr_pages) {
917-
pr_debug("Failed to decrease reservation for DMA buffer\n");
917+
pr_debug("Failed to increase reservation for DMA buffer\n");
918918
ret = -EFAULT;
919919
} else {
920920
ret = 0;

drivers/xen/privcmd-buf.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,9 @@
2121

2222
MODULE_LICENSE("GPL");
2323

24-
static unsigned int limit = 64;
25-
module_param(limit, uint, 0644);
26-
MODULE_PARM_DESC(limit, "Maximum number of pages that may be allocated by "
27-
"the privcmd-buf device per open file");
28-
2924
struct privcmd_buf_private {
3025
struct mutex lock;
3126
struct list_head list;
32-
unsigned int allocated;
3327
};
3428

3529
struct privcmd_buf_vma_private {
@@ -60,13 +54,10 @@ static void privcmd_buf_vmapriv_free(struct privcmd_buf_vma_private *vma_priv)
6054
{
6155
unsigned int i;
6256

63-
vma_priv->file_priv->allocated -= vma_priv->n_pages;
64-
6557
list_del(&vma_priv->list);
6658

6759
for (i = 0; i < vma_priv->n_pages; i++)
68-
if (vma_priv->pages[i])
69-
__free_page(vma_priv->pages[i]);
60+
__free_page(vma_priv->pages[i]);
7061

7162
kfree(vma_priv);
7263
}
@@ -146,28 +137,23 @@ static int privcmd_buf_mmap(struct file *file, struct vm_area_struct *vma)
146137
unsigned int i;
147138
int ret = 0;
148139

149-
if (!(vma->vm_flags & VM_SHARED) || count > limit ||
150-
file_priv->allocated + count > limit)
140+
if (!(vma->vm_flags & VM_SHARED))
151141
return -EINVAL;
152142

153143
vma_priv = kzalloc(sizeof(*vma_priv) + count * sizeof(void *),
154144
GFP_KERNEL);
155145
if (!vma_priv)
156146
return -ENOMEM;
157147

158-
vma_priv->n_pages = count;
159-
count = 0;
160-
for (i = 0; i < vma_priv->n_pages; i++) {
148+
for (i = 0; i < count; i++) {
161149
vma_priv->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
162150
if (!vma_priv->pages[i])
163151
break;
164-
count++;
152+
vma_priv->n_pages++;
165153
}
166154

167155
mutex_lock(&file_priv->lock);
168156

169-
file_priv->allocated += count;
170-
171157
vma_priv->file_priv = file_priv;
172158
vma_priv->users = 1;
173159

include/xen/xen-ops.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,12 @@ int xen_setup_shutdown_event(void);
4242

4343
extern unsigned long *xen_contiguous_bitmap;
4444

45-
#ifdef CONFIG_XEN_PV
45+
#if defined(CONFIG_XEN_PV) || defined(CONFIG_ARM) || defined(CONFIG_ARM64)
4646
int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
4747
unsigned int address_bits,
4848
dma_addr_t *dma_handle);
4949

5050
void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order);
51-
52-
int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr,
53-
xen_pfn_t *pfn, int nr, int *err_ptr, pgprot_t prot,
54-
unsigned int domid, bool no_translate, struct page **pages);
5551
#else
5652
static inline int xen_create_contiguous_region(phys_addr_t pstart,
5753
unsigned int order,
@@ -63,7 +59,13 @@ static inline int xen_create_contiguous_region(phys_addr_t pstart,
6359

6460
static inline void xen_destroy_contiguous_region(phys_addr_t pstart,
6561
unsigned int order) { }
62+
#endif
6663

64+
#if defined(CONFIG_XEN_PV)
65+
int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr,
66+
xen_pfn_t *pfn, int nr, int *err_ptr, pgprot_t prot,
67+
unsigned int domid, bool no_translate, struct page **pages);
68+
#else
6769
static inline int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr,
6870
xen_pfn_t *pfn, int nr, int *err_ptr,
6971
pgprot_t prot, unsigned int domid,

0 commit comments

Comments
 (0)