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
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/extable.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
@@ -93,12 +93,39 @@ clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
|
||||
*/
|
||||
static inline int xen_safe_write_ulong(unsigned long *addr, unsigned long val)
|
||||
{
|
||||
return __put_user(val, (unsigned long __user *)addr);
|
||||
int ret = 0;
|
||||
|
||||
asm volatile("1: mov %[val], %[ptr]\n"
|
||||
"2:\n"
|
||||
".section .fixup, \"ax\"\n"
|
||||
"3: sub $1, %[ret]\n"
|
||||
" jmp 2b\n"
|
||||
".previous\n"
|
||||
_ASM_EXTABLE(1b, 3b)
|
||||
: [ret] "+r" (ret), [ptr] "=m" (*addr)
|
||||
: [val] "r" (val));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int xen_safe_read_ulong(unsigned long *addr, unsigned long *val)
|
||||
static inline int xen_safe_read_ulong(const unsigned long *addr,
|
||||
unsigned long *val)
|
||||
{
|
||||
return __get_user(*val, (unsigned long __user *)addr);
|
||||
int ret = 0;
|
||||
unsigned long rval = ~0ul;
|
||||
|
||||
asm volatile("1: mov %[ptr], %[rval]\n"
|
||||
"2:\n"
|
||||
".section .fixup, \"ax\"\n"
|
||||
"3: sub $1, %[ret]\n"
|
||||
" jmp 2b\n"
|
||||
".previous\n"
|
||||
_ASM_EXTABLE(1b, 3b)
|
||||
: [ret] "+r" (ret), [rval] "+r" (rval)
|
||||
: [ptr] "m" (*addr));
|
||||
*val = rval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XEN_PV
|
||||
|
@@ -656,8 +656,7 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
|
||||
|
||||
/*
|
||||
* The interface requires atomic updates on p2m elements.
|
||||
* xen_safe_write_ulong() is using __put_user which does an atomic
|
||||
* store via asm().
|
||||
* xen_safe_write_ulong() is using an atomic store via asm().
|
||||
*/
|
||||
if (likely(!xen_safe_write_ulong(xen_p2m_addr + pfn, mfn)))
|
||||
return true;
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include <linux/log2.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/atomic.h>
|
||||
|
||||
#include <asm/paravirt.h>
|
||||
#include <asm/qspinlock.h>
|
||||
@@ -21,6 +22,7 @@
|
||||
|
||||
static DEFINE_PER_CPU(int, lock_kicker_irq) = -1;
|
||||
static DEFINE_PER_CPU(char *, irq_name);
|
||||
static DEFINE_PER_CPU(atomic_t, xen_qlock_wait_nest);
|
||||
static bool xen_pvspin = true;
|
||||
|
||||
static void xen_qlock_kick(int cpu)
|
||||
@@ -39,25 +41,25 @@ static void xen_qlock_kick(int cpu)
|
||||
*/
|
||||
static void xen_qlock_wait(u8 *byte, u8 val)
|
||||
{
|
||||
unsigned long flags;
|
||||
int irq = __this_cpu_read(lock_kicker_irq);
|
||||
atomic_t *nest_cnt = this_cpu_ptr(&xen_qlock_wait_nest);
|
||||
|
||||
/* If kicker interrupts not initialized yet, just spin */
|
||||
if (irq == -1 || in_nmi())
|
||||
return;
|
||||
|
||||
/* Guard against reentry. */
|
||||
local_irq_save(flags);
|
||||
/* Detect reentry. */
|
||||
atomic_inc(nest_cnt);
|
||||
|
||||
/* If irq pending already clear it. */
|
||||
if (xen_test_irq_pending(irq)) {
|
||||
/* If irq pending already and no nested call clear it. */
|
||||
if (atomic_read(nest_cnt) == 1 && xen_test_irq_pending(irq)) {
|
||||
xen_clear_irq_pending(irq);
|
||||
} else if (READ_ONCE(*byte) == val) {
|
||||
/* Block until irq becomes pending (or a spurious wakeup) */
|
||||
xen_poll_irq(irq);
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
atomic_dec(nest_cnt);
|
||||
}
|
||||
|
||||
static irqreturn_t dummy_handler(int irq, void *dev_id)
|
||||
|
Reference in New Issue
Block a user