Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bebb6a49 authored by Jon Bloomfield's avatar Jon Bloomfield Committed by Greg Kroah-Hartman
Browse files

drm/i915/gtt: Add read only pages to gen8_pte_encode



commit 25dda4dabeeb12af5209b0183c788ef2a88dabbe upstream.

We can set a bit inside the ppGTT PTE to indicate a page is read-only;
writes from the GPU will be discarded. We can use this to protect pages
and in particular support read-only userptr mappings (necessary for
importing PROT_READ vma).

Signed-off-by: default avatarJon Bloomfield <jon.bloomfield@intel.com>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Matthew Auld <matthew.william.auld@gmail.com>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: default avatarMatthew Auld <matthew.william.auld@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180712185315.3288-1-chris@chris-wilson.co.uk


Reviewed-by: default avatarJon Bloomfield <jon.bloomfield@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1414193e
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -197,11 +197,14 @@ static void ppgtt_unbind_vma(struct i915_vma *vma)

static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
				  enum i915_cache_level level,
				  bool valid)
				  bool valid, u32 flags)
{
	gen8_pte_t pte = valid ? _PAGE_PRESENT | _PAGE_RW : 0;
	pte |= addr;

	if (unlikely(flags & PTE_READ_ONLY))
		pte &= ~_PAGE_RW;

	switch (level) {
	case I915_CACHE_NONE:
		pte |= PPAT_UNCACHED_INDEX;
@@ -472,7 +475,7 @@ static void gen8_initialize_pt(struct i915_address_space *vm,
	gen8_pte_t scratch_pte;

	scratch_pte = gen8_pte_encode(vm->scratch_page.daddr,
				      I915_CACHE_LLC, true);
				      I915_CACHE_LLC, true, 0);

	fill_px(vm->dev, pt, scratch_pte);
}
@@ -769,7 +772,7 @@ static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
{
	struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
	gen8_pte_t scratch_pte = gen8_pte_encode(vm->scratch_page.daddr,
						 I915_CACHE_LLC, use_scratch);
						 I915_CACHE_LLC, use_scratch, 0);

	if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
		gen8_ppgtt_clear_pte_range(vm, &ppgtt->pdp, start, length,
@@ -809,7 +812,7 @@ gen8_ppgtt_insert_pte_entries(struct i915_address_space *vm,

		pt_vaddr[pte] =
			gen8_pte_encode(sg_page_iter_dma_address(sg_iter),
					cache_level, true);
					cache_level, true, 0);
		if (++pte == GEN8_PTES) {
			kunmap_px(ppgtt, pt_vaddr);
			pt_vaddr = NULL;
@@ -1452,7 +1455,7 @@ static void gen8_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
	uint64_t start = ppgtt->base.start;
	uint64_t length = ppgtt->base.total;
	gen8_pte_t scratch_pte = gen8_pte_encode(vm->scratch_page.daddr,
						 I915_CACHE_LLC, true);
						 I915_CACHE_LLC, true, 0);

	if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
		gen8_dump_pdp(&ppgtt->pdp, start, length, scratch_pte, m);
@@ -2321,7 +2324,7 @@ static void gen8_ggtt_insert_page(struct i915_address_space *vm,

	rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv);

	gen8_set_pte(pte, gen8_pte_encode(addr, level, true));
	gen8_set_pte(pte, gen8_pte_encode(addr, level, true, 0));

	I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
	POSTING_READ(GFX_FLSH_CNTL_GEN6);
@@ -2348,7 +2351,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
	gtt_entries = (gen8_pte_t __iomem *)ggtt->gsm + (start >> PAGE_SHIFT);

	for_each_sgt_dma(addr, sgt_iter, st) {
		gtt_entry = gen8_pte_encode(addr, level, true);
		gtt_entry = gen8_pte_encode(addr, level, true, 0);
		gen8_set_pte(&gtt_entries[i++], gtt_entry);
	}

@@ -2499,7 +2502,7 @@ static void gen8_ggtt_clear_range(struct i915_address_space *vm,

	scratch_pte = gen8_pte_encode(vm->scratch_page.daddr,
				      I915_CACHE_LLC,
				      use_scratch);
				      use_scratch, 0);
	for (i = 0; i < num_entries; i++)
		gen8_set_pte(&gtt_base[i], scratch_pte);
	readl(gtt_base);