[Intel-gfx] [RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g
Tian, Kevin
kevin.tian at intel.com
Wed Feb 24 08:08:14 UTC 2016
> From: Wang, Zhi A
> Sent: Thursday, February 18, 2016 7:42 PM
> diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
> new file mode 100644
> index 0000000..52cfa32
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gvt/gvt.c
[...]
> +
> +#include <linux/types.h>
> +#include <xen/xen.h>
would this inclusion lead to a dependency on Xen?
> +#include <linux/kthread.h>
> +
> +#include "gvt.h"
> +
> +struct gvt_host gvt_host;
> +
> +static const char * const supported_hypervisors[] = {
> + [GVT_HYPERVISOR_TYPE_XEN] = "Xen Hypervisor",
> + [GVT_HYPERVISOR_TYPE_KVM] = "KVM",
> +};
> +
> +static int gvt_init_host(void)
> +{
> + struct gvt_host *host = &gvt_host;
> +
> + if (!gvt.enable) {
> + gvt_dbg_core("GVT-g has been disabled by kernel parameter");
> + return -EINVAL;
> + }
> +
> + if (host->initialized) {
> + gvt_err("GVT-g has already been initialized!");
> + return -EINVAL;
> + }
> +
> + /* Xen DOM U */
> + if (xen_domain() && !xen_initial_domain())
> + return -ENODEV;
> +
> + if (xen_initial_domain()) {
> + /* Xen Dom0 */
> + host->kdm = try_then_request_module(
> + symbol_get(xengt_kdm), "xengt");
> + host->hypervisor_type = GVT_HYPERVISOR_TYPE_XEN;
> + } else {
> + /* not in Xen. Try KVMGT */
> + host->kdm = try_then_request_module(
> + symbol_get(kvmgt_kdm), "kvm");
> + host->hypervisor_type = GVT_HYPERVISOR_TYPE_KVM;
> + }
It'd be clearer to add a comment here that above is only a short-term
solution. It's supposed to have a general registration framework in
the future so any hypervisor (Xen or KVM) can register their callbacks
at run-time, then we'll not need such direct Xen/KVM references or
hard assumption in driver code. That framework is now still under
discussion with Xen/KVM community. It doesn't prevent reviewing of
other bits, but better to document it clear here.
> +static int init_device_info(struct pgt_device *pdev)
> +{
> + struct gvt_device_info *info = &pdev->device_info;
> +
> + if (!IS_BROADWELL(pdev->dev_priv)) {
> + DRM_DEBUG_DRIVER("Unsupported GEN device");
> + return -ENODEV;
> + }
> +
> + if (IS_BROADWELL(pdev->dev_priv)) {
> + info->max_gtt_gm_sz = (1ULL << 32); /* 4GB */
> + /*
> + * The layout of BAR0 in BDW:
> + * |< - MMIO 2MB ->|<- Reserved 6MB ->|<- MAX GTT 8MB->|
> + *
> + * GTT offset in BAR0 starts from 8MB to 16MB, and
> + * Whatever GTT size is configured in BIOS,
> + * the size of BAR0 is always 16MB. The actual configured
> + * GTT size can be found in GMCH_CTRL.
> + */
> + info->gtt_start_offset = (1UL << 23); /* 8MB */
> + info->max_gtt_size = (1UL << 23); /* 8MB */
> + info->gtt_entry_size = 8;
> + info->gtt_entry_size_shift = 3;
> + info->gmadr_bytes_in_cmd = 8;
> + info->mmio_size = 2 * 1024 * 1024; /* 2MB */
Above are pure device info. Joonas, do you think whether it makes
sense to make them to drm_i915_private, though gvt is the only
user today?
> + }
> +
> + return 0;
> +}
> +
> +static void init_initial_cfg_space_state(struct pgt_device *pdev)
'init' -> 'setup'
> +{
> + struct pci_dev *pci_dev = pdev->dev_priv->dev->pdev;
> + int i;
> +
> + gvt_dbg_core("init initial cfg space, id %d", pdev->id);
> +
> + for (i = 0; i < GVT_CFG_SPACE_SZ; i += 4)
> + pci_read_config_dword(pci_dev, i,
> + (u32 *)&pdev->initial_cfg_space[i]);
> +
> + for (i = 0; i < GVT_BAR_NUM; i++) {
> + pdev->bar_size[i] = pci_resource_len(pci_dev, i * 2);
> + gvt_dbg_core("bar %d size: %llx", i, pdev->bar_size[i]);
> + }
> +}
> +
> +static void clean_initial_mmio_state(struct pgt_device *pdev)
> +{
> + if (pdev->gttmmio_va) {
> + iounmap(pdev->gttmmio_va);
> + pdev->gttmmio_va = NULL;
> + }
> +
> + if (pdev->gmadr_va) {
> + iounmap(pdev->gmadr_va);
> + pdev->gmadr_va = NULL;
> + }
Can we reuse existing mapping in i915?
> +}
> +
> +static int init_initial_mmio_state(struct pgt_device *pdev)
> +{
'init' -> 'setup'
> + struct gvt_device_info *info = &pdev->device_info;
> +
> + u64 bar0, bar1;
> + int rc;
> +
> + gvt_dbg_core("init initial mmio state, id %d", pdev->id);
> +
> + bar0 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR0];
> + bar1 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR1];
> +
> + pdev->gttmmio_base = bar0 & ~0xf;
> + pdev->reg_num = info->mmio_size / 4;
> + pdev->gmadr_base = bar1 & ~0xf;
> +
> + pdev->gttmmio_va = ioremap(pdev->gttmmio_base, pdev->bar_size[0]);
> + if (!pdev->gttmmio_va) {
> + gvt_err("fail to map GTTMMIO BAR.");
> + return -EFAULT;
> + }
> +
> + pdev->gmadr_va = ioremap(pdev->gmadr_base, pdev->bar_size[2]);
> + if (!pdev->gmadr_va) {
> + gvt_err("fail to map GMADR BAR.");
> + rc = -EFAULT;
> + goto err;
> + }
> +
> + gvt_dbg_core("bar0: 0x%llx, bar1: 0x%llx", bar0, bar1);
> + gvt_dbg_core("mmio size: %x", pdev->mmio_size);
> + gvt_dbg_core("gttmmio: 0x%llx, gmadr: 0x%llx", pdev->gttmmio_base,
> + pdev->gmadr_base);
> + gvt_dbg_core("gttmmio_va: %p", pdev->gttmmio_va);
> + gvt_dbg_core("gmadr_va: %p", pdev->gmadr_va);
> +
since you called 'initial_mmio_state', suppose we should do a MMIO snapshot
here.
[...]
> +
> +static struct pgt_device *alloc_pgt_device(struct drm_i915_private *dev_priv)
> +{
> + struct gvt_host *host = &gvt_host;
> + struct pgt_device *pdev = NULL;
> +
> + pdev = vzalloc(sizeof(*pdev));
> + if (!pdev)
> + return NULL;
> +
> + mutex_lock(&host->device_idr_lock);
> + pdev->id = idr_alloc(&host->device_idr, pdev, 0, 0, GFP_KERNEL);
curious what such ID help here? We already have either dev_priv or
pgt_device pointer passed around. Isn't it enough to mark a device?
[...]
> +
> +/**
> + * gvt_create_pgt_device - create a GVT physical device
> + * @dev: drm device
> + *
> + * This function is called at the initialization stage, to create a physical
> + * GVT device and initialize necessary GVT components for it.
> + *
> + * Returns:
> + * pointer to the pgt_device structure, NULL if failed.
> + */
> +void *gvt_create_pgt_device(struct drm_i915_private *dev_priv)
should we remove 'pgt' completely? We can always use 'gvt_device'
as reference to the object, and then above can be gvt_create_device
or gvt_create_physical_device, or if 'create' is a bit misleading maybe
gvt_initialize_device is cleaner?
Thanks
Kevin
More information about the Intel-gfx
mailing list