Commit 69ab76fd authored by Michel Thierry's avatar Michel Thierry Committed by Daniel Vetter

drm/i915/gen8: Initialize PDPs and PML4

Similar to PDs, while setting up a page directory pointer, make all entries
of the pdp point to the scratch pd before mapping (and make all its entries
point to the scratch page); this is to be safe in case of out of bound
access or  proactive prefetch.

Also add a scratch pdp, which the PML4 entries point to.

v2: Handle scratch_pdp allocation failure correctly, and keep
initialize_px functions together (Akash)
v3: Rebase after Mika's ppgtt cleanup / scratch merge patch series. Rely on
the added macros to initialize the pdps.
v4: Rebase after final merged version of Mika's ppgtt/scratch patches
(and removed commit message part related to v3).
v5: Update commit message to also mention PML4 table initialization and
the new scratch pdp (Akash).
Suggested-by: default avatarAkash Goel <akash.goel@intel.com>
Signed-off-by: default avatarMichel Thierry <michel.thierry@intel.com>
Reviewed-by: default avatarAkash Goel <akash.goel@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent de5ba8eb
...@@ -596,6 +596,27 @@ static void free_pdp(struct drm_device *dev, ...@@ -596,6 +596,27 @@ static void free_pdp(struct drm_device *dev,
} }
} }
static void gen8_initialize_pdp(struct i915_address_space *vm,
struct i915_page_directory_pointer *pdp)
{
gen8_ppgtt_pdpe_t scratch_pdpe;
scratch_pdpe = gen8_pdpe_encode(px_dma(vm->scratch_pd), I915_CACHE_LLC);
fill_px(vm->dev, pdp, scratch_pdpe);
}
static void gen8_initialize_pml4(struct i915_address_space *vm,
struct i915_pml4 *pml4)
{
gen8_ppgtt_pml4e_t scratch_pml4e;
scratch_pml4e = gen8_pml4e_encode(px_dma(vm->scratch_pdp),
I915_CACHE_LLC);
fill_px(vm->dev, pml4, scratch_pml4e);
}
static void static void
gen8_setup_page_directory(struct i915_hw_ppgtt *ppgtt, gen8_setup_page_directory(struct i915_hw_ppgtt *ppgtt,
struct i915_page_directory_pointer *pdp, struct i915_page_directory_pointer *pdp,
...@@ -860,8 +881,20 @@ static int gen8_init_scratch(struct i915_address_space *vm) ...@@ -860,8 +881,20 @@ static int gen8_init_scratch(struct i915_address_space *vm)
return PTR_ERR(vm->scratch_pd); return PTR_ERR(vm->scratch_pd);
} }
if (USES_FULL_48BIT_PPGTT(dev)) {
vm->scratch_pdp = alloc_pdp(dev);
if (IS_ERR(vm->scratch_pdp)) {
free_pd(dev, vm->scratch_pd);
free_pt(dev, vm->scratch_pt);
free_scratch_page(dev, vm->scratch_page);
return PTR_ERR(vm->scratch_pdp);
}
}
gen8_initialize_pt(vm, vm->scratch_pt); gen8_initialize_pt(vm, vm->scratch_pt);
gen8_initialize_pd(vm, vm->scratch_pd); gen8_initialize_pd(vm, vm->scratch_pd);
if (USES_FULL_48BIT_PPGTT(dev))
gen8_initialize_pdp(vm, vm->scratch_pdp);
return 0; return 0;
} }
...@@ -870,6 +903,8 @@ static void gen8_free_scratch(struct i915_address_space *vm) ...@@ -870,6 +903,8 @@ static void gen8_free_scratch(struct i915_address_space *vm)
{ {
struct drm_device *dev = vm->dev; struct drm_device *dev = vm->dev;
if (USES_FULL_48BIT_PPGTT(dev))
free_pdp(dev, vm->scratch_pdp);
free_pd(dev, vm->scratch_pd); free_pd(dev, vm->scratch_pd);
free_pt(dev, vm->scratch_pt); free_pt(dev, vm->scratch_pt);
free_scratch_page(dev, vm->scratch_page); free_scratch_page(dev, vm->scratch_page);
...@@ -1071,6 +1106,7 @@ gen8_ppgtt_alloc_page_dirpointers(struct i915_address_space *vm, ...@@ -1071,6 +1106,7 @@ gen8_ppgtt_alloc_page_dirpointers(struct i915_address_space *vm,
if (IS_ERR(pdp)) if (IS_ERR(pdp))
goto unwind_out; goto unwind_out;
gen8_initialize_pdp(vm, pdp);
pml4->pdps[pml4e] = pdp; pml4->pdps[pml4e] = pdp;
__set_bit(pml4e, new_pdps); __set_bit(pml4e, new_pdps);
trace_i915_page_directory_pointer_entry_alloc(vm, trace_i915_page_directory_pointer_entry_alloc(vm,
...@@ -1350,6 +1386,8 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ...@@ -1350,6 +1386,8 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
if (ret) if (ret)
goto free_scratch; goto free_scratch;
gen8_initialize_pml4(&ppgtt->base, &ppgtt->pml4);
ppgtt->base.total = 1ULL << 48; ppgtt->base.total = 1ULL << 48;
ppgtt->switch_mm = gen8_48b_mm_switch; ppgtt->switch_mm = gen8_48b_mm_switch;
} else { } else {
......
...@@ -278,6 +278,7 @@ struct i915_address_space { ...@@ -278,6 +278,7 @@ struct i915_address_space {
struct i915_page_scratch *scratch_page; struct i915_page_scratch *scratch_page;
struct i915_page_table *scratch_pt; struct i915_page_table *scratch_pt;
struct i915_page_directory *scratch_pd; struct i915_page_directory *scratch_pd;
struct i915_page_directory_pointer *scratch_pdp; /* GEN8+ & 48b PPGTT */
/** /**
* List of objects currently involved in rendering. * List of objects currently involved in rendering.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment