Commit 778ce723 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus-6.1-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen updates from Juergen Gross:

 - Some minor typo fixes

 - A fix of the Xen pcifront driver for supporting the device model to
   run in a Linux stub domain

 - A cleanup of the pcifront driver

 - A series to enable grant-based virtio with Xen on x86

 - A cleanup of Xen PV guests to distinguish between safe and faulting
   MSR accesses

 - Two fixes of the Xen gntdev driver

 - Two fixes of the new xen grant DMA driver

* tag 'for-linus-6.1-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  xen: Kconfig: Fix spelling mistake "Maxmium" -> "Maximum"
  xen/pv: support selecting safe/unsafe msr accesses
  xen/pv: refactor msr access functions to support safe and unsafe accesses
  xen/pv: fix vendor checks for pmu emulation
  xen/pv: add fault recovery control to pmu msr accesses
  xen/virtio: enable grant based virtio on x86
  xen/virtio: use dom0 as default backend for CONFIG_XEN_VIRTIO_FORCE_GRANT
  xen/virtio: restructure xen grant dma setup
  xen/pcifront: move xenstore config scanning into sub-function
  xen/gntdev: Accommodate VMA splitting
  xen/gntdev: Prevent leaking grants
  xen/virtio: Fix potential deadlock when accessing xen_grant_dma_devices
  xen/virtio: Fix n_pages calculation in xen_grant_dma_map(unmap)_page()
  xen/xenbus: Fix spelling mistake "hardward" -> "hardware"
  xen-pcifront: Handle missed Connected state
parents 1440f576 7880672b
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -6851,6 +6851,12 @@
			Crash from Xen panic notifier, without executing late
			panic() code such as dumping handler.

	xen_msr_safe=	[X86,XEN]
			Format: <bool>
			Select whether to always use non-faulting (safe) MSR
			access functions when running as Xen PV guest. The
			default value is controlled by CONFIG_XEN_PV_MSR_SAFE.

	xen_nopvspin	[X86,XEN]
			Disables the qspinlock slowpath using Xen PV optimizations.
			This parameter is obsoleted by "nopvspin" parameter, which
+9 −0
Original line number Diff line number Diff line
@@ -92,3 +92,12 @@ config XEN_DOM0
	select X86_X2APIC if XEN_PVH && X86_64
	help
	  Support running as a Xen Dom0 guest.

config XEN_PV_MSR_SAFE
	bool "Always use safe MSR accesses in PV guests"
	default y
	depends on XEN_PV
	help
	  Use safe (not faulting) MSR access functions even if the MSR access
	  should not fault anyway.
	  The default can be changed by using the "xen_msr_safe" boot parameter.
+1 −1
Original line number Diff line number Diff line
@@ -212,7 +212,7 @@ static void __init xen_hvm_guest_init(void)
		return;

	if (IS_ENABLED(CONFIG_XEN_VIRTIO_FORCE_GRANT))
		virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc);
		virtio_set_mem_acc_cb(xen_virtio_restricted_mem_acc);

	init_hvm_pv_info();

+71 −30
Original line number Diff line number Diff line
@@ -108,11 +108,21 @@ struct tls_descs {
 */
static DEFINE_PER_CPU(struct tls_descs, shadow_tls_desc);

static __read_mostly bool xen_msr_safe = IS_ENABLED(CONFIG_XEN_PV_MSR_SAFE);

static int __init parse_xen_msr_safe(char *str)
{
	if (str)
		return strtobool(str, &xen_msr_safe);
	return -EINVAL;
}
early_param("xen_msr_safe", parse_xen_msr_safe);

static void __init xen_pv_init_platform(void)
{
	/* PV guests can't operate virtio devices without grants. */
	if (IS_ENABLED(CONFIG_XEN_VIRTIO))
		virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc);
		virtio_set_mem_acc_cb(xen_virtio_restricted_mem_acc);

	populate_extra_pte(fix_to_virt(FIX_PARAVIRT_BOOTMAP));

@@ -917,14 +927,18 @@ static void xen_write_cr4(unsigned long cr4)
	native_write_cr4(cr4);
}

static u64 xen_read_msr_safe(unsigned int msr, int *err)
static u64 xen_do_read_msr(unsigned int msr, int *err)
{
	u64 val;
	u64 val = 0;	/* Avoid uninitialized value for safe variant. */

	if (pmu_msr_read(msr, &val, err))
		return val;

	if (err)
		val = native_read_msr_safe(msr, err);
	else
		val = native_read_msr(msr);

	switch (msr) {
	case MSR_IA32_APICBASE:
		val &= ~X2APIC_ENABLE;
@@ -933,23 +947,39 @@ static u64 xen_read_msr_safe(unsigned int msr, int *err)
	return val;
}

static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
static void set_seg(unsigned int which, unsigned int low, unsigned int high,
		    int *err)
{
	int ret;
	unsigned int which;
	u64 base;
	u64 base = ((u64)high << 32) | low;

	if (HYPERVISOR_set_segment_base(which, base) == 0)
		return;

	ret = 0;
	if (err)
		*err = -EIO;
	else
		WARN(1, "Xen set_segment_base(%u, %llx) failed\n", which, base);
}

/*
 * Support write_msr_safe() and write_msr() semantics.
 * With err == NULL write_msr() semantics are selected.
 * Supplying an err pointer requires err to be pre-initialized with 0.
 */
static void xen_do_write_msr(unsigned int msr, unsigned int low,
			     unsigned int high, int *err)
{
	switch (msr) {
	case MSR_FS_BASE:		which = SEGBASE_FS; goto set;
	case MSR_KERNEL_GS_BASE:	which = SEGBASE_GS_USER; goto set;
	case MSR_GS_BASE:		which = SEGBASE_GS_KERNEL; goto set;

	set:
		base = ((u64)high << 32) | low;
		if (HYPERVISOR_set_segment_base(which, base) != 0)
			ret = -EIO;
	case MSR_FS_BASE:
		set_seg(SEGBASE_FS, low, high, err);
		break;

	case MSR_KERNEL_GS_BASE:
		set_seg(SEGBASE_GS_USER, low, high, err);
		break;

	case MSR_GS_BASE:
		set_seg(SEGBASE_GS_KERNEL, low, high, err);
		break;

	case MSR_STAR:
@@ -965,31 +995,42 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
		break;

	default:
		if (!pmu_msr_write(msr, low, high, &ret))
			ret = native_write_msr_safe(msr, low, high);
		if (!pmu_msr_write(msr, low, high, err)) {
			if (err)
				*err = native_write_msr_safe(msr, low, high);
			else
				native_write_msr(msr, low, high);
		}
	}
}

	return ret;
static u64 xen_read_msr_safe(unsigned int msr, int *err)
{
	return xen_do_read_msr(msr, err);
}

static int xen_write_msr_safe(unsigned int msr, unsigned int low,
			      unsigned int high)
{
	int err = 0;

	xen_do_write_msr(msr, low, high, &err);

	return err;
}

static u64 xen_read_msr(unsigned int msr)
{
	/*
	 * This will silently swallow a #GP from RDMSR.  It may be worth
	 * changing that.
	 */
	int err;

	return xen_read_msr_safe(msr, &err);
	return xen_do_read_msr(msr, xen_msr_safe ? &err : NULL);
}

static void xen_write_msr(unsigned int msr, unsigned low, unsigned high)
{
	/*
	 * This will silently swallow a #GP from WRMSR.  It may be worth
	 * changing that.
	 */
	xen_write_msr_safe(msr, low, high);
	int err;

	xen_do_write_msr(msr, low, high, xen_msr_safe ? &err : NULL);
}

/* This is called once we have the cpu_possible_mask */
+42 −29
Original line number Diff line number Diff line
@@ -131,6 +131,10 @@ static inline uint32_t get_fam15h_addr(u32 addr)

static inline bool is_amd_pmu_msr(unsigned int msr)
{
	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
	    boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
		return false;

	if ((msr >= MSR_F15H_PERF_CTL &&
	     msr < MSR_F15H_PERF_CTR + (amd_num_counters * 2)) ||
	    (msr >= MSR_K7_EVNTSEL0 &&
@@ -140,10 +144,15 @@ static inline bool is_amd_pmu_msr(unsigned int msr)
	return false;
}

static int is_intel_pmu_msr(u32 msr_index, int *type, int *index)
static bool is_intel_pmu_msr(u32 msr_index, int *type, int *index)
{
	u32 msr_index_pmc;

	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL &&
	    boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR &&
	    boot_cpu_data.x86_vendor != X86_VENDOR_ZHAOXIN)
		return false;

	switch (msr_index) {
	case MSR_CORE_PERF_FIXED_CTR_CTRL:
	case MSR_IA32_DS_AREA:
@@ -290,48 +299,52 @@ static bool xen_amd_pmu_emulate(unsigned int msr, u64 *val, bool is_read)
	return false;
}

bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err)
static bool pmu_msr_chk_emulated(unsigned int msr, uint64_t *val, bool is_read,
				 bool *emul)
{
	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) {
		if (is_amd_pmu_msr(msr)) {
			if (!xen_amd_pmu_emulate(msr, val, 1))
				*val = native_read_msr_safe(msr, err);
			return true;
		}
	} else {
	int type, index;

		if (is_intel_pmu_msr(msr, &type, &index)) {
			if (!xen_intel_pmu_emulate(msr, val, type, index, 1))
				*val = native_read_msr_safe(msr, err);
	if (is_amd_pmu_msr(msr))
		*emul = xen_amd_pmu_emulate(msr, val, is_read);
	else if (is_intel_pmu_msr(msr, &type, &index))
		*emul = xen_intel_pmu_emulate(msr, val, type, index, is_read);
	else
		return false;

	return true;
}
	}

bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err)
{
	bool emulated;

	if (!pmu_msr_chk_emulated(msr, val, true, &emulated))
		return false;

	if (!emulated) {
		*val = err ? native_read_msr_safe(msr, err)
			   : native_read_msr(msr);
	}

	return true;
}

bool pmu_msr_write(unsigned int msr, uint32_t low, uint32_t high, int *err)
{
	uint64_t val = ((uint64_t)high << 32) | low;
	bool emulated;

	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) {
		if (is_amd_pmu_msr(msr)) {
			if (!xen_amd_pmu_emulate(msr, &val, 0))
				*err = native_write_msr_safe(msr, low, high);
			return true;
		}
	} else {
		int type, index;
	if (!pmu_msr_chk_emulated(msr, &val, false, &emulated))
		return false;

		if (is_intel_pmu_msr(msr, &type, &index)) {
			if (!xen_intel_pmu_emulate(msr, &val, type, index, 0))
	if (!emulated) {
		if (err)
			*err = native_write_msr_safe(msr, low, high);
			return true;
		}
		else
			native_write_msr(msr, low, high);
	}

	return false;
	return true;
}

static unsigned long long xen_amd_read_pmc(int counter)
Loading