Commit cd913922 authored by Juergen Gross's avatar Juergen Gross Committed by Boris Ostrovsky
Browse files

xen: don't use privcmd_call() from xen_mc_flush()



Using privcmd_call() for a singleton multicall seems to be wrong, as
privcmd_call() is using stac()/clac() to enable hypervisor access to
Linux user space.

Even if currently not a problem (pv domains can't use SMAP while HVM
and PVH domains can't use multicalls) things might change when
PVH dom0 support is added to the kernel.

Reported-by: default avatarJan Beulich <jbeulich@suse.com>
Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
Reviewed-by: default avatarJan Beulich <jbeulich@suse.com>
Signed-off-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
parent 405c018a
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -209,7 +209,7 @@ extern struct { char _entry[32]; } hypercall_page[];
})

static inline long
privcmd_call(unsigned call,
xen_single_call(unsigned int call,
		unsigned long a1, unsigned long a2,
		unsigned long a3, unsigned long a4,
		unsigned long a5)
@@ -217,16 +217,29 @@ privcmd_call(unsigned call,
	__HYPERCALL_DECLS;
	__HYPERCALL_5ARG(a1, a2, a3, a4, a5);

	stac();
	asm volatile(CALL_NOSPEC
		     : __HYPERCALL_5PARAM
		     : [thunk_target] "a" (&hypercall_page[call])
		     : __HYPERCALL_CLOBBER5);
	clac();

	return (long)__res;
}

static inline long
privcmd_call(unsigned int call,
	     unsigned long a1, unsigned long a2,
	     unsigned long a3, unsigned long a4,
	     unsigned long a5)
{
	long res;

	stac();
	res = xen_single_call(call, a1, a2, a3, a4, a5);
	clac();

	return res;
}

static inline int
HYPERVISOR_set_trap_table(struct trap_info *table)
{
+3 −3
Original line number Diff line number Diff line
@@ -80,9 +80,9 @@ void xen_mc_flush(void)
		   and just do the call directly. */
		mc = &b->entries[0];

		mc->result = privcmd_call(mc->op,
					  mc->args[0], mc->args[1], mc->args[2], 
					  mc->args[3], mc->args[4]);
		mc->result = xen_single_call(mc->op, mc->args[0], mc->args[1],
					     mc->args[2], mc->args[3],
					     mc->args[4]);
		ret = mc->result < 0;
		break;