diff mbox

[v6,04/14] drm/i915/gvt: Detect 64K gtt entry by IPS bit of PDE

Message ID 1525770316-5287-5-git-send-email-changbin.du@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Du, Changbin May 8, 2018, 9:05 a.m. UTC
From: Changbin Du <changbin.du@intel.com>

This change help us detect the real entry type per PSE and IPS setting.
For 64K entry, we also need to check reg GEN8_GAMW_ECO_DEV_RW_IA.

Signed-off-by: Changbin Du <changbin.du@intel.com>
---
 drivers/gpu/drm/i915/gvt/gtt.c | 68 +++++++++++++++++++++++++++++-------------
 drivers/gpu/drm/i915/gvt/gtt.h |  2 ++
 2 files changed, 49 insertions(+), 21 deletions(-)

Comments

Matthew Auld May 10, 2018, 3:17 p.m. UTC | #1
On 8 May 2018 at 10:05,  <changbin.du@intel.com> wrote:
> From: Changbin Du <changbin.du@intel.com>
>
> This change help us detect the real entry type per PSE and IPS setting.
> For 64K entry, we also need to check reg GEN8_GAMW_ECO_DEV_RW_IA.
>
> Signed-off-by: Changbin Du <changbin.du@intel.com>
> ---
>  drivers/gpu/drm/i915/gvt/gtt.c | 68 +++++++++++++++++++++++++++++-------------
>  drivers/gpu/drm/i915/gvt/gtt.h |  2 ++
>  2 files changed, 49 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
> index cd2a227..7a80518 100644
> --- a/drivers/gpu/drm/i915/gvt/gtt.c
> +++ b/drivers/gpu/drm/i915/gvt/gtt.c
> @@ -384,20 +384,7 @@ static void gen8_gtt_set_pfn(struct intel_gvt_gtt_entry *e, unsigned long pfn)
>
>  static bool gen8_gtt_test_pse(struct intel_gvt_gtt_entry *e)
>  {
> -       /* Entry doesn't have PSE bit. */
> -       if (get_pse_type(e->type) == GTT_TYPE_INVALID)
> -               return false;
> -
> -       e->type = get_entry_type(e->type);
> -       if (!(e->val64 & _PAGE_PSE))
> -               return false;
> -
> -       /* We don't support 64K entry yet, will remove this later. */
> -       if (get_pse_type(e->type) == GTT_TYPE_PPGTT_PTE_64K_ENTRY)
> -               return false;
> -
> -       e->type = get_pse_type(e->type);
> -       return true;
> +       return !!(e->val64 & _PAGE_PSE);
>  }
>
>  static bool gen8_gtt_test_ips(struct intel_gvt_gtt_entry *e)
> @@ -487,6 +474,27 @@ static struct intel_gvt_gtt_gma_ops gen8_gtt_gma_ops = {
>         .gma_to_pml4_index = gen8_gma_to_pml4_index,
>  };
>
> +/* Update entry type per pse and ips bit. */
> +static void update_entry_type_for_real(struct intel_gvt_gtt_pte_ops *pte_ops,
> +       struct intel_gvt_gtt_entry *entry, bool ips)
> +{
> +       switch (entry->type) {
> +       case GTT_TYPE_PPGTT_PDE_ENTRY:
> +       case GTT_TYPE_PPGTT_PDP_ENTRY:
> +               if (pte_ops->test_pse(entry))
> +                       entry->type = get_pse_type(entry->type);
> +               break;
> +       case GTT_TYPE_PPGTT_PTE_4K_ENTRY:
> +               if (ips)
> +                       entry->type = get_pse_type(entry->type);
> +               break;
> +       default:
> +               GEM_BUG_ON(!gtt_type_is_entry(entry->type));
> +       }
> +
> +       GEM_BUG_ON(entry->type == GTT_TYPE_INVALID);
> +}
> +
>  /*
>   * MM helpers.
>   */
> @@ -502,8 +510,7 @@ static void _ppgtt_get_root_entry(struct intel_vgpu_mm *mm,
>         pte_ops->get_entry(guest ? mm->ppgtt_mm.guest_pdps :
>                            mm->ppgtt_mm.shadow_pdps,
>                            entry, index, false, 0, mm->vgpu);
> -
> -       pte_ops->test_pse(entry);
> +       update_entry_type_for_real(pte_ops, entry, false);
>  }
>
>  static inline void ppgtt_get_guest_root_entry(struct intel_vgpu_mm *mm,
> @@ -608,7 +615,8 @@ static inline int ppgtt_spt_get_entry(
>         if (ret)
>                 return ret;
>
> -       ops->test_pse(e);
> +       update_entry_type_for_real(ops, e, guest ?
> +                                  spt->guest_page.pde_ips : false);
>
>         gvt_vdbg_mm("read ppgtt entry, spt type %d, entry type %d, index %lu, value %llx\n",
>                     type, e->type, index, e->val64);
> @@ -752,7 +760,8 @@ static inline struct intel_vgpu_ppgtt_spt *intel_vgpu_find_spt_by_mfn(
>  static int reclaim_one_ppgtt_mm(struct intel_gvt *gvt);
>
>  static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt(
> -               struct intel_vgpu *vgpu, int type, unsigned long gfn)
> +               struct intel_vgpu *vgpu, int type, unsigned long gfn,
> +               bool guest_pde_ips)
>  {
>         struct device *kdev = &vgpu->gvt->dev_priv->drm.pdev->dev;
>         struct intel_vgpu_ppgtt_spt *spt = NULL;
> @@ -792,6 +801,7 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt(
>          */
>         spt->guest_page.type = type;
>         spt->guest_page.gfn = gfn;
> +       spt->guest_page.pde_ips = guest_pde_ips;
>
>         ret = intel_vgpu_register_page_track(vgpu, spt->guest_page.gfn,
>                                         ppgtt_write_protection_handler, spt);
> @@ -934,6 +944,20 @@ static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt)
>         return ret;
>  }
>
> +static bool vgpu_ips_enabled(struct intel_vgpu *vgpu)
> +{
> +       if (INTEL_GEN(vgpu->gvt->dev_priv) == 9) {
> +               u32 ips = vgpu_vreg_t(vgpu, GEN8_GAMW_ECO_DEV_RW_IA) &
> +                       GAMW_ECO_ENABLE_64K_IPS_FIELD;
> +
> +               return ips == GAMW_ECO_ENABLE_64K_IPS_FIELD;
> +       } else if (INTEL_GEN(vgpu->gvt->dev_priv) >= 10) {
> +               /* 64K paging only controlled by IPS bit in PTE now. */
> +               return true;

AFAIK the funny business with having to enable the IPS bit through
mmio is also needed on GEN10.
Zhenyu Wang May 11, 2018, 2:29 a.m. UTC | #2
On 2018.05.10 16:17:35 +0100, Matthew Auld wrote:
> > @@ -934,6 +944,20 @@ static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt)
> >         return ret;
> >  }
> >
> > +static bool vgpu_ips_enabled(struct intel_vgpu *vgpu)
> > +{
> > +       if (INTEL_GEN(vgpu->gvt->dev_priv) == 9) {
> > +               u32 ips = vgpu_vreg_t(vgpu, GEN8_GAMW_ECO_DEV_RW_IA) &
> > +                       GAMW_ECO_ENABLE_64K_IPS_FIELD;
> > +
> > +               return ips == GAMW_ECO_ENABLE_64K_IPS_FIELD;
> > +       } else if (INTEL_GEN(vgpu->gvt->dev_priv) >= 10) {
> > +               /* 64K paging only controlled by IPS bit in PTE now. */
> > +               return true;
> 
> AFAIK the funny business with having to enable the IPS bit through
> mmio is also needed on GEN10.

yeah, looks it only won't be needed from Gen11.

Thanks for review! Will update that.
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index cd2a227..7a80518 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -384,20 +384,7 @@  static void gen8_gtt_set_pfn(struct intel_gvt_gtt_entry *e, unsigned long pfn)
 
 static bool gen8_gtt_test_pse(struct intel_gvt_gtt_entry *e)
 {
-	/* Entry doesn't have PSE bit. */
-	if (get_pse_type(e->type) == GTT_TYPE_INVALID)
-		return false;
-
-	e->type = get_entry_type(e->type);
-	if (!(e->val64 & _PAGE_PSE))
-		return false;
-
-	/* We don't support 64K entry yet, will remove this later. */
-	if (get_pse_type(e->type) == GTT_TYPE_PPGTT_PTE_64K_ENTRY)
-		return false;
-
-	e->type = get_pse_type(e->type);
-	return true;
+	return !!(e->val64 & _PAGE_PSE);
 }
 
 static bool gen8_gtt_test_ips(struct intel_gvt_gtt_entry *e)
@@ -487,6 +474,27 @@  static struct intel_gvt_gtt_gma_ops gen8_gtt_gma_ops = {
 	.gma_to_pml4_index = gen8_gma_to_pml4_index,
 };
 
+/* Update entry type per pse and ips bit. */
+static void update_entry_type_for_real(struct intel_gvt_gtt_pte_ops *pte_ops,
+	struct intel_gvt_gtt_entry *entry, bool ips)
+{
+	switch (entry->type) {
+	case GTT_TYPE_PPGTT_PDE_ENTRY:
+	case GTT_TYPE_PPGTT_PDP_ENTRY:
+		if (pte_ops->test_pse(entry))
+			entry->type = get_pse_type(entry->type);
+		break;
+	case GTT_TYPE_PPGTT_PTE_4K_ENTRY:
+		if (ips)
+			entry->type = get_pse_type(entry->type);
+		break;
+	default:
+		GEM_BUG_ON(!gtt_type_is_entry(entry->type));
+	}
+
+	GEM_BUG_ON(entry->type == GTT_TYPE_INVALID);
+}
+
 /*
  * MM helpers.
  */
@@ -502,8 +510,7 @@  static void _ppgtt_get_root_entry(struct intel_vgpu_mm *mm,
 	pte_ops->get_entry(guest ? mm->ppgtt_mm.guest_pdps :
 			   mm->ppgtt_mm.shadow_pdps,
 			   entry, index, false, 0, mm->vgpu);
-
-	pte_ops->test_pse(entry);
+	update_entry_type_for_real(pte_ops, entry, false);
 }
 
 static inline void ppgtt_get_guest_root_entry(struct intel_vgpu_mm *mm,
@@ -608,7 +615,8 @@  static inline int ppgtt_spt_get_entry(
 	if (ret)
 		return ret;
 
-	ops->test_pse(e);
+	update_entry_type_for_real(ops, e, guest ?
+				   spt->guest_page.pde_ips : false);
 
 	gvt_vdbg_mm("read ppgtt entry, spt type %d, entry type %d, index %lu, value %llx\n",
 		    type, e->type, index, e->val64);
@@ -752,7 +760,8 @@  static inline struct intel_vgpu_ppgtt_spt *intel_vgpu_find_spt_by_mfn(
 static int reclaim_one_ppgtt_mm(struct intel_gvt *gvt);
 
 static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt(
-		struct intel_vgpu *vgpu, int type, unsigned long gfn)
+		struct intel_vgpu *vgpu, int type, unsigned long gfn,
+		bool guest_pde_ips)
 {
 	struct device *kdev = &vgpu->gvt->dev_priv->drm.pdev->dev;
 	struct intel_vgpu_ppgtt_spt *spt = NULL;
@@ -792,6 +801,7 @@  static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt(
 	 */
 	spt->guest_page.type = type;
 	spt->guest_page.gfn = gfn;
+	spt->guest_page.pde_ips = guest_pde_ips;
 
 	ret = intel_vgpu_register_page_track(vgpu, spt->guest_page.gfn,
 					ppgtt_write_protection_handler, spt);
@@ -934,6 +944,20 @@  static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt)
 	return ret;
 }
 
+static bool vgpu_ips_enabled(struct intel_vgpu *vgpu)
+{
+	if (INTEL_GEN(vgpu->gvt->dev_priv) == 9) {
+		u32 ips = vgpu_vreg_t(vgpu, GEN8_GAMW_ECO_DEV_RW_IA) &
+			GAMW_ECO_ENABLE_64K_IPS_FIELD;
+
+		return ips == GAMW_ECO_ENABLE_64K_IPS_FIELD;
+	} else if (INTEL_GEN(vgpu->gvt->dev_priv) >= 10) {
+		/* 64K paging only controlled by IPS bit in PTE now. */
+		return true;
+	} else
+		return false;
+}
+
 static int ppgtt_populate_spt(struct intel_vgpu_ppgtt_spt *spt);
 
 static struct intel_vgpu_ppgtt_spt *ppgtt_populate_spt_by_guest_entry(
@@ -941,6 +965,7 @@  static struct intel_vgpu_ppgtt_spt *ppgtt_populate_spt_by_guest_entry(
 {
 	struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
 	struct intel_vgpu_ppgtt_spt *spt = NULL;
+	bool ips = false;
 	int ret;
 
 	GEM_BUG_ON(!gtt_type_is_pt(get_next_pt_type(we->type)));
@@ -951,7 +976,10 @@  static struct intel_vgpu_ppgtt_spt *ppgtt_populate_spt_by_guest_entry(
 	else {
 		int type = get_next_pt_type(we->type);
 
-		spt = ppgtt_alloc_spt(vgpu, type, ops->get_pfn(we));
+		if (we->type == GTT_TYPE_PPGTT_PDE_ENTRY)
+			ips = vgpu_ips_enabled(vgpu) && ops->test_ips(we);
+
+		spt = ppgtt_alloc_spt(vgpu, type, ops->get_pfn(we), ips);
 		if (IS_ERR(spt)) {
 			ret = PTR_ERR(spt);
 			goto fail;
@@ -1427,8 +1455,6 @@  static int ppgtt_handle_guest_write_page_table_bytes(
 
 	ppgtt_get_guest_entry(spt, &we, index);
 
-	ops->test_pse(&we);
-
 	if (bytes == info->gtt_entry_size) {
 		ret = ppgtt_handle_guest_write_page_table(spt, &we, index);
 		if (ret)
diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h
index 9257b74..c11284b 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.h
+++ b/drivers/gpu/drm/i915/gvt/gtt.h
@@ -223,6 +223,7 @@  struct intel_vgpu_ppgtt_spt {
 
 	struct {
 		intel_gvt_gtt_type_t type;
+		bool pde_ips; /* for 64KB PTEs */
 		void *vaddr;
 		struct page *page;
 		unsigned long mfn;
@@ -230,6 +231,7 @@  struct intel_vgpu_ppgtt_spt {
 
 	struct {
 		intel_gvt_gtt_type_t type;
+		bool pde_ips; /* for 64KB PTEs */
 		unsigned long gfn;
 		unsigned long write_cnt;
 		struct intel_vgpu_oos_page *oos_page;