Commit 1e1d2e18 authored by Jani Nikula's avatar Jani Nikula
Browse files

Merge tag 'gvt-next-2022-04-21-for-christoph' of...

Merge tag 'gvt-next-2022-04-21-for-christoph' of https://github.com/intel/gvt-linux

 into drm-intel-next

gvt-next-2022-04-21-for-christoph

- Separating the MMIO table from GVT-g. (Zhi)
- GVT-g re-factor. (Christoph)
- GVT-g mdev API cleanup. (Jason)
- GVT-g trace/makefile cleanup. (Jani)

[Jani: added #include to adapt to header refactoring in drm-intel-next]
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
From: "Wang, Zhi A" <zhi.a.wang@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/25a713cd-0b7d-4c09-7d91-4f4ef6c9eb11@intel.com
parents b4b15757 2917f531
Loading
Loading
Loading
Loading
+5 −22
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ structure to represent a mediated device's driver::
     struct mdev_driver {
	     int  (*probe)  (struct mdev_device *dev);
	     void (*remove) (struct mdev_device *dev);
	     struct attribute_group **supported_type_groups;
	     struct device_driver    driver;
     };

@@ -119,33 +120,15 @@ to register and unregister itself with the core driver:

    extern void mdev_unregister_driver(struct mdev_driver *drv);

The mediated bus driver is responsible for adding mediated devices to the VFIO
group when devices are bound to the driver and removing mediated devices from
the VFIO when devices are unbound from the driver.


Physical Device Driver Interface
--------------------------------

The physical device driver interface provides the mdev_parent_ops[3] structure
to define the APIs to manage work in the mediated core driver that is related
to the physical device.

The structures in the mdev_parent_ops structure are as follows:

* dev_attr_groups: attributes of the parent device
* mdev_attr_groups: attributes of the mediated device
* supported_config: attributes to define supported configurations
* device_driver: device driver to bind for mediated device instances

The mdev_parent_ops also still has various functions pointers.  Theses exist
for historical reasons only and shall not be used for new drivers.
The mediated bus driver's probe function should create a vfio_device on top of
the mdev_device and connect it to an appropriate implementation of
vfio_device_ops.

When a driver wants to add the GUID creation sysfs to an existing device it has
probe'd to then it should call::

	extern int  mdev_register_device(struct device *dev,
	                                 const struct mdev_parent_ops *ops);
	                                 struct mdev_driver *mdev_driver);

This will provide the 'mdev_supported_types/XX/create' files which can then be
used to trigger the creation of a mdev_device. The created mdev_device will be
+13 −23
Original line number Diff line number Diff line
@@ -102,40 +102,30 @@ config DRM_I915_USERPTR
	  If in doubt, say "Y".

config DRM_I915_GVT
	bool "Enable Intel GVT-g graphics virtualization host support"
	bool

config DRM_I915_GVT_KVMGT
	tristate "Enable KVM host support Intel GVT-g graphics virtualization"
	depends on DRM_I915
	depends on X86
	depends on 64BIT
	default n
	depends on KVM
	depends on VFIO_MDEV
	select DRM_I915_GVT
	select KVM_EXTERNAL_WRITE_TRACKING

	help
	  Choose this option if you want to enable Intel GVT-g graphics
	  virtualization technology host support with integrated graphics.
	  With GVT-g, it's possible to have one integrated graphics
	  device shared by multiple VMs under different hypervisors.

	  Note that at least one hypervisor like Xen or KVM is required for
	  this driver to work, and it only supports newer device from
	  Broadwell+. For further information and setup guide, you can
	  visit: http://01.org/igvt-g.
	  device shared by multiple VMs under KVM.

	  Now it's just a stub to support the modifications of i915 for
	  GVT device model. It requires at least one MPT modules for Xen/KVM
	  and other components of GVT device model to work. Use it under
	  you own risk.
	  Note that this driver only supports newer device from Broadwell on.
	  For further information and setup guide, you can visit:
	  http://01.org/igvt-g.

	  If in doubt, say "N".

config DRM_I915_GVT_KVMGT
	tristate "Enable KVM/VFIO support for Intel GVT-g"
	depends on DRM_I915_GVT
	depends on KVM
	depends on VFIO_MDEV
	select KVM_EXTERNAL_WRITE_TRACKING
	default n
	help
	  Choose this option if you want to enable KVMGT support for
	  Intel GVT-g.

config DRM_I915_PXP
	bool "Enable Intel PXP support"
	depends on DRM_I915
+4 −4
Original line number Diff line number Diff line
@@ -322,13 +322,13 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \
# virtual gpu code
i915-y += i915_vgpu.o

ifeq ($(CONFIG_DRM_I915_GVT),y)
i915-y += intel_gvt.o
i915-$(CONFIG_DRM_I915_GVT) += \
	intel_gvt.o \
	intel_gvt_mmio_table.o
include $(src)/gvt/Makefile
endif

obj-$(CONFIG_DRM_I915) += i915.o
obj-$(CONFIG_DRM_I915_GVT_KVMGT) += gvt/kvmgt.o
obj-$(CONFIG_DRM_I915_GVT_KVMGT) += kvmgt.o

# header test

+23 −7
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0
GVT_DIR := gvt
GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
	interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
	execlist.o scheduler.o sched_policy.o mmio_context.o cmd_parser.o debugfs.o \
	fb_decoder.o dmabuf.o page_track.o

ccflags-y				+= -I $(srctree)/$(src) -I $(srctree)/$(src)/$(GVT_DIR)/
i915-y					+= $(addprefix $(GVT_DIR)/, $(GVT_SOURCE))
kvmgt-$(CONFIG_DRM_I915_GVT) += \
	gvt/aperture_gm.o \
	gvt/cfg_space.o \
	gvt/cmd_parser.o \
	gvt/debugfs.o \
	gvt/display.o \
	gvt/dmabuf.o \
	gvt/edid.o \
	gvt/execlist.o \
	gvt/fb_decoder.o \
	gvt/firmware.o \
	gvt/gtt.o \
	gvt/handlers.o \
	gvt/interrupt.o \
	gvt/kvmgt.o \
	gvt/mmio.o \
	gvt/mmio_context.o \
	gvt/opregion.o \
	gvt/page_track.o \
	gvt/sched_policy.o \
	gvt/scheduler.o \
	gvt/trace_points.o \
	gvt/vgpu.o
+17 −72
Original line number Diff line number Diff line
@@ -129,60 +129,16 @@ int intel_vgpu_emulate_cfg_read(struct intel_vgpu *vgpu, unsigned int offset,
	return 0;
}

static int map_aperture(struct intel_vgpu *vgpu, bool map)
static void map_aperture(struct intel_vgpu *vgpu, bool map)
{
	phys_addr_t aperture_pa = vgpu_aperture_pa_base(vgpu);
	unsigned long aperture_sz = vgpu_aperture_sz(vgpu);
	u64 first_gfn;
	u64 val;
	int ret;

	if (map == vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked)
		return 0;

	val = vgpu_cfg_space(vgpu)[PCI_BASE_ADDRESS_2];
	if (val & PCI_BASE_ADDRESS_MEM_TYPE_64)
		val = *(u64 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_2);
	else
		val = *(u32 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_2);

	first_gfn = (val + vgpu_aperture_offset(vgpu)) >> PAGE_SHIFT;

	ret = intel_gvt_hypervisor_map_gfn_to_mfn(vgpu, first_gfn,
						  aperture_pa >> PAGE_SHIFT,
						  aperture_sz >> PAGE_SHIFT,
						  map);
	if (ret)
		return ret;

	if (map != vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked)
		vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked = map;
	return 0;
}

static int trap_gttmmio(struct intel_vgpu *vgpu, bool trap)
static void trap_gttmmio(struct intel_vgpu *vgpu, bool trap)
{
	u64 start, end;
	u64 val;
	int ret;

	if (trap == vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_GTTMMIO].tracked)
		return 0;

	val = vgpu_cfg_space(vgpu)[PCI_BASE_ADDRESS_0];
	if (val & PCI_BASE_ADDRESS_MEM_TYPE_64)
		start = *(u64 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_0);
	else
		start = *(u32 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_0);

	start &= ~GENMASK(3, 0);
	end = start + vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_GTTMMIO].size - 1;

	ret = intel_gvt_hypervisor_set_trap_area(vgpu, start, end, trap);
	if (ret)
		return ret;

	if (trap != vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_GTTMMIO].tracked)
		vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_GTTMMIO].tracked = trap;
	return 0;
}

static int emulate_pci_command_write(struct intel_vgpu *vgpu,
@@ -191,26 +147,17 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu,
	u8 old = vgpu_cfg_space(vgpu)[offset];
	u8 new = *(u8 *)p_data;
	u8 changed = old ^ new;
	int ret;

	vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
	if (!(changed & PCI_COMMAND_MEMORY))
		return 0;

	if (old & PCI_COMMAND_MEMORY) {
		ret = trap_gttmmio(vgpu, false);
		if (ret)
			return ret;
		ret = map_aperture(vgpu, false);
		if (ret)
			return ret;
		trap_gttmmio(vgpu, false);
		map_aperture(vgpu, false);
	} else {
		ret = trap_gttmmio(vgpu, true);
		if (ret)
			return ret;
		ret = map_aperture(vgpu, true);
		if (ret)
			return ret;
		trap_gttmmio(vgpu, true);
		map_aperture(vgpu, true);
	}

	return 0;
@@ -230,13 +177,12 @@ static int emulate_pci_rom_bar_write(struct intel_vgpu *vgpu,
	return 0;
}

static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset,
static void emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset,
	void *p_data, unsigned int bytes)
{
	u32 new = *(u32 *)(p_data);
	bool lo = IS_ALIGNED(offset, 8);
	u64 size;
	int ret = 0;
	bool mmio_enabled =
		vgpu_cfg_space(vgpu)[PCI_COMMAND] & PCI_COMMAND_MEMORY;
	struct intel_vgpu_pci_bar *bars = vgpu->cfg_space.bar;
@@ -259,14 +205,14 @@ static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset,
			 * Untrap the BAR, since guest hasn't configured a
			 * valid GPA
			 */
			ret = trap_gttmmio(vgpu, false);
			trap_gttmmio(vgpu, false);
			break;
		case PCI_BASE_ADDRESS_2:
		case PCI_BASE_ADDRESS_3:
			size = ~(bars[INTEL_GVT_PCI_BAR_APERTURE].size -1);
			intel_vgpu_write_pci_bar(vgpu, offset,
						size >> (lo ? 0 : 32), lo);
			ret = map_aperture(vgpu, false);
			map_aperture(vgpu, false);
			break;
		default:
			/* Unimplemented BARs */
@@ -282,19 +228,18 @@ static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset,
			 */
			trap_gttmmio(vgpu, false);
			intel_vgpu_write_pci_bar(vgpu, offset, new, lo);
			ret = trap_gttmmio(vgpu, mmio_enabled);
			trap_gttmmio(vgpu, mmio_enabled);
			break;
		case PCI_BASE_ADDRESS_2:
		case PCI_BASE_ADDRESS_3:
			map_aperture(vgpu, false);
			intel_vgpu_write_pci_bar(vgpu, offset, new, lo);
			ret = map_aperture(vgpu, mmio_enabled);
			map_aperture(vgpu, mmio_enabled);
			break;
		default:
			intel_vgpu_write_pci_bar(vgpu, offset, new, lo);
		}
	}
	return ret;
}

/**
@@ -336,8 +281,8 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset,
	case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5:
		if (drm_WARN_ON(&i915->drm, !IS_ALIGNED(offset, 4)))
			return -EINVAL;
		return emulate_pci_bar_write(vgpu, offset, p_data, bytes);

		emulate_pci_bar_write(vgpu, offset, p_data, bytes);
		break;
	case INTEL_GVT_PCI_SWSCI:
		if (drm_WARN_ON(&i915->drm, !IS_ALIGNED(offset, 4)))
			return -EINVAL;
Loading