Re: [PATCH 2/2] drm/edid: make drm_edid_block_valid() static

2024-05-30 Thread Zhi Wang
On Thu, 30 May 2024 15:43:52 +0300
Jani Nikula  wrote:

> drm_edid_block_valid() is no longer used outside of drm_edid.c. Make
> it static.
> 
> Signed-off-by: Jani Nikula 
> 
> ---
> 
> Cc: Zhenyu Wang 
> Cc: Zhi Wang 
> Cc: intel-gvt-...@lists.freedesktop.org
> Cc: intel-gfx@lists.freedesktop.org
> Cc: dri-de...@lists.freedesktop.org
> ---
>  drivers/gpu/drm/drm_edid.c | 17 -
>  include/drm/drm_edid.h |  2 --
>  2 files changed, 4 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index f68a41eeb1fa..13b3fd351b16 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1966,22 +1966,14 @@ static void edid_block_dump(const char
> *level, const void *block, int block_num) block, EDID_LENGTH, false);
>  }
>  
> -/**
> - * drm_edid_block_valid - Sanity check the EDID block (base or
> extension)
> - * @_block: pointer to raw EDID block
> - * @block_num: type of block to validate (0 for base, extension
> otherwise)
> - * @print_bad_edid: if true, dump bad EDID blocks to the console
> - * @edid_corrupt: if true, the header or checksum is invalid
> - *
> +/*
>   * Validate a base or extension EDID block and optionally dump bad
> blocks to
>   * the console.
> - *
> - * Return: True if the block is valid, false otherwise.
>   */
> -bool drm_edid_block_valid(u8 *_block, int block_num, bool
> print_bad_edid,
> -   bool *edid_corrupt)
> +static bool drm_edid_block_valid(void *_block, int block_num, bool
> print_bad_edid,
> +  bool *edid_corrupt)
>  {
> - struct edid *block = (struct edid *)_block;
> + struct edid *block = _block;
>   enum edid_block_status status;
>   bool is_base_block = block_num == 0;
>   bool valid;
> @@ -2024,7 +2016,6 @@ bool drm_edid_block_valid(u8 *_block, int
> block_num, bool print_bad_edid, 
>   return valid;
>  }
> -EXPORT_SYMBOL(drm_edid_block_valid);
>  
>  /**
>   * drm_edid_is_valid - sanity check EDID data
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 6bdfa254a1c1..eaac5e665892 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -440,8 +440,6 @@ int drm_add_modes_noedid(struct drm_connector
> *connector, int hdisplay, int vdisplay);
>  
>  int drm_edid_header_is_valid(const void *edid);
> -bool drm_edid_block_valid(u8 *raw_edid, int block, bool
> print_bad_edid,
> -       bool *edid_corrupt);
>  bool drm_edid_is_valid(struct edid *edid);
>  void drm_edid_get_monitor_name(const struct edid *edid, char *name,
>  int buflen);

Acked-by: Zhi Wang 


Re: [PATCH 1/2] drm/i915/gvt: stop using drm_edid_block_valid()

2024-05-30 Thread Zhi Wang
On Thu, 30 May 2024 15:43:51 +0300
Jani Nikula  wrote:

> We'll want to stop drm_edid_block_valid() usage. KVMGT is the last
> user. Replace with drm_edid_valid(), which unfortunately requires an
> allocated drm_edid. However, on the plus side, this would be required
> to handle the TODO comment about EDID extension block support.
> 
> Signed-off-by: Jani Nikula 
> 
> ---
> 
> Cc: Zhenyu Wang 
> Cc: Zhi Wang 
> Cc: intel-gvt-...@lists.freedesktop.org
> Cc: intel-gfx@lists.freedesktop.org
> Cc: dri-de...@lists.freedesktop.org
> ---
>  drivers/gpu/drm/i915/gvt/kvmgt.c | 18 +-
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c
> b/drivers/gpu/drm/i915/gvt/kvmgt.c index 4f74d867fe1a..7e3e5382c0c0
> 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c
> +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
> @@ -425,6 +425,18 @@ static const struct intel_vgpu_regops
> intel_vgpu_regops_opregion = { .release =
> intel_vgpu_reg_release_opregion, };
>  
> +static bool edid_valid(const void *edid, size_t size)
> +{
> + const struct drm_edid *drm_edid;
> + bool is_valid;
> +
> + drm_edid = drm_edid_alloc(edid, size);
> + is_valid = drm_edid_valid(drm_edid);
> + drm_edid_free(drm_edid);
> +
> + return is_valid;
> +}
> +
>  static int handle_edid_regs(struct intel_vgpu *vgpu,
>   struct vfio_edid_region *region, char *buf,
>   size_t count, u16 offset, bool is_write)
> @@ -443,11 +455,7 @@ static int handle_edid_regs(struct intel_vgpu
> *vgpu, switch (offset) {
>   case offsetof(struct vfio_region_gfx_edid,
> link_state): if (data == VFIO_DEVICE_GFX_LINK_STATE_UP) {
> - if (!drm_edid_block_valid(
> - (u8 *)region->edid_blob,
> - 0,
> - true,
> - NULL)) {
> + if (!edid_valid(region->edid_blob,
> EDID_SIZE)) { gvt_vgpu_err("invalid EDID blob\n");
>   return -EINVAL;
>   }

Acked-by: Zhi Wang 


Re: [PATCH v1 03/12] drm/i915: Make I2C terminology more inclusive

2024-05-03 Thread Zhi Wang
On Tue, 30 Apr 2024 17:38:02 +
Easwar Hariharan  wrote:

> I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced
> "master/slave" with more appropriate terms. Inspired by and following
> on to Wolfram's series to fix drivers/i2c/[1], fix the terminology
> for users of I2C_ALGOBIT bitbanging interface, now that the approved
> verbiage exists in the specification.
> 
> Compile tested, no functionality changes intended
> 
For GVT part,

Acked-by: Zhi Wang 

Thanks,
Zhi.

> [1]:
> https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/
> 
> Signed-off-by: Easwar Hariharan 
> ---
>  drivers/gpu/drm/i915/display/dvo_ch7017.c | 14 -
>  drivers/gpu/drm/i915/display/dvo_ch7xxx.c | 18 +--
>  drivers/gpu/drm/i915/display/dvo_ivch.c   | 16 +-
>  drivers/gpu/drm/i915/display/dvo_ns2501.c | 18 +--
>  drivers/gpu/drm/i915/display/dvo_sil164.c | 18 +--
>  drivers/gpu/drm/i915/display/dvo_tfp410.c | 18 +--
>  drivers/gpu/drm/i915/display/intel_bios.c | 22 +++---
>  drivers/gpu/drm/i915/display/intel_ddi.c  |  2 +-
>  .../gpu/drm/i915/display/intel_display_core.h |  2 +-
>  drivers/gpu/drm/i915/display/intel_dsi.h  |  2 +-
>  drivers/gpu/drm/i915/display/intel_dsi_vbt.c  | 20 ++---
>  drivers/gpu/drm/i915/display/intel_dvo.c  | 14 -
>  drivers/gpu/drm/i915/display/intel_dvo_dev.h  |  2 +-
>  drivers/gpu/drm/i915/display/intel_gmbus.c|  4 +--
>  drivers/gpu/drm/i915/display/intel_sdvo.c | 30
> +-- drivers/gpu/drm/i915/display/intel_vbt_defs.h |
> 4 +-- drivers/gpu/drm/i915/gvt/edid.c   | 28
> - drivers/gpu/drm/i915/gvt/edid.h   |  4
> +-- drivers/gpu/drm/i915/gvt/opregion.c   |  2 +-
>  19 files changed, 119 insertions(+), 119 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/dvo_ch7017.c
> b/drivers/gpu/drm/i915/display/dvo_ch7017.c index
> d0c3880d7f80..493e730c685b 100644 ---
> a/drivers/gpu/drm/i915/display/dvo_ch7017.c +++
> b/drivers/gpu/drm/i915/display/dvo_ch7017.c @@ -170,13 +170,13 @@
> static bool ch7017_read(struct intel_dvo_device *dvo, u8 addr, u8
> *val) { struct i2c_msg msgs[] = {
>   {
> - .addr = dvo->slave_addr,
> + .addr = dvo->target_addr,
>   .flags = 0,
>   .len = 1,
>   .buf = ,
>   },
>   {
> - .addr = dvo->slave_addr,
> + .addr = dvo->target_addr,
>   .flags = I2C_M_RD,
>   .len = 1,
>   .buf = val,
> @@ -189,7 +189,7 @@ static bool ch7017_write(struct intel_dvo_device
> *dvo, u8 addr, u8 val) {
>   u8 buf[2] = { addr, val };
>   struct i2c_msg msg = {
> - .addr = dvo->slave_addr,
> + .addr = dvo->target_addr,
>   .flags = 0,
>   .len = 2,
>   .buf = buf,
> @@ -197,7 +197,7 @@ static bool ch7017_write(struct intel_dvo_device
> *dvo, u8 addr, u8 val) return i2c_transfer(dvo->i2c_bus, , 1) ==
> 1; }
>  
> -/** Probes for a CH7017 on the given bus and slave address. */
> +/** Probes for a CH7017 on the given bus and target address. */
>  static bool ch7017_init(struct intel_dvo_device *dvo,
>   struct i2c_adapter *adapter)
>  {
> @@ -227,13 +227,13 @@ static bool ch7017_init(struct intel_dvo_device
> *dvo, break;
>   default:
>   DRM_DEBUG_KMS("ch701x not detected, got %d: from %s "
> -   "slave %d.\n",
> -   val, adapter->name, dvo->slave_addr);
> +   "target %d.\n",
> +   val, adapter->name, dvo->target_addr);
>   goto fail;
>   }
>  
>   DRM_DEBUG_KMS("%s detected on %s, addr %d\n",
> -   str, adapter->name, dvo->slave_addr);
> +   str, adapter->name, dvo->target_addr);
>   return true;
>  
>  fail:
> diff --git a/drivers/gpu/drm/i915/display/dvo_ch7xxx.c
> b/drivers/gpu/drm/i915/display/dvo_ch7xxx.c index
> 2e8e85da5a40..534b8544e0a4 100644 ---
> a/drivers/gpu/drm/i915/display/dvo_ch7xxx.c +++
> b/drivers/gpu/drm/i915/display/dvo_ch7xxx.c @@ -153,13 +153,13 @@
> static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, u8
> *ch) struct i2c_msg msgs[] = {
>   {
> - .addr = dvo->slave_addr,
> + .addr = dvo->target_addr,
> 

Re: [PATCH 00/21] drm/i915: remove unused structure members

2024-02-16 Thread Zhi Wang
On Fri, 16 Feb 2024 10:51:20 +0200
Jani Nikula  wrote:

> On Fri, 16 Feb 2024, "Jiri Slaby (SUSE)"  wrote:
> > this series removes unused i915 structure members as found by
> > clang-struct (and manually checked by me).
> 
> Thanks Jiri, good stuff!
> 
> Acked-by: Jani Nikula 
> 
> However, you may have overlooked that drivers/gpu/drm/i915/gvt/ is
> maintained separately.
> 
> Cc: Zhenyu, Zhi, how do you want the gvt patches in this series
> handled?
> 

Many thanks for the clean-up patch Jiri! Jani, it would be easier
for us that you can help to apply the patches through i915.

Thanks,
Zhi.

> 
> BR,
> Jani.
> 
> 
> >
> > Cc: intel-gfx@lists.freedesktop.org
> > Cc: Jani Nikula 
> > Cc: Joonas Lahtinen 
> > Cc: Rodrigo Vivi 
> > Cc: Tvrtko Ursulin 
> >
> > Jiri Slaby (SUSE) (21):
> >   drm/i915: remove unused intel_dvo_dev_ops hooks
> >   drm/i915: remove structs intel_vgpu_pipe_format and
> > intel_vgpu_fb_format
> >   drm/i915: remove intel_dsi::{port_bits,hs}
> >   drm/i915: remove
> > intel_gvt_gtt::{mm_alloc_page_table,mm_free_page_table}
> >   drm/i915: remove intel_gvt_mmio_info::{device,addr_range}
> >   drm/i915: remove
> > intel_vgpu_workload::{ring_context,restore_inhibit} drm/i915:
> > remove intel_vbt_panel_data::edp::initialized drm/i915: remove
> > intel_guc::ads_engine_usage_size drm/i915: remove
> > i915_drm_client::id drm/i915: remove i915_perf_stream::size_exponent
> >   drm/i915: remove intel_vgpu_gtt::active_ppgtt_mm_bitmap
> >   drm/i915: remove intel_vgpu_fence::base
> >   drm/i915: remove intel_vgpu_opregion::mapped
> >   drm/i915: remove intel_vgpu::intx_trigger
> >   drm/i915: remove gvt_mmio_block::device
> >   drm/i915: remove intel_gvt_irq_info::warned
> >   drm/i915: remove intel_gvt_event_info::policy
> >   drm/i915: remove intel_gvt_irq::pending_events
> >   drm/i915: remove execute_cb::signal
> >   drm/i915: remove i915_vma::obj_hash
> >   drm/i915: remove intel_memory_region_ops::flags
> >
> >  .../drm/i915/display/intel_display_types.h|  1 -
> >  drivers/gpu/drm/i915/display/intel_dsi.h  |  4 ---
> >  drivers/gpu/drm/i915/display/intel_dvo_dev.h  | 25
> > --- drivers/gpu/drm/i915/gt/uc/intel_guc.h|
> >  2 -- drivers/gpu/drm/i915/gvt/fb_decoder.h | 11 
> >  drivers/gpu/drm/i915/gvt/gtt.h|  3 ---
> >  drivers/gpu/drm/i915/gvt/gvt.h|  5 
> >  drivers/gpu/drm/i915/gvt/interrupt.c  |  1 -
> >  drivers/gpu/drm/i915/gvt/interrupt.h  |  2 --
> >  drivers/gpu/drm/i915/gvt/mmio.h   |  2 --
> >  drivers/gpu/drm/i915/gvt/scheduler.h  |  2 --
> >  drivers/gpu/drm/i915/i915_drm_client.h|  2 --
> >  drivers/gpu/drm/i915/i915_perf_types.h|  1 -
> >  drivers/gpu/drm/i915/i915_request.c   |  1 -
> >  drivers/gpu/drm/i915/i915_vma_types.h |  1 -
> >  drivers/gpu/drm/i915/intel_memory_region.h|  2 --
> >  16 files changed, 65 deletions(-)
> 



Re: [PATCH][next] drm/i915/gvt: remove redundant assignment to pointer map

2024-02-11 Thread Zhi Wang
On Fri,  9 Feb 2024 16:08:29 +
Colin Ian King  wrote:

> The pointer map is being initialized with a value that is never
> read, it is being re-assigned later on in a for-loop. The
> initialization is redundant and can be removed.
> 
> Cleans up clang scan build warning:
> drivers/gpu/drm/i915/gvt/interrupt.c:346:28: warning: Value stored to
> 'map' during its initialization is never read [deadcode.DeadStores]
> 
> Signed-off-by: Colin Ian King 
> ---
>  drivers/gpu/drm/i915/gvt/interrupt.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gvt/interrupt.c
> b/drivers/gpu/drm/i915/gvt/interrupt.c index
> c8e7dfc9f791..8c8e37f50a45 100644 ---
> a/drivers/gpu/drm/i915/gvt/interrupt.c +++
> b/drivers/gpu/drm/i915/gvt/interrupt.c @@ -343,7 +343,7 @@ static
> void update_upstream_irq(struct intel_vgpu *vgpu, {
>   struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
>   struct intel_gvt_irq *irq = >gvt->irq;
> - struct intel_gvt_irq_map *map = irq->irq_map;
> + struct intel_gvt_irq_map *map;
>   struct intel_gvt_irq_info *up_irq_info = NULL;
>   u32 set_bits = 0;
>   u32 clear_bits = 0;

Thanks for the patch!

Reviewed-by: Zhi Wang 


Re: [Intel-gfx] [PATCH] drm/i915: Replace dead 01.org link

2024-02-03 Thread Zhi Wang
On Fri,  4 Aug 2023 12:05:44 +0800
Zhenyu Wang  wrote:

> 01.org is dead so replace old gvt link with current wiki page.
> 
> Signed-off-by: Zhenyu Wang 
> Acked-by: Jani Nikula 
> ---
>  MAINTAINERS  | 2 +-
>  drivers/gpu/drm/i915/Kconfig | 2 +-
>  drivers/gpu/drm/i915/intel_gvt.c | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d516295978a4..805d33a107aa 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -10436,7 +10436,7 @@ M:Zhi Wang 
>  L:   intel-gvt-...@lists.freedesktop.org
>  L:   intel-gfx@lists.freedesktop.org
>  S:   Supported
> -W:   https://01.org/igvt-g
> +W:   https://github.com/intel/gvt-linux/wiki
>  T:   git https://github.com/intel/gvt-linux.git
>  F:   drivers/gpu/drm/i915/gvt/
>  
> diff --git a/drivers/gpu/drm/i915/Kconfig
> b/drivers/gpu/drm/i915/Kconfig index 01b5a8272a27..854255966d3d 100644
> --- a/drivers/gpu/drm/i915/Kconfig
> +++ b/drivers/gpu/drm/i915/Kconfig
> @@ -140,7 +140,7 @@ config DRM_I915_GVT_KVMGT
>  
> 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.
> +   https://github.com/intel/gvt-linux/wiki.
>  
> If in doubt, say "N".
>  
> diff --git a/drivers/gpu/drm/i915/intel_gvt.c
> b/drivers/gpu/drm/i915/intel_gvt.c index e98b6d69a91a..9b6d87c8b583
> 100644 --- a/drivers/gpu/drm/i915/intel_gvt.c
> +++ b/drivers/gpu/drm/i915/intel_gvt.c
> @@ -41,7 +41,7 @@
>   * To virtualize GPU resources GVT-g driver depends on hypervisor
> technology
>   * e.g KVM/VFIO/mdev, Xen, etc. to provide resource access trapping
> capability
>   * and be virtualized within GVT-g device module. More architectural
> design
> - * doc is available on https://01.org/group/2230/documentation-list.
> + * doc is available on https://github.com/intel/gvt-linux/wiki.
>   */
>  
>  static LIST_HEAD(intel_gvt_devices);

Reviewed-by: Zhi Wang 


[Intel-gfx] [PATCH RESEND] drm/i915/gvt: remove unused variable gma_bottom in command parser

2023-05-30 Thread Zhi Wang
Remove unused variable gma_bottom in scan_workload() and scan_wa_ctx().
commit be1da7070aea ("drm/i915/gvt: vGPU command scanner") introduces
gma_bottom in several functions to calculate the size of the command
buffer. However, some of them are set but actually unused.

When compiling the code with ccflags -Wunused-but-set-variable, gcc
throws warnings.

Remove unused variables to avoid the gcc warnings. Tested via compiling
the code with ccflags -Wunused-but-set-variable.

Fixes: be1da7070aea ("drm/i915/gvt: vGPU command scanner")
Suggested-by: Jani Nikula 
Cc: Zhenyu Wang 
Cc: intel-gvt-...@lists.freedesktop.org
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/cmd_parser.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c 
b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index 3c4ae1da0d41..05f9348b7a9d 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -2833,7 +2833,7 @@ static int command_scan(struct parser_exec_state *s,
 
 static int scan_workload(struct intel_vgpu_workload *workload)
 {
-   unsigned long gma_head, gma_tail, gma_bottom;
+   unsigned long gma_head, gma_tail;
struct parser_exec_state s;
int ret = 0;
 
@@ -2843,7 +2843,6 @@ static int scan_workload(struct intel_vgpu_workload 
*workload)
 
gma_head = workload->rb_start + workload->rb_head;
gma_tail = workload->rb_start + workload->rb_tail;
-   gma_bottom = workload->rb_start +  _RING_CTL_BUF_SIZE(workload->rb_ctl);
 
s.buf_type = RING_BUFFER_INSTRUCTION;
s.buf_addr_type = GTT_BUFFER;
@@ -2874,7 +2873,7 @@ static int scan_workload(struct intel_vgpu_workload 
*workload)
 static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 {
 
-   unsigned long gma_head, gma_tail, gma_bottom, ring_size, ring_tail;
+   unsigned long gma_head, gma_tail, ring_size, ring_tail;
struct parser_exec_state s;
int ret = 0;
struct intel_vgpu_workload *workload = container_of(wa_ctx,
@@ -2891,7 +2890,6 @@ static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
PAGE_SIZE);
gma_head = wa_ctx->indirect_ctx.guest_gma;
gma_tail = wa_ctx->indirect_ctx.guest_gma + ring_tail;
-   gma_bottom = wa_ctx->indirect_ctx.guest_gma + ring_size;
 
s.buf_type = RING_BUFFER_INSTRUCTION;
s.buf_addr_type = GTT_BUFFER;
-- 
2.25.1



[Intel-gfx] [PATCH 1/2] drm/i915/gvt: Make intel_gvt_match_device() static

2022-04-27 Thread Zhi Wang
After the refactor of GVT-g, the reference of intel_gvt_match_device()
only happens in handlers.c. Make it static to let the compiler be
happy.

Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Robert Beckett 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/handlers.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index cf00398c2870..a93f8fd423c2 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -72,7 +72,7 @@ unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt)
return 0;
 }
 
-bool intel_gvt_match_device(struct intel_gvt *gvt,
+static bool intel_gvt_match_device(struct intel_gvt *gvt,
unsigned long device)
 {
return intel_gvt_get_device_type(gvt) & device;
-- 
2.17.1



[Intel-gfx] [PATCH 2/2] drm/i915/gvt: Fix the compiling error when CONFIG_DRM_I915_DEBUG_RUNTIME_PM=n

2022-04-27 Thread Zhi Wang
A compiling error was reported when CONFIG_DRM_I915_DEBUG_RUNTIME_PM=n.
Fix the problem by using the pre-defined macro.

Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/intel_gvt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c
index 24bc693439e8..e98b6d69a91a 100644
--- a/drivers/gpu/drm/i915/intel_gvt.c
+++ b/drivers/gpu/drm/i915/intel_gvt.c
@@ -309,7 +309,9 @@ EXPORT_SYMBOL_NS_GPL(__intel_context_do_pin, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(__intel_context_do_unpin, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(intel_ring_begin, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(intel_runtime_pm_get, I915_GVT);
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
 EXPORT_SYMBOL_NS_GPL(intel_runtime_pm_put, I915_GVT);
+#endif
 EXPORT_SYMBOL_NS_GPL(intel_runtime_pm_put_unchecked, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(intel_uncore_forcewake_for_reg, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(intel_uncore_forcewake_get, I915_GVT);
-- 
2.17.1



[Intel-gfx] [PATCH] drm/i915/gvt: Add missing symbol export.

2022-04-25 Thread Zhi Wang
When CONFIG_DRM_I915_DEBUG_RUNTIME and CONFIG_DRM_I915_DEBUG_PM
are enabled, two more extra symols in i915 are required to be
exported.

Cc: Jani Nikula 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/intel_gvt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c
index 7c03d975069e..24bc693439e8 100644
--- a/drivers/gpu/drm/i915/intel_gvt.c
+++ b/drivers/gpu/drm/i915/intel_gvt.c
@@ -309,6 +309,7 @@ EXPORT_SYMBOL_NS_GPL(__intel_context_do_pin, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(__intel_context_do_unpin, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(intel_ring_begin, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(intel_runtime_pm_get, I915_GVT);
+EXPORT_SYMBOL_NS_GPL(intel_runtime_pm_put, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(intel_runtime_pm_put_unchecked, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(intel_uncore_forcewake_for_reg, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(intel_uncore_forcewake_get, I915_GVT);
@@ -316,3 +317,4 @@ EXPORT_SYMBOL_NS_GPL(intel_uncore_forcewake_put, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(shmem_pin_map, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(shmem_unpin_map, I915_GVT);
 EXPORT_SYMBOL_NS_GPL(__px_dma, I915_GVT);
+EXPORT_SYMBOL_NS_GPL(i915_fence_ops, I915_GVT);
-- 
2.17.1



[Intel-gfx] [PATCH v9 3/3] i915/gvt: Use the initial HW state snapshot saved in i915

2022-04-07 Thread Zhi Wang
The code of saving initial HW state snapshot has been moved into i915.
Let the GVT-g core logic use that snapshot.

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/firmware.c | 25 +
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/firmware.c 
b/drivers/gpu/drm/i915/gvt/firmware.c
index 1a8274a3f4b1..54fe442238c6 100644
--- a/drivers/gpu/drm/i915/gvt/firmware.c
+++ b/drivers/gpu/drm/i915/gvt/firmware.c
@@ -66,22 +66,16 @@ static struct bin_attribute firmware_attr = {
.mmap = NULL,
 };
 
-static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data)
-{
-   *(u32 *)(data + offset) = intel_uncore_read_notrace(gvt->gt->uncore,
-   _MMIO(offset));
-   return 0;
-}
-
 static int expose_firmware_sysfs(struct intel_gvt *gvt)
 {
struct intel_gvt_device_info *info = >device_info;
-   struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
+   struct drm_i915_private *i915 = gvt->gt->i915;
+   struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
struct gvt_firmware_header *h;
void *firmware;
void *p;
unsigned long size, crc32_start;
-   int i, ret;
+   int ret;
 
size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
firmware = vzalloc(size);
@@ -99,17 +93,16 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
 
p = firmware + h->cfg_space_offset;
 
-   for (i = 0; i < h->cfg_space_size; i += 4)
-   pci_read_config_dword(pdev, i, p + i);
-
-   memcpy(gvt->firmware.cfg_space, p, info->cfg_space_size);
+   memcpy(gvt->firmware.cfg_space, i915->vgpu.initial_cfg_space,
+  info->cfg_space_size);
+   memcpy(p, gvt->firmware.cfg_space, info->cfg_space_size);
 
p = firmware + h->mmio_offset;
 
-   /* Take a snapshot of hw mmio registers. */
-   intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, p);
+   memcpy(gvt->firmware.mmio, i915->vgpu.initial_mmio,
+  info->mmio_size);
 
-   memcpy(gvt->firmware.mmio, p, info->mmio_size);
+   memcpy(p, gvt->firmware.mmio, info->mmio_size);
 
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);
-- 
2.25.1



[Intel-gfx] [PATCH v9 1/3] i915/gvt: Separate the MMIO tracking table from GVT-g

2022-04-07 Thread Zhi Wang
From: Zhi Wang 

To support the new mdev interfaces and the re-factor patches from
Christoph, which moves the GVT-g code into a dedicated module, the GVT-g
MMIO tracking table needs to be separated from GVT-g.

v9:
- Fix a problem might cause kernel panic.

v8:
- Use SPDX header in the intel_gvt_mmio_table.c
- Reference the gvt.h with path. (Jani)
- Add a missing fix on mmio emulation path during the debug.
- Fix a building problem on refreshed gvt-staging branch. (Christoph)

v7:
- Keep the marcos of device generation in GVT-g. (Christoph, Jani)

v6:
- Move the mmio_table.c into i915. (Christoph)
- Keep init_device_info and related structures in GVT-g. (Christoph)
- Refine the callbacks of the iterator. (Christoph)
- Move the flags of MMIO register defination to GVT-g. (Chrsitoph)
- Move the mmio block handling to GVT-g.

v5:
- Re-design the mmio table framework. (Christoph)

v4:
- Fix the errors of patch checking scripts.

v3:
- Fix the errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

v2:
- Implement a mmio table instead of generating it by marco in i915. (Jani)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/Makefile   |2 +-
 drivers/gpu/drm/i915/gvt/gvt.h  |3 +-
 drivers/gpu/drm/i915/gvt/handlers.c | 1033 ++-
 drivers/gpu/drm/i915/gvt/mmio.h |1 -
 drivers/gpu/drm/i915/gvt/reg.h  |9 +-
 drivers/gpu/drm/i915/intel_gvt.h|   21 +
 drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 1290 +++
 7 files changed, 1460 insertions(+), 899 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_gvt_mmio_table.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 1a771ee5b1d0..b4abe0650ba1 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -321,7 +321,7 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \
 i915-y += i915_vgpu.o
 
 ifeq ($(CONFIG_DRM_I915_GVT),y)
-i915-y += intel_gvt.o
+i915-y += intel_gvt.o intel_gvt_mmio_table.o
 include $(src)/gvt/Makefile
 endif
 
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 0ebffc327528..bfe07c69cfd2 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -36,6 +36,7 @@
 #include 
 
 #include "i915_drv.h"
+#include "intel_gvt.h"
 
 #include "debug.h"
 #include "hypercall.h"
@@ -272,7 +273,7 @@ struct intel_gvt_mmio {
 /* Value of command write of this reg needs to be patched */
 #define F_CMD_WRITE_PATCH  (1 << 8)
 
-   const struct gvt_mmio_block *mmio_block;
+   struct gvt_mmio_block *mmio_block;
unsigned int num_mmio_block;
 
DECLARE_HASHTABLE(mmio_info_table, INTEL_GVT_MMIO_HASH_BITS);
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index 520a7e1942f3..9bd3c15bfab6 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -101,12 +101,11 @@ struct intel_gvt_mmio_info 
*intel_gvt_find_mmio_info(struct intel_gvt *gvt,
return NULL;
 }
 
-static int new_mmio_info(struct intel_gvt *gvt,
-   u32 offset, u16 flags, u32 size,
-   u32 addr_mask, u32 ro_mask, u32 device,
-   gvt_mmio_func read, gvt_mmio_func write)
+static int setup_mmio_info(struct intel_gvt *gvt, u32 offset, u32 size,
+  u16 flags, u32 addr_mask, u32 ro_mask, u32 device,
+  gvt_mmio_func read, gvt_mmio_func write)
 {
-   struct intel_gvt_mmio_info *info, *p;
+   struct intel_gvt_mmio_info *p;
u32 start, end, i;
 
if (!intel_gvt_match_device(gvt, device))
@@ -119,32 +118,18 @@ static int new_mmio_info(struct intel_gvt *gvt,
end = offset + size;
 
for (i = start; i < end; i += 4) {
-   info = kzalloc(sizeof(*info), GFP_KERNEL);
-   if (!info)
-   return -ENOMEM;
-
-   info->offset = i;
-   p = intel_gvt_find_mmio_info(gvt, info->offset);
-   if (p) {
-   WARN(1, "dup mmio definition offset %x\n",
-   info->offset);
-   kfree(info);
-
-   /* We return -EEXIST here to make GVT-g load fail.
-* So duplicated MMIO can be found as soon as
-* possible.
-*/
-   return -EEXIST;
+   p = intel_gvt_find_mmio_info(gvt, i);
+   if (!p) {
+   WARN(1, "assign a handler to a non-tracked mmio %x\n",
+   i);
+   return -ENODEV;
}
-
-   info->ro_mask = ro_mask;
-   info->devi

[Intel-gfx] [PATCH v9 2/3] i915/gvt: Save the initial HW state snapshot in i915

2022-04-07 Thread Zhi Wang
Save the initial HW state snapshot in i915 so that the rest code of GVT-g
can be moved into a dedicated module while it can still get a clean
initial HW state saved at the correct time during the initialization of
i915. The futhrer vGPU created by GVT-g will use this HW state as the
initial HW state.

v6:
- Remove the reference of intel_gvt_device_info.(Christoph)
- Refine the save_mmio() function. (Christoph)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/i915_drv.h  |  2 +
 drivers/gpu/drm/i915/intel_gvt.c | 92 +++-
 2 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 943267393ecb..abb39444b8be 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -421,6 +421,8 @@ struct i915_virtual_gpu {
struct mutex lock; /* serialises sending of g2v_notify command pkts */
bool active;
u32 caps;
+   u32 *initial_mmio;
+   u8 *initial_cfg_space;
 };
 
 struct i915_selftest_stash {
diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c
index cf6e98962d82..65daab2c4d9e 100644
--- a/drivers/gpu/drm/i915/intel_gvt.c
+++ b/drivers/gpu/drm/i915/intel_gvt.c
@@ -86,6 +86,85 @@ void intel_gvt_sanitize_options(struct drm_i915_private 
*dev_priv)
dev_priv->params.enable_gvt = 0;
 }
 
+static void free_initial_hw_state(struct drm_i915_private *dev_priv)
+{
+   struct i915_virtual_gpu *vgpu = _priv->vgpu;
+
+   vfree(vgpu->initial_mmio);
+   vgpu->initial_mmio = NULL;
+
+   kfree(vgpu->initial_cfg_space);
+   vgpu->initial_cfg_space = NULL;
+}
+
+static void save_mmio(struct intel_gvt_mmio_table_iter *iter, u32 offset,
+ u32 size)
+{
+   struct drm_i915_private *dev_priv = iter->i915;
+   u32 *mmio, i;
+
+   for (i = offset; i < offset + size; i += 4) {
+   mmio = iter->data + i;
+   *mmio = intel_uncore_read_notrace(to_gt(dev_priv)->uncore,
+ _MMIO(i));
+   }
+}
+
+static int handle_mmio(struct intel_gvt_mmio_table_iter *iter,
+  u32 offset, u32 size)
+{
+   if (WARN_ON(!IS_ALIGNED(offset, 4)))
+   return -EINVAL;
+
+   save_mmio(iter, offset, size);
+   return 0;
+}
+
+static int save_initial_hw_state(struct drm_i915_private *dev_priv)
+{
+   struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+   struct i915_virtual_gpu *vgpu = _priv->vgpu;
+   struct intel_gvt_mmio_table_iter iter;
+   void *mem;
+   int i, ret;
+
+   mem = kzalloc(PCI_CFG_SPACE_EXP_SIZE, GFP_KERNEL);
+   if (!mem)
+   return -ENOMEM;
+
+   vgpu->initial_cfg_space = mem;
+
+   for (i = 0; i < PCI_CFG_SPACE_EXP_SIZE; i += 4)
+   pci_read_config_dword(pdev, i, mem + i);
+
+   mem = vzalloc(2 * SZ_1M);
+   if (!mem) {
+   ret = -ENOMEM;
+   goto err_mmio;
+   }
+
+   vgpu->initial_mmio = mem;
+
+   iter.i915 = dev_priv;
+   iter.data = vgpu->initial_mmio;
+   iter.handle_mmio_cb = handle_mmio;
+
+   ret = intel_gvt_iterate_mmio_table();
+   if (ret)
+   goto err_iterate;
+
+   return 0;
+
+err_iterate:
+   vfree(vgpu->initial_mmio);
+   vgpu->initial_mmio = NULL;
+err_mmio:
+   kfree(vgpu->initial_cfg_space);
+   vgpu->initial_cfg_space = NULL;
+
+   return ret;
+}
+
 /**
  * intel_gvt_init - initialize GVT components
  * @dev_priv: drm i915 private data
@@ -115,15 +194,23 @@ int intel_gvt_init(struct drm_i915_private *dev_priv)
return -EIO;
}
 
+   ret = save_initial_hw_state(dev_priv);
+   if (ret) {
+   drm_dbg(_priv->drm, "Fail to save initial HW state\n");
+   goto err_save_hw_state;
+   }
+
ret = intel_gvt_init_device(dev_priv);
if (ret) {
drm_dbg(_priv->drm, "Fail to init GVT device\n");
-   goto bail;
+   goto err_init_device;
}
 
return 0;
 
-bail:
+err_init_device:
+   free_initial_hw_state(dev_priv);
+err_save_hw_state:
dev_priv->params.enable_gvt = 0;
return 0;
 }
@@ -147,6 +234,7 @@ void intel_gvt_driver_remove(struct drm_i915_private 
*dev_priv)
return;
 
intel_gvt_clean_device(dev_priv);
+   free_initial_hw_state(dev_priv);
 }
 
 /**
-- 
2.25.1



[Intel-gfx] [PATCH v9 0/3] Refactor GVT-g MMIO tracking table and handlers

2022-04-07 Thread Zhi Wang
To support the new mdev interfaces and the re-factor patches from
Christoph, which moves the GVT-g code into a dedicated module, the GVT-g
initialization path has to be separated into two phases:

a) Early initialization.

The early initialization of GVT requires to be done when loading i915.
Mostly it's because the initial clean HW state needs to be saved before
i915 touches the HW.

b) Late initalization.

This phases of initalization will setup the rest components of GVT-g,
which can be done later when the dedicated module is being loaded.

To initialize the GVT-g MMIO tracking table in the early initalization
stage, which will be done in i915, the GVT-g MMIO tracking table needs
to be sperated accordingly and moved into i915.

v9:
- Fix a problem might casue kernel panic.

v8:
- Use SPDX header in the intel_gvt_mmio_table.c
- Reference the gvt.h with path. (Jani)
- Add a missing fix on mmio emulation path during my debug.
- Fix a building problem on refreshed gvt-staging branch. (Christoph)


v7:
- Keep the marcos of device generation in GVT-g. (Christoph, Jani)

v6:
- Move the mmio_table.c into i915. (Christoph)
- Keep init_device_info and related structures in GVT-g. (Christoph)
- Refine the callbacks of the iterator. (Christoph)
- Move the flags of MMIO register defination to GVT-g. (Chrsitoph)
- Move the mmio block handling to GVT-g.

v5:
- Re-design the mmio table framework. (Christoph)

v4:
- Fix the errors of patch checking scripts.

v3:
- Fix the errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

v2:
- Implement a mmio table instead of generating it by marco in i915. (Jani)

Zhi Wang (3):
  i915/gvt: Separate the MMIO tracking table from GVT-g
  i915/gvt: Save the initial HW state snapshot in i915
  i915/gvt: Use the initial HW state snapshot saved in i915

 drivers/gpu/drm/i915/Makefile   |2 +-
 drivers/gpu/drm/i915/gvt/firmware.c |   25 +-
 drivers/gpu/drm/i915/gvt/gvt.h  |3 +-
 drivers/gpu/drm/i915/gvt/handlers.c | 1033 ++-
 drivers/gpu/drm/i915/gvt/mmio.h |1 -
 drivers/gpu/drm/i915/gvt/reg.h  |9 +-
 drivers/gpu/drm/i915/i915_drv.h |2 +
 drivers/gpu/drm/i915/intel_gvt.c|   92 +-
 drivers/gpu/drm/i915/intel_gvt.h|   21 +
 drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 1290 +++
 10 files changed, 1561 insertions(+), 917 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_gvt_mmio_table.c

-- 
2.25.1



[Intel-gfx] [PATCH v8 3/3] i915/gvt: Use the initial HW state snapshot saved in i915

2022-04-01 Thread Zhi Wang
The code of saving initial HW state snapshot has been moved into i915.
Let the GVT-g core logic use that snapshot.

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/firmware.c | 25 +
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/firmware.c 
b/drivers/gpu/drm/i915/gvt/firmware.c
index 1a8274a3f4b1..54fe442238c6 100644
--- a/drivers/gpu/drm/i915/gvt/firmware.c
+++ b/drivers/gpu/drm/i915/gvt/firmware.c
@@ -66,22 +66,16 @@ static struct bin_attribute firmware_attr = {
.mmap = NULL,
 };
 
-static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data)
-{
-   *(u32 *)(data + offset) = intel_uncore_read_notrace(gvt->gt->uncore,
-   _MMIO(offset));
-   return 0;
-}
-
 static int expose_firmware_sysfs(struct intel_gvt *gvt)
 {
struct intel_gvt_device_info *info = >device_info;
-   struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
+   struct drm_i915_private *i915 = gvt->gt->i915;
+   struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
struct gvt_firmware_header *h;
void *firmware;
void *p;
unsigned long size, crc32_start;
-   int i, ret;
+   int ret;
 
size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
firmware = vzalloc(size);
@@ -99,17 +93,16 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
 
p = firmware + h->cfg_space_offset;
 
-   for (i = 0; i < h->cfg_space_size; i += 4)
-   pci_read_config_dword(pdev, i, p + i);
-
-   memcpy(gvt->firmware.cfg_space, p, info->cfg_space_size);
+   memcpy(gvt->firmware.cfg_space, i915->vgpu.initial_cfg_space,
+  info->cfg_space_size);
+   memcpy(p, gvt->firmware.cfg_space, info->cfg_space_size);
 
p = firmware + h->mmio_offset;
 
-   /* Take a snapshot of hw mmio registers. */
-   intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, p);
+   memcpy(gvt->firmware.mmio, i915->vgpu.initial_mmio,
+  info->mmio_size);
 
-   memcpy(gvt->firmware.mmio, p, info->mmio_size);
+   memcpy(p, gvt->firmware.mmio, info->mmio_size);
 
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);
-- 
2.25.1



[Intel-gfx] [PATCH v8 1/3] i915/gvt: Separate the MMIO tracking table from GVT-g

2022-04-01 Thread Zhi Wang
From: Zhi Wang 

To support the new mdev interfaces and the re-factor patches from
Christoph, which moves the GVT-g code into a dedicated module, the GVT-g
MMIO tracking table needs to be separated from GVT-g.

---
v8:

- Use SPDX header in the intel_gvt_mmio_table.c
- Reference the gvt.h with path. (Jani)
- Add a missing fix on mmio emulation path during the debug.
- Fix a building problem on refreshed gvt-staging branch. (Christoph)

v7:

- Keep the marcos of device generation in GVT-g. (Christoph, Jani)

v6:

- Move the mmio_table.c into i915. (Christoph)
- Keep init_device_info and related structures in GVT-g. (Christoph)
- Refine the callbacks of the iterator. (Christoph)
- Move the flags of MMIO register defination to GVT-g. (Chrsitoph)
- Move the mmio block handling to GVT-g.

v5:

- Re-design the mmio table framework. (Christoph)

v4:

- Fix the errors of patch checking scripts.

v3:

- Fix the errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

v2:

- Implement a mmio table instead of generating it by marco in i915. (Jani)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/Makefile   |2 +-
 drivers/gpu/drm/i915/gvt/gvt.h  |3 +-
 drivers/gpu/drm/i915/gvt/handlers.c | 1031 ++-
 drivers/gpu/drm/i915/gvt/mmio.h |1 -
 drivers/gpu/drm/i915/gvt/reg.h  |9 +-
 drivers/gpu/drm/i915/intel_gvt.h|   21 +
 drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 1290 +++
 7 files changed, 1458 insertions(+), 899 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_gvt_mmio_table.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 1a771ee5b1d0..b4abe0650ba1 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -321,7 +321,7 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \
 i915-y += i915_vgpu.o
 
 ifeq ($(CONFIG_DRM_I915_GVT),y)
-i915-y += intel_gvt.o
+i915-y += intel_gvt.o intel_gvt_mmio_table.o
 include $(src)/gvt/Makefile
 endif
 
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 0ebffc327528..bfe07c69cfd2 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -36,6 +36,7 @@
 #include 
 
 #include "i915_drv.h"
+#include "intel_gvt.h"
 
 #include "debug.h"
 #include "hypercall.h"
@@ -272,7 +273,7 @@ struct intel_gvt_mmio {
 /* Value of command write of this reg needs to be patched */
 #define F_CMD_WRITE_PATCH  (1 << 8)
 
-   const struct gvt_mmio_block *mmio_block;
+   struct gvt_mmio_block *mmio_block;
unsigned int num_mmio_block;
 
DECLARE_HASHTABLE(mmio_info_table, INTEL_GVT_MMIO_HASH_BITS);
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index 520a7e1942f3..a84783eecd3b 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -101,12 +101,11 @@ struct intel_gvt_mmio_info 
*intel_gvt_find_mmio_info(struct intel_gvt *gvt,
return NULL;
 }
 
-static int new_mmio_info(struct intel_gvt *gvt,
-   u32 offset, u16 flags, u32 size,
-   u32 addr_mask, u32 ro_mask, u32 device,
-   gvt_mmio_func read, gvt_mmio_func write)
+static int setup_mmio_info(struct intel_gvt *gvt, u32 offset, u32 size,
+  u16 flags, u32 addr_mask, u32 ro_mask, u32 device,
+  gvt_mmio_func read, gvt_mmio_func write)
 {
-   struct intel_gvt_mmio_info *info, *p;
+   struct intel_gvt_mmio_info *p;
u32 start, end, i;
 
if (!intel_gvt_match_device(gvt, device))
@@ -119,32 +118,18 @@ static int new_mmio_info(struct intel_gvt *gvt,
end = offset + size;
 
for (i = start; i < end; i += 4) {
-   info = kzalloc(sizeof(*info), GFP_KERNEL);
-   if (!info)
-   return -ENOMEM;
-
-   info->offset = i;
-   p = intel_gvt_find_mmio_info(gvt, info->offset);
-   if (p) {
-   WARN(1, "dup mmio definition offset %x\n",
-   info->offset);
-   kfree(info);
-
-   /* We return -EEXIST here to make GVT-g load fail.
-* So duplicated MMIO can be found as soon as
-* possible.
-*/
-   return -EEXIST;
+   p = intel_gvt_find_mmio_info(gvt, i);
+   if (!p) {
+   WARN(1, "assign a handler to a non-tracked mmio %x\n",
+   i);
+   return -ENODEV;
}
-
-   info->ro_mask = ro_mask;
-   info->device = device;
-   info->

[Intel-gfx] [PATCH v8 2/3] i915/gvt: Save the initial HW state snapshot in i915

2022-04-01 Thread Zhi Wang
Save the initial HW state snapshot in i915 so that the rest code of GVT-g
can be moved into a dedicated module while it can still get a clean
initial HW state saved at the correct time during the initialization of
i915. The futhrer vGPU created by GVT-g will use this HW state as the
initial HW state.

---
v6:

- Remove the reference of intel_gvt_device_info.(Christoph)
- Refine the save_mmio() function. (Christoph)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/i915_drv.h  |  2 +
 drivers/gpu/drm/i915/intel_gvt.c | 92 +++-
 2 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 943267393ecb..abb39444b8be 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -421,6 +421,8 @@ struct i915_virtual_gpu {
struct mutex lock; /* serialises sending of g2v_notify command pkts */
bool active;
u32 caps;
+   u32 *initial_mmio;
+   u8 *initial_cfg_space;
 };
 
 struct i915_selftest_stash {
diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c
index cf6e98962d82..65daab2c4d9e 100644
--- a/drivers/gpu/drm/i915/intel_gvt.c
+++ b/drivers/gpu/drm/i915/intel_gvt.c
@@ -86,6 +86,85 @@ void intel_gvt_sanitize_options(struct drm_i915_private 
*dev_priv)
dev_priv->params.enable_gvt = 0;
 }
 
+static void free_initial_hw_state(struct drm_i915_private *dev_priv)
+{
+   struct i915_virtual_gpu *vgpu = _priv->vgpu;
+
+   vfree(vgpu->initial_mmio);
+   vgpu->initial_mmio = NULL;
+
+   kfree(vgpu->initial_cfg_space);
+   vgpu->initial_cfg_space = NULL;
+}
+
+static void save_mmio(struct intel_gvt_mmio_table_iter *iter, u32 offset,
+ u32 size)
+{
+   struct drm_i915_private *dev_priv = iter->i915;
+   u32 *mmio, i;
+
+   for (i = offset; i < offset + size; i += 4) {
+   mmio = iter->data + i;
+   *mmio = intel_uncore_read_notrace(to_gt(dev_priv)->uncore,
+ _MMIO(i));
+   }
+}
+
+static int handle_mmio(struct intel_gvt_mmio_table_iter *iter,
+  u32 offset, u32 size)
+{
+   if (WARN_ON(!IS_ALIGNED(offset, 4)))
+   return -EINVAL;
+
+   save_mmio(iter, offset, size);
+   return 0;
+}
+
+static int save_initial_hw_state(struct drm_i915_private *dev_priv)
+{
+   struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+   struct i915_virtual_gpu *vgpu = _priv->vgpu;
+   struct intel_gvt_mmio_table_iter iter;
+   void *mem;
+   int i, ret;
+
+   mem = kzalloc(PCI_CFG_SPACE_EXP_SIZE, GFP_KERNEL);
+   if (!mem)
+   return -ENOMEM;
+
+   vgpu->initial_cfg_space = mem;
+
+   for (i = 0; i < PCI_CFG_SPACE_EXP_SIZE; i += 4)
+   pci_read_config_dword(pdev, i, mem + i);
+
+   mem = vzalloc(2 * SZ_1M);
+   if (!mem) {
+   ret = -ENOMEM;
+   goto err_mmio;
+   }
+
+   vgpu->initial_mmio = mem;
+
+   iter.i915 = dev_priv;
+   iter.data = vgpu->initial_mmio;
+   iter.handle_mmio_cb = handle_mmio;
+
+   ret = intel_gvt_iterate_mmio_table();
+   if (ret)
+   goto err_iterate;
+
+   return 0;
+
+err_iterate:
+   vfree(vgpu->initial_mmio);
+   vgpu->initial_mmio = NULL;
+err_mmio:
+   kfree(vgpu->initial_cfg_space);
+   vgpu->initial_cfg_space = NULL;
+
+   return ret;
+}
+
 /**
  * intel_gvt_init - initialize GVT components
  * @dev_priv: drm i915 private data
@@ -115,15 +194,23 @@ int intel_gvt_init(struct drm_i915_private *dev_priv)
return -EIO;
}
 
+   ret = save_initial_hw_state(dev_priv);
+   if (ret) {
+   drm_dbg(_priv->drm, "Fail to save initial HW state\n");
+   goto err_save_hw_state;
+   }
+
ret = intel_gvt_init_device(dev_priv);
if (ret) {
drm_dbg(_priv->drm, "Fail to init GVT device\n");
-   goto bail;
+   goto err_init_device;
}
 
return 0;
 
-bail:
+err_init_device:
+   free_initial_hw_state(dev_priv);
+err_save_hw_state:
dev_priv->params.enable_gvt = 0;
return 0;
 }
@@ -147,6 +234,7 @@ void intel_gvt_driver_remove(struct drm_i915_private 
*dev_priv)
return;
 
intel_gvt_clean_device(dev_priv);
+   free_initial_hw_state(dev_priv);
 }
 
 /**
-- 
2.25.1



[Intel-gfx] [PATCH v8 0/3] Refactor GVT-g MMIO tracking table and handlers

2022-04-01 Thread Zhi Wang
To support the new mdev interfaces and the re-factor patches from
Christoph, which moves the GVT-g code into a dedicated module, the GVT-g
initialization path has to be separated into two phases:

a) Early initialization.

The early initialization of GVT requires to be done when loading i915.
Mostly it's because the initial clean HW state needs to be saved before
i915 touches the HW.

b) Late initalization.

This phases of initalization will setup the rest components of GVT-g,
which can be done later when the dedicated module is being loaded.

To initialize the GVT-g MMIO tracking table in the early initalization
stage, which will be done in i915, the GVT-g MMIO tracking table needs
to be sperated accordingly and moved into i915.

---
v8:

- Use SPDX header in the intel_gvt_mmio_table.c
- Reference the gvt.h with path. (Jani)
- Add a missing fix on mmio emulation path during my debug.
- Fix a building problem on refreshed gvt-staging branch. (Christoph)


v7:

- Keep the marcos of device generation in GVT-g. (Christoph, Jani)

v6:

- Move the mmio_table.c into i915. (Christoph)
- Keep init_device_info and related structures in GVT-g. (Christoph)
- Refine the callbacks of the iterator. (Christoph)
- Move the flags of MMIO register defination to GVT-g. (Chrsitoph)
- Move the mmio block handling to GVT-g.

v5:

- Re-design the mmio table framework. (Christoph)

v4:

- Fix the errors of patch checking scripts.

v3:

- Fix the errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

v2:

- Implement a mmio table instead of generating it by marco in i915. (Jani)

Zhi Wang (3):
  i915/gvt: Separate the MMIO tracking table from GVT-g
  i915/gvt: Save the initial HW state snapshot in i915
  i915/gvt: Use the initial HW state snapshot saved in i915

 drivers/gpu/drm/i915/Makefile   |2 +-
 drivers/gpu/drm/i915/gvt/firmware.c |   25 +-
 drivers/gpu/drm/i915/gvt/gvt.h  |3 +-
 drivers/gpu/drm/i915/gvt/handlers.c | 1031 ++-
 drivers/gpu/drm/i915/gvt/mmio.h |1 -
 drivers/gpu/drm/i915/gvt/reg.h  |9 +-
 drivers/gpu/drm/i915/i915_drv.h |2 +
 drivers/gpu/drm/i915/intel_gvt.c|   92 +-
 drivers/gpu/drm/i915/intel_gvt.h|   21 +
 drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 1290 +++
 10 files changed, 1559 insertions(+), 917 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_gvt_mmio_table.c

-- 
2.25.1



Re: [Intel-gfx] [PATCH v7 1/3] i915/gvt: Separate the MMIO tracking table from GVT-g

2022-03-31 Thread Zhi Wang

Thanks. Let me fix that. :)

On 3/31/22 04:33, Christoph Hellwig wrote:

On Thu, Mar 31, 2022 at 08:04:04AM +, Wang, Zhi A wrote:

Hi Chris:

Thanks for the testing. Can you attach the dmesg? I tested mostly on my skylake 
desktop with some 3D workload.

Sure, I should have done that from the beginning:

[   25.354587] vfio_mdev 6814f392-50ac-4236-ae3d-26d472fd8aae: Adding to iommu 
group 0
[   25.583015] L1TF CPU bug present and SMT on, data leak possible. See 
CVE-2018-3646 and 
https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/l1tf.html for 
details.
[   26.429492] kvm [2555]: vcpu0, guest rIP: 0x81003e6e disabled 
perfctr wrmsr: 0xc2 data 0x
[   30.206202] BUG: kernel NULL pointer dereference, address: 
[   30.206206] #PF: supervisor instruction fetch in kernel mode
[   30.206208] #PF: error_code(0x0010) - not-present page
[   30.206209] PGD 0 P4D 0
[   30.206211] Oops: 0010 [#1] PREEMPT SMP PTI
[   30.206214] CPU: 6 PID: 2565 Comm: qemu-system-x86 Tainted: GE   
  5.17.0+ #1292
[   30.206216] Hardware name: LENOVO 20KH006JGE/20KH006JGE, BIOS N23ET62W (1.37 
) 02/19/2019
[   30.206217] RIP: 0010:0x0
[   30.206223] Code: Unable to access opcode bytes at RIP 0xffd6.
[   30.206224] RSP: 0018:a775c3fb3e18 EFLAGS: 00010286
[   30.206226] RAX:  RBX: 90a808bc RCX: 0004
[   30.206227] RDX: a775c3fb3e80 RSI: 00042300 RDI: a775c40ad000
[   30.206228] RBP: a775c40ad000 R08: 0001 R09: 00021180
[   30.206230] R10: a775c3fb3e80 R11: a775c3fb3e80 R12: 0004
[   30.206231] R13: fd042300 R14: 00042300 R15: a775c40ad008
[   30.206232] FS:  7fdd9cbfc700() GS:90ab9278() 
knlGS:
[   30.206233] CS:  0010 DS:  ES:  CR0: 80050033
[   30.206235] CR2: ffd6 CR3: 0001c117c002 CR4: 003726e0
[   30.206236] Call Trace:
[   30.206238]  
[   30.206239]  intel_vgpu_emulate_mmio_read+0xe9/0x390
[   30.206247]  intel_vgpu_rw.isra.0+0x1a7/0x1e0
[   30.206249]  intel_vgpu_read+0x15c/0x200
[   30.206252]  vfs_read+0x9b/0x190
[   30.206257]  __x64_sys_pread64+0x8d/0xc0
[   30.206259]  do_syscall_64+0x3b/0x90
[   30.206263]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[   30.206266] RIP: 0033:0x7fddb17e41a7
[   30.206268] Code: 08 89 3c 24 48 89 4c 24 18 e8 f5 7b f9 ff 4c 8b 54 24 18 48 8b 
54 24 10 41 89 c0 48 8b 74 24 08 8b 3c 24 b8 11 00 00 00 0f 05 <48> 3d 00 f0 ff 
ff 77 31 44 89 c7 48 89 04 24 e8 25 7c f9 ff 48 8b
[   30.206270] RSP: 002b:7fdd9cbfb2f0 EFLAGS: 0293 ORIG_RAX: 
0011
[   30.206272] RAX: ffda RBX: 55ee30d20ed8 RCX: 7fddb17e41a7
[   30.206273] RDX: 0004 RSI: 7fdd9cbfb338 RDI: 001b
[   30.206274] RBP: 0004 R08:  R09: 
[   30.206275] R10: 00042300 R11: 0293 R12: 00042300
[   30.206276] R13: 55ee30d20df0 R14: 0004 R15: 00042300
[   30.206278]  
[   30.206279] Modules linked in: cmac(E) ctr(E) ccm(E) rfcomm(E) sd_mod(E) 
sg(E) uvcvideo(E) videobuf2_vmalloc(E) videobuf2_memops(E) videobuf2_v4l2(E) 
videobuf2_common(E) videodev(E) mc(E) btusb(E) btrtl(E) btbcm(E) btintel(E) 
uas(E) usb_storage(E) scsi_mod(E) scsi_common(E) bnep(E) snd_hda_codec_hdmi(E) 
wmi_bmof(E) intel_wmi_thunderbolt(E) joydev(E) bluetooth(E) intel_rapl_msr(E) 
crc16(E) x86_pkg_temp_thermal(E) jitterentropy_rng(E) intel_powerclamp(E) 
sha512_generic(E) drbg(E) coretemp(E) ansi_cprng(E) crc32_pclmul(E) 
ecdh_generic(E) ghash_clmulni_intel(E) ecc(E) aesni_intel(E) libaes(E) 
crypto_simd(E) iwlmvm(E) snd_soc_skl(E) cryptd(E) snd_soc_hdac_hda(E) 
mac80211(E) snd_ctl_led(E) snd_hda_ext_core(E) snd_hda_codec_realtek(E) 
libarc4(E) snd_soc_core(E) snd_hda_codec_generic(E) snd_soc_acpi_intel_match(E) 
kvm_intel(E) snd_soc_acpi(E) snd_soc_sst_ipc(E) iwlwifi(E) snd_soc_sst_dsp(E) 
intel_cstate(E) intel_uncore(E) snd_hda_intel(E) serio_raw(E) 
snd_intel_dspcfg(E) pcspkr(E)
[   30.206314]  snd_hda_codec(E) efi_pstore(E) snd_hwdep(E) tpm_crb(E) 
processor_thermal_device_pci_legacy(E) snd_hda_core(E) intel_soc_dts_iosf(E) 
iTCO_wdt(E) iTCO_vendor_support(E) cfg80211(E) processor_thermal_device(E) 
snd_pcm(E) tpm_tis(E) processor_thermal_rfim(E) thinkpad_acpi(E) watchdog(E) 
processor_thermal_mbox(E) tpm_tis_core(E) ucsi_acpi(E) nvram(E) mei_me(E) 
snd_timer(E) processor_thermal_rapl(E) ledtrig_audio(E) intel_pch_thermal(E) 
tpm(E) intel_rapl_common(E) mei(E) platform_profile(E) typec_ucsi(E) typec(E) 
rng_core(E) wmi(E) snd(E) battery(E) ac(E) soundcore(E) int3403_thermal(E) 
rfkill(E) int340x_thermal_zone(E) int3400_thermal(E) evdev(E) acpi_pad(E) 
acpi_thermal_rel(E) parport_pc(E) ppdev(E) lp(E) parport(E) efivarfs(E) 
ip_tables(E) x_tables(E) autofs4(E) i2c_designware_platform(E) 
i2c_designware_core(E) nvme(E) nvme_core(E) t10_pi(E) xhci_pci(E) e1000e(E) 

[Intel-gfx] [PATCH v7 3/3] i915/gvt: Use the initial HW state snapshot saved in i915

2022-03-25 Thread Zhi Wang
The code of saving initial HW state snapshot has been moved into i915.
Let the GVT-g core logic use that snapshot.

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/firmware.c | 25 +
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/firmware.c 
b/drivers/gpu/drm/i915/gvt/firmware.c
index 1a8274a3f4b1..54fe442238c6 100644
--- a/drivers/gpu/drm/i915/gvt/firmware.c
+++ b/drivers/gpu/drm/i915/gvt/firmware.c
@@ -66,22 +66,16 @@ static struct bin_attribute firmware_attr = {
.mmap = NULL,
 };
 
-static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data)
-{
-   *(u32 *)(data + offset) = intel_uncore_read_notrace(gvt->gt->uncore,
-   _MMIO(offset));
-   return 0;
-}
-
 static int expose_firmware_sysfs(struct intel_gvt *gvt)
 {
struct intel_gvt_device_info *info = >device_info;
-   struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
+   struct drm_i915_private *i915 = gvt->gt->i915;
+   struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
struct gvt_firmware_header *h;
void *firmware;
void *p;
unsigned long size, crc32_start;
-   int i, ret;
+   int ret;
 
size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
firmware = vzalloc(size);
@@ -99,17 +93,16 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
 
p = firmware + h->cfg_space_offset;
 
-   for (i = 0; i < h->cfg_space_size; i += 4)
-   pci_read_config_dword(pdev, i, p + i);
-
-   memcpy(gvt->firmware.cfg_space, p, info->cfg_space_size);
+   memcpy(gvt->firmware.cfg_space, i915->vgpu.initial_cfg_space,
+  info->cfg_space_size);
+   memcpy(p, gvt->firmware.cfg_space, info->cfg_space_size);
 
p = firmware + h->mmio_offset;
 
-   /* Take a snapshot of hw mmio registers. */
-   intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, p);
+   memcpy(gvt->firmware.mmio, i915->vgpu.initial_mmio,
+  info->mmio_size);
 
-   memcpy(gvt->firmware.mmio, p, info->mmio_size);
+   memcpy(p, gvt->firmware.mmio, info->mmio_size);
 
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);
-- 
2.25.1



[Intel-gfx] [PATCH v7 2/3] i915/gvt: Save the initial HW state snapshot in i915

2022-03-25 Thread Zhi Wang
Save the initial HW state snapshot in i915 so that the rest code of GVT-g
can be moved into a dedicated module while it can still get a clean
initial HW state saved at the correct time during the initialization of
i915. The futhrer vGPU created by GVT-g will use this HW state as the
initial HW state.

v6:

- Remove the reference of intel_gvt_device_info.(Christoph)
- Refine the save_mmio() function. (Christoph)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/i915_drv.h  |  2 +
 drivers/gpu/drm/i915/intel_gvt.c | 92 +++-
 2 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 418091484e02..0edc9ecbd403 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -429,6 +429,8 @@ struct i915_virtual_gpu {
struct mutex lock; /* serialises sending of g2v_notify command pkts */
bool active;
u32 caps;
+   u32 *initial_mmio;
+   u8 *initial_cfg_space;
 };
 
 struct i915_selftest_stash {
diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c
index cf6e98962d82..65daab2c4d9e 100644
--- a/drivers/gpu/drm/i915/intel_gvt.c
+++ b/drivers/gpu/drm/i915/intel_gvt.c
@@ -86,6 +86,85 @@ void intel_gvt_sanitize_options(struct drm_i915_private 
*dev_priv)
dev_priv->params.enable_gvt = 0;
 }
 
+static void free_initial_hw_state(struct drm_i915_private *dev_priv)
+{
+   struct i915_virtual_gpu *vgpu = _priv->vgpu;
+
+   vfree(vgpu->initial_mmio);
+   vgpu->initial_mmio = NULL;
+
+   kfree(vgpu->initial_cfg_space);
+   vgpu->initial_cfg_space = NULL;
+}
+
+static void save_mmio(struct intel_gvt_mmio_table_iter *iter, u32 offset,
+ u32 size)
+{
+   struct drm_i915_private *dev_priv = iter->i915;
+   u32 *mmio, i;
+
+   for (i = offset; i < offset + size; i += 4) {
+   mmio = iter->data + i;
+   *mmio = intel_uncore_read_notrace(to_gt(dev_priv)->uncore,
+ _MMIO(i));
+   }
+}
+
+static int handle_mmio(struct intel_gvt_mmio_table_iter *iter,
+  u32 offset, u32 size)
+{
+   if (WARN_ON(!IS_ALIGNED(offset, 4)))
+   return -EINVAL;
+
+   save_mmio(iter, offset, size);
+   return 0;
+}
+
+static int save_initial_hw_state(struct drm_i915_private *dev_priv)
+{
+   struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+   struct i915_virtual_gpu *vgpu = _priv->vgpu;
+   struct intel_gvt_mmio_table_iter iter;
+   void *mem;
+   int i, ret;
+
+   mem = kzalloc(PCI_CFG_SPACE_EXP_SIZE, GFP_KERNEL);
+   if (!mem)
+   return -ENOMEM;
+
+   vgpu->initial_cfg_space = mem;
+
+   for (i = 0; i < PCI_CFG_SPACE_EXP_SIZE; i += 4)
+   pci_read_config_dword(pdev, i, mem + i);
+
+   mem = vzalloc(2 * SZ_1M);
+   if (!mem) {
+   ret = -ENOMEM;
+   goto err_mmio;
+   }
+
+   vgpu->initial_mmio = mem;
+
+   iter.i915 = dev_priv;
+   iter.data = vgpu->initial_mmio;
+   iter.handle_mmio_cb = handle_mmio;
+
+   ret = intel_gvt_iterate_mmio_table();
+   if (ret)
+   goto err_iterate;
+
+   return 0;
+
+err_iterate:
+   vfree(vgpu->initial_mmio);
+   vgpu->initial_mmio = NULL;
+err_mmio:
+   kfree(vgpu->initial_cfg_space);
+   vgpu->initial_cfg_space = NULL;
+
+   return ret;
+}
+
 /**
  * intel_gvt_init - initialize GVT components
  * @dev_priv: drm i915 private data
@@ -115,15 +194,23 @@ int intel_gvt_init(struct drm_i915_private *dev_priv)
return -EIO;
}
 
+   ret = save_initial_hw_state(dev_priv);
+   if (ret) {
+   drm_dbg(_priv->drm, "Fail to save initial HW state\n");
+   goto err_save_hw_state;
+   }
+
ret = intel_gvt_init_device(dev_priv);
if (ret) {
drm_dbg(_priv->drm, "Fail to init GVT device\n");
-   goto bail;
+   goto err_init_device;
}
 
return 0;
 
-bail:
+err_init_device:
+   free_initial_hw_state(dev_priv);
+err_save_hw_state:
dev_priv->params.enable_gvt = 0;
return 0;
 }
@@ -147,6 +234,7 @@ void intel_gvt_driver_remove(struct drm_i915_private 
*dev_priv)
return;
 
intel_gvt_clean_device(dev_priv);
+   free_initial_hw_state(dev_priv);
 }
 
 /**
-- 
2.25.1



[Intel-gfx] [PATCH v7 1/3] i915/gvt: Separate the MMIO tracking table from GVT-g

2022-03-25 Thread Zhi Wang
From: Zhi Wang 

To support the new mdev interfaces and the re-factor patches from
Christoph, which moves the GVT-g code into a dedicated module, the GVT-g
MMIO tracking table needs to be separated from GVT-g.

v7:

- Keep the marcos of device generation in GVT-g. (Christoph, Jani)

v6:

- Move the mmio_table.c into i915. (Christoph)
- Keep init_device_info and related structures in GVT-g. (Christoph)
- Refine the callbacks of the iterator. (Christoph)
- Move the flags of MMIO register defination to GVT-g. (Chrsitoph)
- Move the mmio block handling to GVT-g.

v5:

- Re-design the mmio table framework. (Christoph)

v4:

- Fix the errors of patch checking scripts.

v3:

- Fix the errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

v2:

- Implement a mmio table instead of generating it by marco in i915. (Jani)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/Makefile   |2 +-
 drivers/gpu/drm/i915/gvt/gvt.h  |3 +-
 drivers/gpu/drm/i915/gvt/handlers.c | 1031 ++-
 drivers/gpu/drm/i915/gvt/mmio.h |1 -
 drivers/gpu/drm/i915/gvt/reg.h  |9 +-
 drivers/gpu/drm/i915/intel_gvt.h|   21 +
 drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 1308 +++
 7 files changed, 1476 insertions(+), 899 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_gvt_mmio_table.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 9d588d936e3d..cbd1a0a01cda 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -320,7 +320,7 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \
 i915-y += i915_vgpu.o
 
 ifeq ($(CONFIG_DRM_I915_GVT),y)
-i915-y += intel_gvt.o
+i915-y += intel_gvt.o intel_gvt_mmio_table.o
 include $(src)/gvt/Makefile
 endif
 
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 0ebffc327528..bfe07c69cfd2 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -36,6 +36,7 @@
 #include 
 
 #include "i915_drv.h"
+#include "intel_gvt.h"
 
 #include "debug.h"
 #include "hypercall.h"
@@ -272,7 +273,7 @@ struct intel_gvt_mmio {
 /* Value of command write of this reg needs to be patched */
 #define F_CMD_WRITE_PATCH  (1 << 8)
 
-   const struct gvt_mmio_block *mmio_block;
+   struct gvt_mmio_block *mmio_block;
unsigned int num_mmio_block;
 
DECLARE_HASHTABLE(mmio_info_table, INTEL_GVT_MMIO_HASH_BITS);
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index 5e3ae5970c6b..1a3702649d8c 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -100,12 +100,11 @@ struct intel_gvt_mmio_info 
*intel_gvt_find_mmio_info(struct intel_gvt *gvt,
return NULL;
 }
 
-static int new_mmio_info(struct intel_gvt *gvt,
-   u32 offset, u16 flags, u32 size,
-   u32 addr_mask, u32 ro_mask, u32 device,
-   gvt_mmio_func read, gvt_mmio_func write)
+static int setup_mmio_info(struct intel_gvt *gvt, u32 offset, u32 size,
+  u16 flags, u32 addr_mask, u32 ro_mask, u32 device,
+  gvt_mmio_func read, gvt_mmio_func write)
 {
-   struct intel_gvt_mmio_info *info, *p;
+   struct intel_gvt_mmio_info *p;
u32 start, end, i;
 
if (!intel_gvt_match_device(gvt, device))
@@ -118,32 +117,18 @@ static int new_mmio_info(struct intel_gvt *gvt,
end = offset + size;
 
for (i = start; i < end; i += 4) {
-   info = kzalloc(sizeof(*info), GFP_KERNEL);
-   if (!info)
-   return -ENOMEM;
-
-   info->offset = i;
-   p = intel_gvt_find_mmio_info(gvt, info->offset);
-   if (p) {
-   WARN(1, "dup mmio definition offset %x\n",
-   info->offset);
-   kfree(info);
-
-   /* We return -EEXIST here to make GVT-g load fail.
-* So duplicated MMIO can be found as soon as
-* possible.
-*/
-   return -EEXIST;
+   p = intel_gvt_find_mmio_info(gvt, i);
+   if (!p) {
+   WARN(1, "assign a handler to a non-tracked mmio %x\n",
+   i);
+   return -ENODEV;
}
-
-   info->ro_mask = ro_mask;
-   info->device = device;
-   info->read = read ? read : intel_vgpu_default_mmio_read;
-   info->write = write ? write : intel_vgpu_default_mmio_write;
-   gvt->mmio.mmio_attribute[info->offset / 4] = flags;
-  

[Intel-gfx] [PATCH v6 3/3] i915/gvt: Use the initial HW state snapshot saved in i915

2022-02-08 Thread Zhi Wang
The code of saving initial HW state snapshot has been moved into i915.
Let the GVT-g core logic use that snapshot.

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/firmware.c | 25 +
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/firmware.c 
b/drivers/gpu/drm/i915/gvt/firmware.c
index 1a8274a3f4b1..54fe442238c6 100644
--- a/drivers/gpu/drm/i915/gvt/firmware.c
+++ b/drivers/gpu/drm/i915/gvt/firmware.c
@@ -66,22 +66,16 @@ static struct bin_attribute firmware_attr = {
.mmap = NULL,
 };
 
-static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data)
-{
-   *(u32 *)(data + offset) = intel_uncore_read_notrace(gvt->gt->uncore,
-   _MMIO(offset));
-   return 0;
-}
-
 static int expose_firmware_sysfs(struct intel_gvt *gvt)
 {
struct intel_gvt_device_info *info = >device_info;
-   struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
+   struct drm_i915_private *i915 = gvt->gt->i915;
+   struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
struct gvt_firmware_header *h;
void *firmware;
void *p;
unsigned long size, crc32_start;
-   int i, ret;
+   int ret;
 
size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
firmware = vzalloc(size);
@@ -99,17 +93,16 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
 
p = firmware + h->cfg_space_offset;
 
-   for (i = 0; i < h->cfg_space_size; i += 4)
-   pci_read_config_dword(pdev, i, p + i);
-
-   memcpy(gvt->firmware.cfg_space, p, info->cfg_space_size);
+   memcpy(gvt->firmware.cfg_space, i915->vgpu.initial_cfg_space,
+  info->cfg_space_size);
+   memcpy(p, gvt->firmware.cfg_space, info->cfg_space_size);
 
p = firmware + h->mmio_offset;
 
-   /* Take a snapshot of hw mmio registers. */
-   intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, p);
+   memcpy(gvt->firmware.mmio, i915->vgpu.initial_mmio,
+  info->mmio_size);
 
-   memcpy(gvt->firmware.mmio, p, info->mmio_size);
+   memcpy(p, gvt->firmware.mmio, info->mmio_size);
 
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);
-- 
2.25.1



[Intel-gfx] [PATCH v6 1/3] i915/gvt: Introduce the mmio table to support VFIO new mdev API

2022-02-08 Thread Zhi Wang
From: Zhi Wang 

To support the new mdev interfaces and the re-factor patches from
Christoph, which moves the GVT-g code into a dedicated module, the GVT-g
initialization path has to be separated into two phases:

a) Early initialization.

The early initialization of GVT requires to be done when loading i915.
Mostly it's because the initial clean HW state needs to be saved before
i915 touches the HW.

b) Late initalization.

This phases of initalization will setup the rest components of GVT-g,
which can be done later when the dedicated module is being loaded.

v6:

- Move the mmio_table.c into i915. (Christoph)
- Keep init_device_info and related structures in GVT-g. (Christoph)
- Refine the callbacks of the iterator. (Christoph)
- Move the flags of MMIO register defination to GVT-g. (Chrsitoph)
- Move the mmio block handling to GVT-g.

v5:

- Re-design the mmio table framework. (Christoph)

v4:

- Fix the errors of patch checking scripts.

v3:

- Fix the errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

v2:

- Implement a mmio table instead of generating it by marco in i915. (Jani)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Tested-by: Terrence Xu 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/Makefile   |2 +-
 drivers/gpu/drm/i915/gvt/cmd_parser.c   |2 +-
 drivers/gpu/drm/i915/gvt/gvt.h  |3 +-
 drivers/gpu/drm/i915/gvt/handlers.c | 1062 ++-
 drivers/gpu/drm/i915/gvt/mmio.h |   17 -
 drivers/gpu/drm/i915/gvt/reg.h  |9 +-
 drivers/gpu/drm/i915/intel_gvt.c|   20 +-
 drivers/gpu/drm/i915/intel_gvt.h|   37 +
 drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 1308 +++
 9 files changed, 1501 insertions(+), 959 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_gvt_mmio_table.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index a26e6736bebb..fc882e299d65 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -318,7 +318,7 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \
 i915-y += i915_vgpu.o
 
 ifeq ($(CONFIG_DRM_I915_GVT),y)
-i915-y += intel_gvt.o
+i915-y += intel_gvt.o intel_gvt_mmio_table.o
 include $(src)/gvt/Makefile
 endif
 
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c 
b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index ec18122cc216..e9b5c70bb004 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -3205,7 +3205,7 @@ int intel_gvt_scan_engine_context(struct 
intel_vgpu_workload *workload)
 
 static int init_cmd_table(struct intel_gvt *gvt)
 {
-   unsigned int gen_type = intel_gvt_get_device_type(gvt);
+   unsigned int gen_type = intel_gvt_get_device_type(gvt->gt->i915);
int i;
 
for (i = 0; i < ARRAY_SIZE(cmd_info); i++) {
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 0ebffc327528..bfe07c69cfd2 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -36,6 +36,7 @@
 #include 
 
 #include "i915_drv.h"
+#include "intel_gvt.h"
 
 #include "debug.h"
 #include "hypercall.h"
@@ -272,7 +273,7 @@ struct intel_gvt_mmio {
 /* Value of command write of this reg needs to be patched */
 #define F_CMD_WRITE_PATCH  (1 << 8)
 
-   const struct gvt_mmio_block *mmio_block;
+   struct gvt_mmio_block *mmio_block;
unsigned int num_mmio_block;
 
DECLARE_HASHTABLE(mmio_info_table, INTEL_GVT_MMIO_HASH_BITS);
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index 9f8ae6776e98..f4d997bae0fc 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -42,35 +42,10 @@
 #include "display/intel_display_types.h"
 #include "display/intel_fbc.h"
 
-/* XXX FIXME i915 has changed PP_XXX definition */
-#define PCH_PP_STATUS  _MMIO(0xc7200)
-#define PCH_PP_CONTROL _MMIO(0xc7204)
-#define PCH_PP_ON_DELAYS _MMIO(0xc7208)
-#define PCH_PP_OFF_DELAYS _MMIO(0xc720c)
-#define PCH_PP_DIVISOR _MMIO(0xc7210)
-
-unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt)
-{
-   struct drm_i915_private *i915 = gvt->gt->i915;
-
-   if (IS_BROADWELL(i915))
-   return D_BDW;
-   else if (IS_SKYLAKE(i915))
-   return D_SKL;
-   else if (IS_KABYLAKE(i915))
-   return D_KBL;
-   else if (IS_BROXTON(i915))
-   return D_BXT;
-   else if (IS_COFFEELAKE(i915) || IS_COMETLAKE(i915))
-   return D_CFL;
-
-   return 0;
-}
-
 bool intel_gvt_match_device(struct intel_gvt *gvt,
unsigned long device)
 {
-   return intel_gvt_get_device_type(gvt) & device;
+   return intel_gvt_get_device_type(gvt->gt->i915) & device;
 }
 
 static void read_vr

[Intel-gfx] [PATCH v6 2/3] i915/gvt: Save the initial HW state snapshot in i915

2022-02-08 Thread Zhi Wang
Save the initial HW state snapshot in i915 so that the rest code of GVT-g
can be moved into a dedicated module while it can still get a clean
initial HW state saved at the correct time during the initialization of
i915. The futhrer vGPU created by GVT-g will use this HW state as the
initial HW state.

v6:

- Remove the reference of intel_gvt_device_info.(Christoph)
- Refine the save_mmio() function. (Christoph)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/i915_drv.h  |  2 +
 drivers/gpu/drm/i915/intel_gvt.c | 92 +++-
 2 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 44c1f98144b4..2a230840cdfa 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -606,6 +606,8 @@ struct i915_virtual_gpu {
struct mutex lock; /* serialises sending of g2v_notify command pkts */
bool active;
u32 caps;
+   u32 *initial_mmio;
+   u8 *initial_cfg_space;
 };
 
 struct i915_selftest_stash {
diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c
index 32aa6f111d6b..c5019173ac44 100644
--- a/drivers/gpu/drm/i915/intel_gvt.c
+++ b/drivers/gpu/drm/i915/intel_gvt.c
@@ -68,6 +68,85 @@ void intel_gvt_sanitize_options(struct drm_i915_private 
*dev_priv)
dev_priv->params.enable_gvt = 0;
 }
 
+static void free_initial_hw_state(struct drm_i915_private *dev_priv)
+{
+   struct i915_virtual_gpu *vgpu = _priv->vgpu;
+
+   vfree(vgpu->initial_mmio);
+   vgpu->initial_mmio = NULL;
+
+   kfree(vgpu->initial_cfg_space);
+   vgpu->initial_cfg_space = NULL;
+}
+
+static void save_mmio(struct intel_gvt_mmio_table_iter *iter, u32 offset,
+ u32 size)
+{
+   struct drm_i915_private *dev_priv = iter->i915;
+   u32 *mmio, i;
+
+   for (i = offset; i < offset + size; i += 4) {
+   mmio = iter->data + i;
+   *mmio = intel_uncore_read_notrace(to_gt(dev_priv)->uncore,
+ _MMIO(i));
+   }
+}
+
+static int handle_mmio(struct intel_gvt_mmio_table_iter *iter,
+  u32 offset, u32 device, u32 size)
+{
+   if (WARN_ON(!IS_ALIGNED(offset, 4)))
+   return -EINVAL;
+
+   save_mmio(iter, offset, size);
+   return 0;
+}
+
+static int save_initial_hw_state(struct drm_i915_private *dev_priv)
+{
+   struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+   struct i915_virtual_gpu *vgpu = _priv->vgpu;
+   struct intel_gvt_mmio_table_iter iter;
+   void *mem;
+   int i, ret;
+
+   mem = kzalloc(PCI_CFG_SPACE_EXP_SIZE, GFP_KERNEL);
+   if (!mem)
+   return -ENOMEM;
+
+   vgpu->initial_cfg_space = mem;
+
+   for (i = 0; i < PCI_CFG_SPACE_EXP_SIZE; i += 4)
+   pci_read_config_dword(pdev, i, mem + i);
+
+   mem = vzalloc(2 * SZ_1M);
+   if (!mem) {
+   ret = -ENOMEM;
+   goto err_mmio;
+   }
+
+   vgpu->initial_mmio = mem;
+
+   iter.i915 = dev_priv;
+   iter.data = vgpu->initial_mmio;
+   iter.handle_mmio_cb = handle_mmio;
+
+   ret = intel_gvt_iterate_mmio_table();
+   if (ret)
+   goto err_iterate;
+
+   return 0;
+
+err_iterate:
+   vfree(vgpu->initial_mmio);
+   vgpu->initial_mmio = NULL;
+err_mmio:
+   kfree(vgpu->initial_cfg_space);
+   vgpu->initial_cfg_space = NULL;
+
+   return ret;
+}
+
 /**
  * intel_gvt_init - initialize GVT components
  * @dev_priv: drm i915 private data
@@ -97,15 +176,23 @@ int intel_gvt_init(struct drm_i915_private *dev_priv)
return -EIO;
}
 
+   ret = save_initial_hw_state(dev_priv);
+   if (ret) {
+   drm_dbg(_priv->drm, "Fail to save initial HW state\n");
+   goto err_save_hw_state;
+   }
+
ret = intel_gvt_init_device(dev_priv);
if (ret) {
drm_dbg(_priv->drm, "Fail to init GVT device\n");
-   goto bail;
+   goto err_init_device;
}
 
return 0;
 
-bail:
+err_init_device:
+   free_initial_hw_state(dev_priv);
+err_save_hw_state:
dev_priv->params.enable_gvt = 0;
return 0;
 }
@@ -129,6 +216,7 @@ void intel_gvt_driver_remove(struct drm_i915_private 
*dev_priv)
return;
 
intel_gvt_clean_device(dev_priv);
+   free_initial_hw_state(dev_priv);
 }
 
 /**
-- 
2.25.1



Re: [Intel-gfx] [PATCH 1/3] i915/gvt: Introduce the mmio_table.c to support VFIO new mdev API

2022-02-07 Thread Zhi Wang

On 2/7/22 05:48, Jani Nikula wrote:


On Mon, 07 Feb 2022, Christoph Hellwig  wrote:

On Mon, Feb 07, 2022 at 08:28:13AM +, Wang, Zhi A wrote:

1) About having the mmio_table.h, I would like to keep the stuff in a
dedicated header as putting them in intel_gvt.h might needs i915 guys
to maintain it.
2) The other one is about if we should move the mmio_table.c into
i915 folder. I guess we need the some comments from Jani. In the
current version that I am testing, it's still in GVT folder. Guess we
can submit a patch to move it to i915 folder later if Jani is ok
about that.

Yes, let's have Jani chime in on these.  They're basically one and the
same issue.  This code will have to be built into into the core i915
driver even with my planned split, which is kindof the point of this
exercise.  I think it makes sense to use the subdirectories as boundaries
for where the code ends up and not to declarare maintainership boundaries,
but it will be up to the i915 and gvt maintainers to decide that.

Agreed. If there's going to be a gvt.ko, I think all of gvt/ should be
part of that module, nothing more, nothing less.

The gvt related files in i915/ should probably be named intel_gvt* or
something, ditto for function naming, and we'll probably want patches
touching them be Cc'd to intel-gfx list.

Joonas, Rodrigo, Tvrtko, thoughts?

BR,
Jani.


Hi Christoph and Jani:

Thanks for the comments. It would be nice that people can achieve a 
agreement. I am OK with both of the options and also moving some files 
into different folders doesn't needs me to do the full test run again. :)



Thanks,

Zhi.



[Intel-gfx] [PATCH 3/3] i915/gvt: Use the initial HW state snapshot saved in i915

2022-01-27 Thread Zhi Wang
The code of saving initial HW state snapshot has been moved into i915.
Let the GVT-g core logic use that snapshot.

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/firmware.c | 25 +
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/firmware.c 
b/drivers/gpu/drm/i915/gvt/firmware.c
index 1a8274a3f4b1..1d55920bfd42 100644
--- a/drivers/gpu/drm/i915/gvt/firmware.c
+++ b/drivers/gpu/drm/i915/gvt/firmware.c
@@ -66,22 +66,16 @@ static struct bin_attribute firmware_attr = {
.mmap = NULL,
 };
 
-static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data)
-{
-   *(u32 *)(data + offset) = intel_uncore_read_notrace(gvt->gt->uncore,
-   _MMIO(offset));
-   return 0;
-}
-
 static int expose_firmware_sysfs(struct intel_gvt *gvt)
 {
struct intel_gvt_device_info *info = >device_info;
-   struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
+   struct drm_i915_private *i915 = gvt->gt->i915;
+   struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
struct gvt_firmware_header *h;
void *firmware;
void *p;
unsigned long size, crc32_start;
-   int i, ret;
+   int ret;
 
size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
firmware = vzalloc(size);
@@ -99,17 +93,16 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
 
p = firmware + h->cfg_space_offset;
 
-   for (i = 0; i < h->cfg_space_size; i += 4)
-   pci_read_config_dword(pdev, i, p + i);
-
-   memcpy(gvt->firmware.cfg_space, p, info->cfg_space_size);
+   memcpy(gvt->firmware.cfg_space, i915->vgpu.initial_cfg_space,
+   info->cfg_space_size);
+   memcpy(p, gvt->firmware.cfg_space, info->cfg_space_size);
 
p = firmware + h->mmio_offset;
 
-   /* Take a snapshot of hw mmio registers. */
-   intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, p);
+   memcpy(gvt->firmware.mmio, i915->vgpu.initial_mmio,
+   info->mmio_size);
 
-   memcpy(gvt->firmware.mmio, p, info->mmio_size);
+   memcpy(p, gvt->firmware.mmio, info->mmio_size);
 
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);
-- 
2.25.1



[Intel-gfx] [PATCH 2/3] i915/gvt: save the initial HW state snapshot in i915.

2022-01-27 Thread Zhi Wang
Save the inital HW state snapshot in i915 so that the rest code of GVT-g
can be moved into a dedicated module while it can still get a clean
initial HW state saved at the correct time during the initialization of
i915. The futhrer vGPU created by GVT-g will use this HW state as the
initial HW state.

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/i915_drv.h  |   2 +
 drivers/gpu/drm/i915/intel_gvt.c | 110 ++-
 2 files changed, 110 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 44c1f98144b4..2a230840cdfa 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -606,6 +606,8 @@ struct i915_virtual_gpu {
struct mutex lock; /* serialises sending of g2v_notify command pkts */
bool active;
u32 caps;
+   u32 *initial_mmio;
+   u8 *initial_cfg_space;
 };
 
 struct i915_selftest_stash {
diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c
index cf6e98962d82..a3d8bdb24d3f 100644
--- a/drivers/gpu/drm/i915/intel_gvt.c
+++ b/drivers/gpu/drm/i915/intel_gvt.c
@@ -86,6 +86,103 @@ void intel_gvt_sanitize_options(struct drm_i915_private 
*dev_priv)
dev_priv->params.enable_gvt = 0;
 }
 
+static void free_initial_hw_state(struct drm_i915_private *dev_priv)
+{
+   struct i915_virtual_gpu *vgpu = _priv->vgpu;
+
+   vfree(vgpu->initial_mmio);
+   vgpu->initial_mmio = NULL;
+
+   kfree(vgpu->initial_cfg_space);
+   vgpu->initial_cfg_space = NULL;
+}
+
+static void save_mmio(struct intel_gvt_mmio_table_iter *iter, u32 offset,
+ u32 size)
+{
+   struct drm_i915_private *dev_priv = iter->i915;
+   void *mmio = iter->data;
+   u32 start, end, i;
+
+   start = offset;
+   end = offset + size;
+
+   for (i = start; i < end; i += 4) {
+   *(u32 *)(mmio + i) = intel_uncore_read_notrace(
+   to_gt(dev_priv)->uncore, _MMIO(offset));
+   }
+}
+
+static int do_mmio(u32 offset, u16 flags, u32 size, u32 addr_mask,
+  u32 ro_mask, u32 device,
+  struct intel_gvt_mmio_table_iter *iter)
+{
+   if (WARN_ON(!IS_ALIGNED(offset, 4)))
+   return -EINVAL;
+
+   save_mmio(iter, offset, size);
+   return 0;
+}
+
+static int do_mmio_block(u32 offset, u32 size, u32 device,
+struct intel_gvt_mmio_table_iter *iter)
+{
+   if (WARN_ON(!IS_ALIGNED(offset, 4)))
+   return -EINVAL;
+
+   save_mmio(iter, offset, size);
+   return 0;
+}
+
+static int save_inital_hw_state(struct drm_i915_private *dev_priv)
+{
+   struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+   struct intel_gvt_device_info info;
+   struct i915_virtual_gpu *vgpu = _priv->vgpu;
+   struct intel_gvt_mmio_table_iter iter;
+   void *mem;
+   int i, ret;
+
+   intel_gvt_init_device_info(dev_priv, );
+
+   mem = kzalloc(info.cfg_space_size, GFP_KERNEL);
+   if (!mem)
+   return -ENOMEM;
+
+   vgpu->initial_cfg_space = mem;
+
+   for (i = 0; i < PCI_CFG_SPACE_EXP_SIZE; i += 4)
+   pci_read_config_dword(pdev, i, mem + i);
+
+   mem = vzalloc(info.mmio_size);
+   if (!mem) {
+   ret = -ENOMEM;
+   goto err_mmio;
+   }
+
+   vgpu->initial_mmio = mem;
+
+   iter.i915 = dev_priv;
+   iter.data = vgpu->initial_mmio;
+   iter.do_mmio = do_mmio;
+   iter.do_mmio_block = do_mmio_block;
+
+   ret = intel_gvt_iterate_mmio_table();
+   if (ret)
+   goto err_iterate;
+
+   return 0;
+
+err_iterate:
+   vfree(vgpu->initial_mmio);
+   vgpu->initial_mmio = NULL;
+err_mmio:
+   kfree(vgpu->initial_cfg_space);
+   vgpu->initial_cfg_space = NULL;
+
+   return ret;
+}
+
 /**
  * intel_gvt_init - initialize GVT components
  * @dev_priv: drm i915 private data
@@ -115,15 +212,23 @@ int intel_gvt_init(struct drm_i915_private *dev_priv)
return -EIO;
}
 
+   ret = save_inital_hw_state(dev_priv);
+   if (ret) {
+   drm_dbg(_priv->drm, "Fail to save inital HW state\n");
+   goto err_save_hw_state;
+   }
+
ret = intel_gvt_init_device(dev_priv);
if (ret) {
drm_dbg(_priv->drm, "Fail to init GVT device\n");
-   goto bail;
+   goto err_init_device;
}
 
return 0;
 
-bail:
+err_init_device:
+   free_initial_hw_state(dev_priv);
+err_save_hw_state:
dev_priv->params.enable_gvt = 0;
return 0;
 }
@@ -147,6 +252,7 @@ void intel_gvt_driver_remove(struct drm_i915_private 
*dev_priv)
r

[Intel-gfx] [PATCH 1/3] i915/gvt: Introduce the mmio_table.c to support VFIO new mdev API

2022-01-27 Thread Zhi Wang
From: Zhi Wang 

To support the new mdev interfaces and the re-factor patches from
Christoph, which moves the GVT-g code into a dedicated module, the GVT-g
initialization path has to be separated into two phases:

a) Early initialization.

The early initialization of GVT requires to be done when loading i915.
Mostly it's because the initial clean HW state needs to be saved before
i915 touches the HW.

b) Late initalization.

This phases of initalization will setup the rest components of GVT-g,
which can be done later when the dedicated module is being loaded.

v5:

- Re-design the mmio table framework. (Chirstoph)

v4:

- Fix the errors of patch checking scripts.

v3:

- Fix the errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

v2:

- Implement a mmio table instead of generating it by marco in i915. (Jani)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Tested-by: Terrence Xu 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/Makefile |2 +-
 drivers/gpu/drm/i915/gvt/cmd_parser.c |2 +-
 drivers/gpu/drm/i915/gvt/gvt.c|   19 +-
 drivers/gpu/drm/i915/gvt/gvt.h|   21 +-
 drivers/gpu/drm/i915/gvt/handlers.c   | 1878 +
 drivers/gpu/drm/i915/gvt/mmio.h   |2 -
 drivers/gpu/drm/i915/gvt/mmio_table.c | 1386 ++
 drivers/gpu/drm/i915/gvt/mmio_table.h |   58 +
 drivers/gpu/drm/i915/gvt/reg.h|9 +-
 9 files changed, 1796 insertions(+), 1581 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/mmio_table.c
 create mode 100644 drivers/gpu/drm/i915/gvt/mmio_table.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index a26e6736bebb..029e5f5e0955 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -318,7 +318,7 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \
 i915-y += i915_vgpu.o
 
 ifeq ($(CONFIG_DRM_I915_GVT),y)
-i915-y += intel_gvt.o
+i915-y += intel_gvt.o gvt/mmio_table.o
 include $(src)/gvt/Makefile
 endif
 
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c 
b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index ec18122cc216..e9b5c70bb004 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -3205,7 +3205,7 @@ int intel_gvt_scan_engine_context(struct 
intel_vgpu_workload *workload)
 
 static int init_cmd_table(struct intel_gvt *gvt)
 {
-   unsigned int gen_type = intel_gvt_get_device_type(gvt);
+   unsigned int gen_type = intel_gvt_get_device_type(gvt->gt->i915);
int i;
 
for (i = 0; i < ARRAY_SIZE(cmd_info); i++) {
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index f0b69e4dcb52..a0243e863613 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -63,23 +63,6 @@ static const struct intel_gvt_ops intel_gvt_ops = {
.emulate_hotplug = intel_vgpu_emulate_hotplug,
 };
 
-static void init_device_info(struct intel_gvt *gvt)
-{
-   struct intel_gvt_device_info *info = >device_info;
-   struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
-
-   info->max_support_vgpus = 8;
-   info->cfg_space_size = PCI_CFG_SPACE_EXP_SIZE;
-   info->mmio_size = 2 * 1024 * 1024;
-   info->mmio_bar = 0;
-   info->gtt_start_offset = 8 * 1024 * 1024;
-   info->gtt_entry_size = 8;
-   info->gtt_entry_size_shift = 3;
-   info->gmadr_bytes_in_cmd = 8;
-   info->max_surface_size = 36 * 1024 * 1024;
-   info->msi_cap_offset = pdev->msi_cap;
-}
-
 static void intel_gvt_test_and_emulate_vblank(struct intel_gvt *gvt)
 {
struct intel_vgpu *vgpu;
@@ -208,7 +191,7 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
gvt->gt = to_gt(i915);
i915->gvt = gvt;
 
-   init_device_info(gvt);
+   intel_gvt_init_device_info(i915, >device_info);
 
ret = intel_gvt_setup_mmio_info(gvt);
if (ret)
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 0ebffc327528..e4513e2ce469 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -40,6 +40,7 @@
 #include "debug.h"
 #include "hypercall.h"
 #include "mmio.h"
+#include "mmio_table.h"
 #include "reg.h"
 #include "interrupt.h"
 #include "gtt.h"
@@ -65,20 +66,6 @@ struct intel_gvt_host {
 
 extern struct intel_gvt_host intel_gvt_host;
 
-/* Describe per-platform limitations. */
-struct intel_gvt_device_info {
-   u32 max_support_vgpus;
-   u32 cfg_space_size;
-   u32 mmio_size;
-   u32 mmio_bar;
-   unsigned long msi_cap_offset;
-   u32 gtt_start_offset;
-   u32 gtt_entry_size;
-   u32 gtt_entry_size_shift;
-   int gmadr_bytes_in_cmd;
-   u32 max_surface_size;
-};
-
 /* GM resources owned by a vGPU */
 struct intel_vgpu_gm {
   

[Intel-gfx] [GVT PULL] gvt-fixes for drm-intel-fixes

2022-01-15 Thread Zhi Wang
Hi folks:

Here is the gvt-fixes pull for drm-intel-fixes. It contains:

- Make DRM_I915_GVT depend on X86 (Siva Mullati)
- Clean kernel doc in gtt.c (Randy Dunlap)

This pull has been tested by: dim apply-pull drm-intel-fixes < this_email.eml

Zhi.

The following changes since commit d46f329a3f6048e04736e86cb13c880645048792:

  drm/i915: Increment composite fence seqno (2021-12-27 11:33:40 +0200)

are available in the Git repository at:

  https://github.com/intel/gvt-linux.git tags/gvt-fixes-2022-01-13

for you to fetch changes up to d72d69abfdb6e0375981cfdda8eb45143f12c77d:

  drm/i915/gvt: Make DRM_I915_GVT depend on X86 (2022-01-13 18:13:12 +)


gvt-fixes-2022-01-13

- Make DRM_I915_GVT depend on X86 (Siva Mullati)
- Clean kernel doc in gtt.c (Randy Dunlap)


Randy Dunlap (1):
  drm/i915/gvt: clean up kernel-doc in gtt.c

Siva Mullati (1):
  drm/i915/gvt: Make DRM_I915_GVT depend on X86

 drivers/gpu/drm/i915/Kconfig   | 1 +
 drivers/gpu/drm/i915/gvt/gtt.c | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)


[Intel-gfx] [PATCH v4 1/2] i915/gvt: Introduce the mmio_info_table.c to support VFIO new mdev API

2021-11-29 Thread Zhi Wang
From: Zhi Wang 

To support the new mdev interfaces and the re-factor patches from
Christoph, which moves the GVT-g code into a dedicated module, the GVT-g
initialization path has to be separated into two phases:

a) Early initialization.

The early initialization of GVT requires to be done when loading i915.
Mostly it's because the initial clean HW state needs to be saved before
i915 touches the HW.

b) Late initalization.

This phases of initalization will setup the rest components of GVT-g,
which can be done later when the dedicated module is being loaded.

v4:

- Fix the errors of patch checking scripts.

v3:

- Fix the errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

v2:

- Implement a mmio table instead of generating it by marco in i915. (Jani)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Tested-by: Terrence Xu 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/Makefile  |2 +-
 drivers/gpu/drm/i915/gvt/gvt.c |   38 +-
 drivers/gpu/drm/i915/gvt/gvt.h |1 +
 drivers/gpu/drm/i915/gvt/handlers.c| 1780 +++-
 drivers/gpu/drm/i915/gvt/mmio.h|5 +-
 drivers/gpu/drm/i915/gvt/mmio_info_table.c | 1461 
 drivers/gpu/drm/i915/gvt/mmio_info_table.h |   37 +
 drivers/gpu/drm/i915/gvt/reg.h |9 +-
 drivers/gpu/drm/i915/intel_gvt.c   |   42 +-
 9 files changed, 1777 insertions(+), 1598 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/mmio_info_table.c
 create mode 100644 drivers/gpu/drm/i915/gvt/mmio_info_table.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index cdc244bbbfc1..55603aebe3e4 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -309,7 +309,7 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \
 i915-y += i915_vgpu.o
 
 ifeq ($(CONFIG_DRM_I915_GVT),y)
-i915-y += intel_gvt.o
+i915-y += intel_gvt.o gvt/mmio_info_table.o
 include $(src)/gvt/Makefile
 endif
 
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index cbac409f6c8a..c7580db355c0 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -63,23 +63,6 @@ static const struct intel_gvt_ops intel_gvt_ops = {
.emulate_hotplug = intel_vgpu_emulate_hotplug,
 };
 
-static void init_device_info(struct intel_gvt *gvt)
-{
-   struct intel_gvt_device_info *info = >device_info;
-   struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
-
-   info->max_support_vgpus = 8;
-   info->cfg_space_size = PCI_CFG_SPACE_EXP_SIZE;
-   info->mmio_size = 2 * 1024 * 1024;
-   info->mmio_bar = 0;
-   info->gtt_start_offset = 8 * 1024 * 1024;
-   info->gtt_entry_size = 8;
-   info->gtt_entry_size_shift = 3;
-   info->gmadr_bytes_in_cmd = 8;
-   info->max_surface_size = 36 * 1024 * 1024;
-   info->msi_cap_offset = pdev->msi_cap;
-}
-
 static void intel_gvt_test_and_emulate_vblank(struct intel_gvt *gvt)
 {
struct intel_vgpu *vgpu;
@@ -169,7 +152,6 @@ void intel_gvt_clean_device(struct drm_i915_private *i915)
intel_gvt_clean_workload_scheduler(gvt);
intel_gvt_clean_gtt(gvt);
intel_gvt_free_firmware(gvt);
-   intel_gvt_clean_mmio_info(gvt);
idr_destroy(>vgpu_idr);
 
kfree(i915->gvt);
@@ -188,16 +170,12 @@ void intel_gvt_clean_device(struct drm_i915_private *i915)
  */
 int intel_gvt_init_device(struct drm_i915_private *i915)
 {
-   struct intel_gvt *gvt;
+   struct intel_gvt *gvt = i915->gvt;
struct intel_vgpu *vgpu;
int ret;
 
-   if (drm_WARN_ON(>drm, i915->gvt))
-   return -EEXIST;
-
-   gvt = kzalloc(sizeof(struct intel_gvt), GFP_KERNEL);
-   if (!gvt)
-   return -ENOMEM;
+   if (drm_WARN_ON(>drm, !i915->gvt))
+   return -ENODEV;
 
gvt_dbg_core("init gvt device\n");
 
@@ -205,12 +183,8 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
spin_lock_init(>scheduler.mmio_context_lock);
mutex_init(>lock);
mutex_init(>sched_lock);
-   gvt->gt = >gt;
-   i915->gvt = gvt;
-
-   init_device_info(gvt);
 
-   ret = intel_gvt_setup_mmio_info(gvt);
+   ret = intel_gvt_setup_mmio_handlers(gvt);
if (ret)
goto out_clean_idr;
 
@@ -218,7 +192,7 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
 
ret = intel_gvt_load_firmware(gvt);
if (ret)
-   goto out_clean_mmio_info;
+   goto out_clean_idr;
 
ret = intel_gvt_init_irq(gvt);
if (ret)
@@ -277,8 +251,6 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
intel_gvt_clean_gtt(gvt);
 out_free_firmware:
intel_gvt_free_firmware(gvt);
-out_clean_mmio_info:
-   intel_gvt_clean_

[Intel-gfx] [PATCH v4 2/2] i915/gvt: save the MMIO snapshot in the early init of GVT-g

2021-11-29 Thread Zhi Wang
From: Zhi Wang 

To support the early init of GVT-g, which will be put in i915, after the
GVT-g is moved into a dedicated module, we need to save the MMIO snapshot
in the early init of GVT-g, when the HW hasn't been touched.

v3:

- Fix errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Tested-by: Terrence Xu 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/firmware.c| 40 +---
 drivers/gpu/drm/i915/gvt/handlers.c| 39 
 drivers/gpu/drm/i915/gvt/mmio_info_table.c | 72 +-
 drivers/gpu/drm/i915/gvt/mmio_info_table.h |  3 +
 4 files changed, 77 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/firmware.c 
b/drivers/gpu/drm/i915/gvt/firmware.c
index 1a8274a3f4b1..28719c2f253f 100644
--- a/drivers/gpu/drm/i915/gvt/firmware.c
+++ b/drivers/gpu/drm/i915/gvt/firmware.c
@@ -66,12 +66,6 @@ static struct bin_attribute firmware_attr = {
.mmap = NULL,
 };
 
-static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data)
-{
-   *(u32 *)(data + offset) = intel_uncore_read_notrace(gvt->gt->uncore,
-   _MMIO(offset));
-   return 0;
-}
 
 static int expose_firmware_sysfs(struct intel_gvt *gvt)
 {
@@ -81,7 +75,7 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
void *firmware;
void *p;
unsigned long size, crc32_start;
-   int i, ret;
+   int ret;
 
size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
firmware = vzalloc(size);
@@ -99,17 +93,11 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
 
p = firmware + h->cfg_space_offset;
 
-   for (i = 0; i < h->cfg_space_size; i += 4)
-   pci_read_config_dword(pdev, i, p + i);
-
-   memcpy(gvt->firmware.cfg_space, p, info->cfg_space_size);
+   memcpy(p, gvt->firmware.cfg_space, info->cfg_space_size);
 
p = firmware + h->mmio_offset;
 
-   /* Take a snapshot of hw mmio registers. */
-   intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, p);
-
-   memcpy(gvt->firmware.mmio, p, info->mmio_size);
+   memcpy(p, gvt->firmware.mmio, info->mmio_size);
 
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);
@@ -142,9 +130,6 @@ void intel_gvt_free_firmware(struct intel_gvt *gvt)
 {
if (!gvt->firmware.firmware_loaded)
clean_firmware_sysfs(gvt);
-
-   kfree(gvt->firmware.cfg_space);
-   vfree(gvt->firmware.mmio);
 }
 
 static int verify_firmware(struct intel_gvt *gvt,
@@ -204,36 +189,17 @@ static int verify_firmware(struct intel_gvt *gvt,
  */
 int intel_gvt_load_firmware(struct intel_gvt *gvt)
 {
-   struct intel_gvt_device_info *info = >device_info;
struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
struct intel_gvt_firmware *firmware = >firmware;
struct gvt_firmware_header *h;
const struct firmware *fw;
char *path;
-   void *mem;
int ret;
 
path = kmalloc(PATH_MAX, GFP_KERNEL);
if (!path)
return -ENOMEM;
 
-   mem = kmalloc(info->cfg_space_size, GFP_KERNEL);
-   if (!mem) {
-   kfree(path);
-   return -ENOMEM;
-   }
-
-   firmware->cfg_space = mem;
-
-   mem = vmalloc(info->mmio_size);
-   if (!mem) {
-   kfree(path);
-   kfree(firmware->cfg_space);
-   return -ENOMEM;
-   }
-
-   firmware->mmio = mem;
-
sprintf(path, "%s/vid_0x%04x_did_0x%04x_rid_0x%02x.golden_hw_state",
 GVT_FIRMWARE_PATH, pdev->vendor, pdev->device,
 pdev->revision);
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index 2c064da3db6d..ba7b330a2c71 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -2406,45 +2406,6 @@ int intel_gvt_setup_mmio_handlers(struct intel_gvt *gvt)
return ret;
 }
 
-/**
- * intel_gvt_for_each_tracked_mmio - iterate each tracked mmio
- * @gvt: a GVT device
- * @handler: the handler
- * @data: private data given to handler
- *
- * Returns:
- * Zero on success, negative error code if failed.
- */
-int intel_gvt_for_each_tracked_mmio(struct intel_gvt *gvt,
-   int (*handler)(struct intel_gvt *gvt, u32 offset, void *data),
-   void *data)
-{
-   struct gvt_mmio_block *block = gvt->mmio.mmio_block;
-   struct intel_gvt_mmio_info *e;
-   int i, j, ret;
-
-   hash_for_each(gvt->mmio.mmio_info_table, i, e, node) {
-   ret = handler(gvt, e->offset, data);
-  

[Intel-gfx] [PATCH v3 1/2] i915/gvt: Introduce the mmio_info_table.c to support VFIO new mdev API

2021-11-26 Thread Zhi Wang
From: Zhi Wang 

To support the new mdev interfaces and the re-factor patches from
Christoph, which moves the GVT-g code into a dedicated module, the GVT-g
initialization path has to be seperated into two phases:

a) Early initialization.

The early initialization of GVT requires to be done when loading i915.
Mostly it's because the inital clean HW state needs to be saved before
i915 touches the HW.

b) Late initalization.

This phases of initalization will setup the rest components of GVT-g,
which can be done later when the dedicated module is being loaded.

v3:

- Fix the errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

v2:

- Implement a mmio table instead of generating it by marco in i915. (Jani)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Tested-by: Terrence Xu 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/Makefile  |2 +-
 drivers/gpu/drm/i915/gvt/gvt.c |   38 +-
 drivers/gpu/drm/i915/gvt/gvt.h |1 +
 drivers/gpu/drm/i915/gvt/handlers.c| 1780 +++-
 drivers/gpu/drm/i915/gvt/mmio.h|5 +-
 drivers/gpu/drm/i915/gvt/mmio_info_table.c | 1461 
 drivers/gpu/drm/i915/gvt/mmio_info_table.h |   37 +
 drivers/gpu/drm/i915/gvt/reg.h |9 +-
 drivers/gpu/drm/i915/intel_gvt.c   |   42 +-
 9 files changed, 1777 insertions(+), 1598 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/mmio_info_table.c
 create mode 100644 drivers/gpu/drm/i915/gvt/mmio_info_table.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index cdc244bbbfc1..55603aebe3e4 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -309,7 +309,7 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \
 i915-y += i915_vgpu.o
 
 ifeq ($(CONFIG_DRM_I915_GVT),y)
-i915-y += intel_gvt.o
+i915-y += intel_gvt.o gvt/mmio_info_table.o
 include $(src)/gvt/Makefile
 endif
 
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index cbac409f6c8a..c7580db355c0 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -63,23 +63,6 @@ static const struct intel_gvt_ops intel_gvt_ops = {
.emulate_hotplug = intel_vgpu_emulate_hotplug,
 };
 
-static void init_device_info(struct intel_gvt *gvt)
-{
-   struct intel_gvt_device_info *info = >device_info;
-   struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
-
-   info->max_support_vgpus = 8;
-   info->cfg_space_size = PCI_CFG_SPACE_EXP_SIZE;
-   info->mmio_size = 2 * 1024 * 1024;
-   info->mmio_bar = 0;
-   info->gtt_start_offset = 8 * 1024 * 1024;
-   info->gtt_entry_size = 8;
-   info->gtt_entry_size_shift = 3;
-   info->gmadr_bytes_in_cmd = 8;
-   info->max_surface_size = 36 * 1024 * 1024;
-   info->msi_cap_offset = pdev->msi_cap;
-}
-
 static void intel_gvt_test_and_emulate_vblank(struct intel_gvt *gvt)
 {
struct intel_vgpu *vgpu;
@@ -169,7 +152,6 @@ void intel_gvt_clean_device(struct drm_i915_private *i915)
intel_gvt_clean_workload_scheduler(gvt);
intel_gvt_clean_gtt(gvt);
intel_gvt_free_firmware(gvt);
-   intel_gvt_clean_mmio_info(gvt);
idr_destroy(>vgpu_idr);
 
kfree(i915->gvt);
@@ -188,16 +170,12 @@ void intel_gvt_clean_device(struct drm_i915_private *i915)
  */
 int intel_gvt_init_device(struct drm_i915_private *i915)
 {
-   struct intel_gvt *gvt;
+   struct intel_gvt *gvt = i915->gvt;
struct intel_vgpu *vgpu;
int ret;
 
-   if (drm_WARN_ON(>drm, i915->gvt))
-   return -EEXIST;
-
-   gvt = kzalloc(sizeof(struct intel_gvt), GFP_KERNEL);
-   if (!gvt)
-   return -ENOMEM;
+   if (drm_WARN_ON(>drm, !i915->gvt))
+   return -ENODEV;
 
gvt_dbg_core("init gvt device\n");
 
@@ -205,12 +183,8 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
spin_lock_init(>scheduler.mmio_context_lock);
mutex_init(>lock);
mutex_init(>sched_lock);
-   gvt->gt = >gt;
-   i915->gvt = gvt;
-
-   init_device_info(gvt);
 
-   ret = intel_gvt_setup_mmio_info(gvt);
+   ret = intel_gvt_setup_mmio_handlers(gvt);
if (ret)
goto out_clean_idr;
 
@@ -218,7 +192,7 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
 
ret = intel_gvt_load_firmware(gvt);
if (ret)
-   goto out_clean_mmio_info;
+   goto out_clean_idr;
 
ret = intel_gvt_init_irq(gvt);
if (ret)
@@ -277,8 +251,6 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
intel_gvt_clean_gtt(gvt);
 out_free_firmware:
intel_gvt_free_firmware(gvt);
-out_clean_mmio_info:
-   intel_gvt_clean_mmio_info(gvt);
 out_clean_idr:
idr_destroy

[Intel-gfx] [PATCH v3 2/2] i915/gvt: save the MMIO snapshot in the early init of GVT-g

2021-11-26 Thread Zhi Wang
From: Zhi Wang 

To support the early init of GVT-g, which will be put in i915, after the
GVT-g is moved into a dedicated module, we need to save the MMIO snapshot
in the early init of GVT-g, when the HW hasn't been touched.

v3:

- Fix errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Tested-by: Terrence Xu 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/firmware.c| 40 +---
 drivers/gpu/drm/i915/gvt/handlers.c| 39 
 drivers/gpu/drm/i915/gvt/mmio_info_table.c | 72 +-
 drivers/gpu/drm/i915/gvt/mmio_info_table.h |  3 +
 4 files changed, 77 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/firmware.c 
b/drivers/gpu/drm/i915/gvt/firmware.c
index 1a8274a3f4b1..28719c2f253f 100644
--- a/drivers/gpu/drm/i915/gvt/firmware.c
+++ b/drivers/gpu/drm/i915/gvt/firmware.c
@@ -66,12 +66,6 @@ static struct bin_attribute firmware_attr = {
.mmap = NULL,
 };
 
-static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data)
-{
-   *(u32 *)(data + offset) = intel_uncore_read_notrace(gvt->gt->uncore,
-   _MMIO(offset));
-   return 0;
-}
 
 static int expose_firmware_sysfs(struct intel_gvt *gvt)
 {
@@ -81,7 +75,7 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
void *firmware;
void *p;
unsigned long size, crc32_start;
-   int i, ret;
+   int ret;
 
size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
firmware = vzalloc(size);
@@ -99,17 +93,11 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
 
p = firmware + h->cfg_space_offset;
 
-   for (i = 0; i < h->cfg_space_size; i += 4)
-   pci_read_config_dword(pdev, i, p + i);
-
-   memcpy(gvt->firmware.cfg_space, p, info->cfg_space_size);
+   memcpy(p, gvt->firmware.cfg_space, info->cfg_space_size);
 
p = firmware + h->mmio_offset;
 
-   /* Take a snapshot of hw mmio registers. */
-   intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, p);
-
-   memcpy(gvt->firmware.mmio, p, info->mmio_size);
+   memcpy(p, gvt->firmware.mmio, info->mmio_size);
 
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);
@@ -142,9 +130,6 @@ void intel_gvt_free_firmware(struct intel_gvt *gvt)
 {
if (!gvt->firmware.firmware_loaded)
clean_firmware_sysfs(gvt);
-
-   kfree(gvt->firmware.cfg_space);
-   vfree(gvt->firmware.mmio);
 }
 
 static int verify_firmware(struct intel_gvt *gvt,
@@ -204,36 +189,17 @@ static int verify_firmware(struct intel_gvt *gvt,
  */
 int intel_gvt_load_firmware(struct intel_gvt *gvt)
 {
-   struct intel_gvt_device_info *info = >device_info;
struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
struct intel_gvt_firmware *firmware = >firmware;
struct gvt_firmware_header *h;
const struct firmware *fw;
char *path;
-   void *mem;
int ret;
 
path = kmalloc(PATH_MAX, GFP_KERNEL);
if (!path)
return -ENOMEM;
 
-   mem = kmalloc(info->cfg_space_size, GFP_KERNEL);
-   if (!mem) {
-   kfree(path);
-   return -ENOMEM;
-   }
-
-   firmware->cfg_space = mem;
-
-   mem = vmalloc(info->mmio_size);
-   if (!mem) {
-   kfree(path);
-   kfree(firmware->cfg_space);
-   return -ENOMEM;
-   }
-
-   firmware->mmio = mem;
-
sprintf(path, "%s/vid_0x%04x_did_0x%04x_rid_0x%02x.golden_hw_state",
 GVT_FIRMWARE_PATH, pdev->vendor, pdev->device,
 pdev->revision);
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index 2c064da3db6d..ba7b330a2c71 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -2406,45 +2406,6 @@ int intel_gvt_setup_mmio_handlers(struct intel_gvt *gvt)
return ret;
 }
 
-/**
- * intel_gvt_for_each_tracked_mmio - iterate each tracked mmio
- * @gvt: a GVT device
- * @handler: the handler
- * @data: private data given to handler
- *
- * Returns:
- * Zero on success, negative error code if failed.
- */
-int intel_gvt_for_each_tracked_mmio(struct intel_gvt *gvt,
-   int (*handler)(struct intel_gvt *gvt, u32 offset, void *data),
-   void *data)
-{
-   struct gvt_mmio_block *block = gvt->mmio.mmio_block;
-   struct intel_gvt_mmio_info *e;
-   int i, j, ret;
-
-   hash_for_each(gvt->mmio.mmio_info_table, i, e, node) {
-   ret = handler(gvt, e->offset, data);
-  

[Intel-gfx] [PATCH 2/2] i915/gvt: save the MMIO snapshot in the early init of GVT-g

2021-11-19 Thread Zhi Wang
From: Zhi Wang 

To support the early init of GVT-g, which will be put in i915, after the
GVT-g is moved into a dedicated module, we need to save the MMIO snapshot
in the early init of GVT-g, when the HW hasn't been touched.

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Tested-by: Terrence Xu 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/firmware.c| 36 +--
 drivers/gpu/drm/i915/gvt/handlers.c| 39 
 drivers/gpu/drm/i915/gvt/mmio_info_table.c | 72 +-
 drivers/gpu/drm/i915/gvt/mmio_info_table.h |  3 +
 4 files changed, 76 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/firmware.c 
b/drivers/gpu/drm/i915/gvt/firmware.c
index 1a8274a3f4b1..dd5d4dd7a8cf 100644
--- a/drivers/gpu/drm/i915/gvt/firmware.c
+++ b/drivers/gpu/drm/i915/gvt/firmware.c
@@ -66,12 +66,6 @@ static struct bin_attribute firmware_attr = {
.mmap = NULL,
 };
 
-static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data)
-{
-   *(u32 *)(data + offset) = intel_uncore_read_notrace(gvt->gt->uncore,
-   _MMIO(offset));
-   return 0;
-}
 
 static int expose_firmware_sysfs(struct intel_gvt *gvt)
 {
@@ -99,17 +93,11 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
 
p = firmware + h->cfg_space_offset;
 
-   for (i = 0; i < h->cfg_space_size; i += 4)
-   pci_read_config_dword(pdev, i, p + i);
-
-   memcpy(gvt->firmware.cfg_space, p, info->cfg_space_size);
+   memcpy(p, gvt->firmware.cfg_space, info->cfg_space_size);
 
p = firmware + h->mmio_offset;
 
-   /* Take a snapshot of hw mmio registers. */
-   intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, p);
-
-   memcpy(gvt->firmware.mmio, p, info->mmio_size);
+   memcpy(p, gvt->firmware.mmio, info->mmio_size);
 
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);
@@ -142,9 +130,6 @@ void intel_gvt_free_firmware(struct intel_gvt *gvt)
 {
if (!gvt->firmware.firmware_loaded)
clean_firmware_sysfs(gvt);
-
-   kfree(gvt->firmware.cfg_space);
-   vfree(gvt->firmware.mmio);
 }
 
 static int verify_firmware(struct intel_gvt *gvt,
@@ -217,23 +202,6 @@ int intel_gvt_load_firmware(struct intel_gvt *gvt)
if (!path)
return -ENOMEM;
 
-   mem = kmalloc(info->cfg_space_size, GFP_KERNEL);
-   if (!mem) {
-   kfree(path);
-   return -ENOMEM;
-   }
-
-   firmware->cfg_space = mem;
-
-   mem = vmalloc(info->mmio_size);
-   if (!mem) {
-   kfree(path);
-   kfree(firmware->cfg_space);
-   return -ENOMEM;
-   }
-
-   firmware->mmio = mem;
-
sprintf(path, "%s/vid_0x%04x_did_0x%04x_rid_0x%02x.golden_hw_state",
 GVT_FIRMWARE_PATH, pdev->vendor, pdev->device,
 pdev->revision);
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index 2c064da3db6d..ba7b330a2c71 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -2406,45 +2406,6 @@ int intel_gvt_setup_mmio_handlers(struct intel_gvt *gvt)
return ret;
 }
 
-/**
- * intel_gvt_for_each_tracked_mmio - iterate each tracked mmio
- * @gvt: a GVT device
- * @handler: the handler
- * @data: private data given to handler
- *
- * Returns:
- * Zero on success, negative error code if failed.
- */
-int intel_gvt_for_each_tracked_mmio(struct intel_gvt *gvt,
-   int (*handler)(struct intel_gvt *gvt, u32 offset, void *data),
-   void *data)
-{
-   struct gvt_mmio_block *block = gvt->mmio.mmio_block;
-   struct intel_gvt_mmio_info *e;
-   int i, j, ret;
-
-   hash_for_each(gvt->mmio.mmio_info_table, i, e, node) {
-   ret = handler(gvt, e->offset, data);
-   if (ret)
-   return ret;
-   }
-
-   for (i = 0; i < gvt->mmio.num_mmio_block; i++, block++) {
-   /* pvinfo data doesn't come from hw mmio */
-   if (i915_mmio_reg_offset(block->offset) == VGT_PVINFO_PAGE)
-   continue;
-
-   for (j = 0; j < block->size; j += 4) {
-   ret = handler(gvt,
- i915_mmio_reg_offset(block->offset) + j,
- data);
-   if (ret)
-   return ret;
-   }
-   }
-   return 0;
-}
-
 /**
  * intel_vgpu_default_mmio_read - default MMIO read handler
  * @vgpu: a vGPU
diff --git a/drivers/gpu/drm/i915/gvt/mmio_info_table.c 

[Intel-gfx] [PATCH 1/2] i915/gvt: Introduce the mmio_info_table.c to support VFIO new mdev API

2021-11-19 Thread Zhi Wang
From: Zhi Wang 

To support the new mdev interfaces and the re-factor patches from
Christoph, which moves the GVT-g code into a dedicated module, the GVT-g
initialization path has to be seperated into two phases:

a) Early initialization.

The early initialization of GVT requires to be done when loading i915.
Mostly it's because the inital clean HW state needs to be saved before
i915 touches the HW.

b) Late initalization.

This phases of initalization will setup the rest components of GVT-g,
which can be done later when the dedicated module is being loaded.

v2:

- Implement a mmio table instead of generating it by marco in i915. (Jani)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Tested-by: Terrence Xu 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/Makefile  |2 +-
 drivers/gpu/drm/i915/gvt/gvt.c |   38 +-
 drivers/gpu/drm/i915/gvt/gvt.h |1 +
 drivers/gpu/drm/i915/gvt/handlers.c| 1780 +++-
 drivers/gpu/drm/i915/gvt/mmio.h|5 +-
 drivers/gpu/drm/i915/gvt/mmio_info_table.c | 1461 
 drivers/gpu/drm/i915/gvt/mmio_info_table.h |   35 +
 drivers/gpu/drm/i915/gvt/reg.h |9 +-
 drivers/gpu/drm/i915/intel_gvt.c   |   42 +-
 9 files changed, 1775 insertions(+), 1598 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/mmio_info_table.c
 create mode 100644 drivers/gpu/drm/i915/gvt/mmio_info_table.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index cdc244bbbfc1..55603aebe3e4 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -309,7 +309,7 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \
 i915-y += i915_vgpu.o
 
 ifeq ($(CONFIG_DRM_I915_GVT),y)
-i915-y += intel_gvt.o
+i915-y += intel_gvt.o gvt/mmio_info_table.o
 include $(src)/gvt/Makefile
 endif
 
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index cbac409f6c8a..c7580db355c0 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -63,23 +63,6 @@ static const struct intel_gvt_ops intel_gvt_ops = {
.emulate_hotplug = intel_vgpu_emulate_hotplug,
 };
 
-static void init_device_info(struct intel_gvt *gvt)
-{
-   struct intel_gvt_device_info *info = >device_info;
-   struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
-
-   info->max_support_vgpus = 8;
-   info->cfg_space_size = PCI_CFG_SPACE_EXP_SIZE;
-   info->mmio_size = 2 * 1024 * 1024;
-   info->mmio_bar = 0;
-   info->gtt_start_offset = 8 * 1024 * 1024;
-   info->gtt_entry_size = 8;
-   info->gtt_entry_size_shift = 3;
-   info->gmadr_bytes_in_cmd = 8;
-   info->max_surface_size = 36 * 1024 * 1024;
-   info->msi_cap_offset = pdev->msi_cap;
-}
-
 static void intel_gvt_test_and_emulate_vblank(struct intel_gvt *gvt)
 {
struct intel_vgpu *vgpu;
@@ -169,7 +152,6 @@ void intel_gvt_clean_device(struct drm_i915_private *i915)
intel_gvt_clean_workload_scheduler(gvt);
intel_gvt_clean_gtt(gvt);
intel_gvt_free_firmware(gvt);
-   intel_gvt_clean_mmio_info(gvt);
idr_destroy(>vgpu_idr);
 
kfree(i915->gvt);
@@ -188,16 +170,12 @@ void intel_gvt_clean_device(struct drm_i915_private *i915)
  */
 int intel_gvt_init_device(struct drm_i915_private *i915)
 {
-   struct intel_gvt *gvt;
+   struct intel_gvt *gvt = i915->gvt;
struct intel_vgpu *vgpu;
int ret;
 
-   if (drm_WARN_ON(>drm, i915->gvt))
-   return -EEXIST;
-
-   gvt = kzalloc(sizeof(struct intel_gvt), GFP_KERNEL);
-   if (!gvt)
-   return -ENOMEM;
+   if (drm_WARN_ON(>drm, !i915->gvt))
+   return -ENODEV;
 
gvt_dbg_core("init gvt device\n");
 
@@ -205,12 +183,8 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
spin_lock_init(>scheduler.mmio_context_lock);
mutex_init(>lock);
mutex_init(>sched_lock);
-   gvt->gt = >gt;
-   i915->gvt = gvt;
-
-   init_device_info(gvt);
 
-   ret = intel_gvt_setup_mmio_info(gvt);
+   ret = intel_gvt_setup_mmio_handlers(gvt);
if (ret)
goto out_clean_idr;
 
@@ -218,7 +192,7 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
 
ret = intel_gvt_load_firmware(gvt);
if (ret)
-   goto out_clean_mmio_info;
+   goto out_clean_idr;
 
ret = intel_gvt_init_irq(gvt);
if (ret)
@@ -277,8 +251,6 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
intel_gvt_clean_gtt(gvt);
 out_free_firmware:
intel_gvt_free_firmware(gvt);
-out_clean_mmio_info:
-   intel_gvt_clean_mmio_info(gvt);
 out_clean_idr:
idr_destroy(>vgpu_idr);
kfree(gvt);
diff --git a/drivers/gpu/drm/i915/gvt

[Intel-gfx] [PATCH 3/3] i915/gvt: Use the initial HW state snapshot saved in i915

2021-11-09 Thread Zhi Wang
From: Zhi Wang 

The code of saving initial HW state snapshot has been moved into i915.
Let the GVT-g core logic use that snapshot.

Cc: Joonas Lahtinen 
Cc: Jani Nikula 
Cc: Rodrigo Vivi 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/cfg_space.c |  2 +-
 drivers/gpu/drm/i915/gvt/firmware.c  | 45 
 drivers/gpu/drm/i915/gvt/gvt.h   |  2 --
 drivers/gpu/drm/i915/gvt/mmio.c  |  2 +-
 4 files changed, 7 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c 
b/drivers/gpu/drm/i915/gvt/cfg_space.c
index b490e3db2e38..51588ca95113 100644
--- a/drivers/gpu/drm/i915/gvt/cfg_space.c
+++ b/drivers/gpu/drm/i915/gvt/cfg_space.c
@@ -379,7 +379,7 @@ void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu,
u16 *gmch_ctl;
u8 next;
 
-   memcpy(vgpu_cfg_space(vgpu), gvt->firmware.cfg_space,
+   memcpy(vgpu_cfg_space(vgpu), gvt->hw_state.cfg_space,
   info->cfg_space_size);
 
if (!primary) {
diff --git a/drivers/gpu/drm/i915/gvt/firmware.c 
b/drivers/gpu/drm/i915/gvt/firmware.c
index 1a8274a3f4b1..a98af544abca 100644
--- a/drivers/gpu/drm/i915/gvt/firmware.c
+++ b/drivers/gpu/drm/i915/gvt/firmware.c
@@ -66,13 +66,6 @@ static struct bin_attribute firmware_attr = {
.mmap = NULL,
 };
 
-static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data)
-{
-   *(u32 *)(data + offset) = intel_uncore_read_notrace(gvt->gt->uncore,
-   _MMIO(offset));
-   return 0;
-}
-
 static int expose_firmware_sysfs(struct intel_gvt *gvt)
 {
struct intel_gvt_device_info *info = >device_info;
@@ -81,7 +74,7 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
void *firmware;
void *p;
unsigned long size, crc32_start;
-   int i, ret;
+   int ret;
 
size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
firmware = vzalloc(size);
@@ -99,17 +92,11 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
 
p = firmware + h->cfg_space_offset;
 
-   for (i = 0; i < h->cfg_space_size; i += 4)
-   pci_read_config_dword(pdev, i, p + i);
-
-   memcpy(gvt->firmware.cfg_space, p, info->cfg_space_size);
+   memcpy(gvt->hw_state.cfg_space, p, info->cfg_space_size);
 
p = firmware + h->mmio_offset;
 
-   /* Take a snapshot of hw mmio registers. */
-   intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, p);
-
-   memcpy(gvt->firmware.mmio, p, info->mmio_size);
+   memcpy(gvt->hw_state.mmio, p, info->mmio_size);
 
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);
@@ -142,9 +129,6 @@ void intel_gvt_free_firmware(struct intel_gvt *gvt)
 {
if (!gvt->firmware.firmware_loaded)
clean_firmware_sysfs(gvt);
-
-   kfree(gvt->firmware.cfg_space);
-   vfree(gvt->firmware.mmio);
 }
 
 static int verify_firmware(struct intel_gvt *gvt,
@@ -204,36 +188,17 @@ static int verify_firmware(struct intel_gvt *gvt,
  */
 int intel_gvt_load_firmware(struct intel_gvt *gvt)
 {
-   struct intel_gvt_device_info *info = >device_info;
struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
struct intel_gvt_firmware *firmware = >firmware;
struct gvt_firmware_header *h;
const struct firmware *fw;
char *path;
-   void *mem;
int ret;
 
path = kmalloc(PATH_MAX, GFP_KERNEL);
if (!path)
return -ENOMEM;
 
-   mem = kmalloc(info->cfg_space_size, GFP_KERNEL);
-   if (!mem) {
-   kfree(path);
-   return -ENOMEM;
-   }
-
-   firmware->cfg_space = mem;
-
-   mem = vmalloc(info->mmio_size);
-   if (!mem) {
-   kfree(path);
-   kfree(firmware->cfg_space);
-   return -ENOMEM;
-   }
-
-   firmware->mmio = mem;
-
sprintf(path, "%s/vid_0x%04x_did_0x%04x_rid_0x%02x.golden_hw_state",
 GVT_FIRMWARE_PATH, pdev->vendor, pdev->device,
 pdev->revision);
@@ -256,9 +221,9 @@ int intel_gvt_load_firmware(struct intel_gvt *gvt)
 
h = (struct gvt_firmware_header *)fw->data;
 
-   memcpy(firmware->cfg_space, fw->data + h->cfg_space_offset,
+   memcpy(gvt->hw_state.cfg_space, fw->data + h->cfg_space_offset,
   h->cfg_space_size);
-   memcpy(firmware->mmio, fw->data + h->mmio_offset,
+   memcpy(gvt->hw_state.mmio, fw->data + h->mmio_offset,
   h->mmio_size);
 
release_firmware(fw);
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index

[Intel-gfx] [PATCH 1/3] i915/gvt: seperate tracked MMIO table from handlers.c

2021-11-09 Thread Zhi Wang
From: Zhi Wang 

To support the new mdev interfaces and the re-factor patches from
Christoph, which moves the GVT-g code into a dedicated module, the GVT-g
MMIO snapshot still needs to be saved in i915 so that the inital clean HW
state can be used for the further vGPU. Seperate the tracked MMIO table
from GVT-g, so that GVT-g and i915 can both use it.

Cc: Joonas Lahtinen 
Cc: Jani Nikula 
Cc: Rodrigo Vivi 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/handlers.c   | 1539 +---
 drivers/gpu/drm/i915/gvt/mmio_table.h | 1570 +
 drivers/gpu/drm/i915/gvt/reg.h|6 +
 drivers/gpu/drm/i915/intel_gvt.c  |   11 +
 4 files changed, 1592 insertions(+), 1534 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/mmio_table.h

diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index cde0a477fb49..6a08d362bf66 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -41,13 +41,6 @@
 #include "i915_pvinfo.h"
 #include "display/intel_display_types.h"
 
-/* XXX FIXME i915 has changed PP_XXX definition */
-#define PCH_PP_STATUS  _MMIO(0xc7200)
-#define PCH_PP_CONTROL _MMIO(0xc7204)
-#define PCH_PP_ON_DELAYS _MMIO(0xc7208)
-#define PCH_PP_OFF_DELAYS _MMIO(0xc720c)
-#define PCH_PP_DIVISOR _MMIO(0xc7210)
-
 unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt)
 {
struct drm_i915_private *i915 = gvt->gt->i915;
@@ -2131,1501 +2124,7 @@ static int csfe_chicken1_mmio_write(struct intel_vgpu 
*vgpu,
return 0;
 }
 
-#define MMIO_F(reg, s, f, am, rm, d, r, w) do { \
-   ret = new_mmio_info(gvt, i915_mmio_reg_offset(reg), \
-   f, s, am, rm, d, r, w); \
-   if (ret) \
-   return ret; \
-} while (0)
-
-#define MMIO_D(reg, d) \
-   MMIO_F(reg, 4, 0, 0, 0, d, NULL, NULL)
-
-#define MMIO_DH(reg, d, r, w) \
-   MMIO_F(reg, 4, 0, 0, 0, d, r, w)
-
-#define MMIO_DFH(reg, d, f, r, w) \
-   MMIO_F(reg, 4, f, 0, 0, d, r, w)
-
-#define MMIO_GM(reg, d, r, w) \
-   MMIO_F(reg, 4, F_GMADR, 0xF000, 0, d, r, w)
-
-#define MMIO_GM_RDR(reg, d, r, w) \
-   MMIO_F(reg, 4, F_GMADR | F_CMD_ACCESS, 0xF000, 0, d, r, w)
-
-#define MMIO_RO(reg, d, f, rm, r, w) \
-   MMIO_F(reg, 4, F_RO | f, 0, rm, d, r, w)
-
-#define MMIO_RING_F(prefix, s, f, am, rm, d, r, w) do { \
-   MMIO_F(prefix(RENDER_RING_BASE), s, f, am, rm, d, r, w); \
-   MMIO_F(prefix(BLT_RING_BASE), s, f, am, rm, d, r, w); \
-   MMIO_F(prefix(GEN6_BSD_RING_BASE), s, f, am, rm, d, r, w); \
-   MMIO_F(prefix(VEBOX_RING_BASE), s, f, am, rm, d, r, w); \
-   if (HAS_ENGINE(gvt->gt, VCS1)) \
-   MMIO_F(prefix(GEN8_BSD2_RING_BASE), s, f, am, rm, d, r, w); \
-} while (0)
-
-#define MMIO_RING_D(prefix, d) \
-   MMIO_RING_F(prefix, 4, 0, 0, 0, d, NULL, NULL)
-
-#define MMIO_RING_DFH(prefix, d, f, r, w) \
-   MMIO_RING_F(prefix, 4, f, 0, 0, d, r, w)
-
-#define MMIO_RING_GM(prefix, d, r, w) \
-   MMIO_RING_F(prefix, 4, F_GMADR, 0x, 0, d, r, w)
-
-#define MMIO_RING_GM_RDR(prefix, d, r, w) \
-   MMIO_RING_F(prefix, 4, F_GMADR | F_CMD_ACCESS, 0x, 0, d, r, w)
-
-#define MMIO_RING_RO(prefix, d, f, rm, r, w) \
-   MMIO_RING_F(prefix, 4, F_RO | f, 0, rm, d, r, w)
-
-static int init_generic_mmio_info(struct intel_gvt *gvt)
-{
-   struct drm_i915_private *dev_priv = gvt->gt->i915;
-   int ret;
-
-   MMIO_RING_DFH(RING_IMR, D_ALL, 0, NULL,
-   intel_vgpu_reg_imr_handler);
-
-   MMIO_DFH(SDEIMR, D_ALL, 0, NULL, intel_vgpu_reg_imr_handler);
-   MMIO_DFH(SDEIER, D_ALL, 0, NULL, intel_vgpu_reg_ier_handler);
-   MMIO_DFH(SDEIIR, D_ALL, 0, NULL, intel_vgpu_reg_iir_handler);
-   MMIO_D(SDEISR, D_ALL);
-
-   MMIO_RING_DFH(RING_HWSTAM, D_ALL, 0, NULL, NULL);
-
-
-   MMIO_DH(GEN8_GAMW_ECO_DEV_RW_IA, D_BDW_PLUS, NULL,
-   gamw_echo_dev_rw_ia_write);
-
-   MMIO_GM_RDR(BSD_HWS_PGA_GEN7, D_ALL, NULL, NULL);
-   MMIO_GM_RDR(BLT_HWS_PGA_GEN7, D_ALL, NULL, NULL);
-   MMIO_GM_RDR(VEBOX_HWS_PGA_GEN7, D_ALL, NULL, NULL);
-
-#define RING_REG(base) _MMIO((base) + 0x28)
-   MMIO_RING_DFH(RING_REG, D_ALL, F_CMD_ACCESS, NULL, NULL);
-#undef RING_REG
-
-#define RING_REG(base) _MMIO((base) + 0x134)
-   MMIO_RING_DFH(RING_REG, D_ALL, F_CMD_ACCESS, NULL, NULL);
-#undef RING_REG
-
-#define RING_REG(base) _MMIO((base) + 0x6c)
-   MMIO_RING_DFH(RING_REG, D_ALL, 0, mmio_read_from_hw, NULL);
-#undef RING_REG
-   MMIO_DH(GEN7_SC_INSTDONE, D_BDW_PLUS, mmio_read_from_hw, NULL);
-
-   MMIO_GM_RDR(_MMIO(0x2148), D_ALL, NULL, NULL);
-   MMIO_GM_RDR(CCID(RENDER_RING_BASE), D_ALL, NULL, NULL);
-   MMIO_GM_RDR(_MMIO(0x12198), D_ALL, NULL, NULL);
-   MMIO_D(GEN7_CXT_SIZE, D_ALL);
-
-   MMIO_RING_DFH(RING_TAIL, D_ALL, 0, NULL, NULL);
-   MMIO_RING_

[Intel-gfx] [PATCH 2/3] i915/gvt: save the initial HW state snapshot in i915.

2021-11-09 Thread Zhi Wang
From: Zhi Wang 

Save the inital HW state snapshot in i915 so that the rest code of GVT-g
can be moved into a dedicated module while it can still get a clean
initial HW state saved at the correct time during the initialization of
i915. The futhrer vGPU created by GVT-g will use this HW state as the
initial HW state.

Cc: Joonas Lahtinen 
Cc: Jani Nikula 
Cc: Rodrigo Vivi 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/gvt.c   | 31 +
 drivers/gpu/drm/i915/gvt/gvt.h   |  6 +++
 drivers/gpu/drm/i915/intel_gvt.c | 75 ++--
 3 files changed, 80 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index cbac409f6c8a..4b3b47892453 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -63,23 +63,6 @@ static const struct intel_gvt_ops intel_gvt_ops = {
.emulate_hotplug = intel_vgpu_emulate_hotplug,
 };
 
-static void init_device_info(struct intel_gvt *gvt)
-{
-   struct intel_gvt_device_info *info = >device_info;
-   struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
-
-   info->max_support_vgpus = 8;
-   info->cfg_space_size = PCI_CFG_SPACE_EXP_SIZE;
-   info->mmio_size = 2 * 1024 * 1024;
-   info->mmio_bar = 0;
-   info->gtt_start_offset = 8 * 1024 * 1024;
-   info->gtt_entry_size = 8;
-   info->gtt_entry_size_shift = 3;
-   info->gmadr_bytes_in_cmd = 8;
-   info->max_surface_size = 36 * 1024 * 1024;
-   info->msi_cap_offset = pdev->msi_cap;
-}
-
 static void intel_gvt_test_and_emulate_vblank(struct intel_gvt *gvt)
 {
struct intel_vgpu *vgpu;
@@ -188,27 +171,19 @@ void intel_gvt_clean_device(struct drm_i915_private *i915)
  */
 int intel_gvt_init_device(struct drm_i915_private *i915)
 {
-   struct intel_gvt *gvt;
+   struct intel_gvt *gvt = i915->gvt;
struct intel_vgpu *vgpu;
int ret;
 
-   if (drm_WARN_ON(>drm, i915->gvt))
+   if (drm_WARN_ON(>drm, !i915->gvt))
return -EEXIST;
 
-   gvt = kzalloc(sizeof(struct intel_gvt), GFP_KERNEL);
-   if (!gvt)
-   return -ENOMEM;
-
gvt_dbg_core("init gvt device\n");
 
idr_init_base(>vgpu_idr, 1);
spin_lock_init(>scheduler.mmio_context_lock);
mutex_init(>lock);
mutex_init(>sched_lock);
-   gvt->gt = >gt;
-   i915->gvt = gvt;
-
-   init_device_info(gvt);
 
ret = intel_gvt_setup_mmio_info(gvt);
if (ret)
@@ -281,8 +256,6 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
intel_gvt_clean_mmio_info(gvt);
 out_clean_idr:
idr_destroy(>vgpu_idr);
-   kfree(gvt);
-   i915->gvt = NULL;
return ret;
 }
 
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 0c0615602343..1defee730cf3 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -296,6 +296,11 @@ struct intel_vgpu_type {
enum intel_vgpu_edid resolution;
 };
 
+struct intel_gvt_hw_state {
+   void *cfg_space;
+   void *mmio;
+};
+
 struct intel_gvt {
/* GVT scope lock, protect GVT itself, and all resource currently
 * not yet protected by special locks(vgpu and scheduler lock).
@@ -311,6 +316,7 @@ struct intel_gvt {
struct intel_gvt_gm gm;
struct intel_gvt_fence fence;
struct intel_gvt_mmio mmio;
+   struct intel_gvt_hw_state hw_state;
struct intel_gvt_firmware firmware;
struct intel_gvt_irq irq;
struct intel_gvt_gtt gtt;
diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c
index 64846d9bff0b..4fd51974bd35 100644
--- a/drivers/gpu/drm/i915/intel_gvt.c
+++ b/drivers/gpu/drm/i915/intel_gvt.c
@@ -87,8 +87,12 @@ void intel_gvt_sanitize_options(struct drm_i915_private 
*dev_priv)
 }
 
 #define GENERATE_MMIO_TABLE_IN_I915
-static int new_mmio_info(struct intel_gvt *gvt, u64 offset)
+static int new_mmio_info(struct intel_gvt *gvt, u32 offset)
 {
+   void *mmio = gvt->hw_state.mmio;
+
+   *(u32 *)(mmio + offset) = intel_uncore_read_notrace(gvt->gt->uncore,
+   _MMIO(offset));
return 0;
 }
 
@@ -96,6 +100,22 @@ static int new_mmio_info(struct intel_gvt *gvt, u64 offset)
 #include "gvt/mmio_table.h"
 #undef GENERATE_MMIO_TABLE_IN_I915
 
+static void init_device_info(struct intel_gvt *gvt)
+{
+   struct intel_gvt_device_info *info = >device_info;
+   struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
+
+   info->max_support_vgpus = 8;
+   info->cfg_space_size = PCI_CFG_SPACE_EXP_SIZE;
+   info->mmio_size = 2 * 1024 * 1024;
+   info->mmio_bar = 0;
+   info->gtt_start_offset 

[Intel-gfx] [PATCH] drm/i915/gvt: Introduce per object locking in GVT scheduler.

2020-09-07 Thread Zhi Wang
To support ww locking and per-object implemented in i915, GVT scheduler needs
to be refined. Most of the changes are located in shadow batch buffer, shadow
wa context in GVT-g, where use quite a lot of i915 gem object APIs.

Cc: Maarten Lankhorst 
Cc: Joonas Lahtinen 
Cc: Zhenyu Wang 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/scheduler.c | 68 ++--
 1 file changed, 57 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c 
b/drivers/gpu/drm/i915/gvt/scheduler.c
index 1570eb8..fe7ee10 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -396,7 +396,9 @@ static void release_shadow_wa_ctx(struct 
intel_shadow_wa_ctx *wa_ctx)
if (!wa_ctx->indirect_ctx.obj)
return;
 
+   i915_gem_object_lock(wa_ctx->indirect_ctx.obj, NULL);
i915_gem_object_unpin_map(wa_ctx->indirect_ctx.obj);
+   i915_gem_object_unlock(wa_ctx->indirect_ctx.obj);
i915_gem_object_put(wa_ctx->indirect_ctx.obj);
 
wa_ctx->indirect_ctx.obj = NULL;
@@ -504,6 +506,7 @@ static int prepare_shadow_batch_buffer(struct 
intel_vgpu_workload *workload)
struct intel_gvt *gvt = workload->vgpu->gvt;
const int gmadr_bytes = gvt->device_info.gmadr_bytes_in_cmd;
struct intel_vgpu_shadow_bb *bb;
+   struct i915_gem_ww_ctx ww;
int ret;
 
list_for_each_entry(bb, >shadow_bb, list) {
@@ -528,10 +531,19 @@ static int prepare_shadow_batch_buffer(struct 
intel_vgpu_workload *workload)
 * directly
 */
if (!bb->ppgtt) {
-   bb->vma = i915_gem_object_ggtt_pin(bb->obj,
-  NULL, 0, 0, 0);
+   i915_gem_ww_ctx_init(, false);
+retry:
+   i915_gem_object_lock(bb->obj, );
+
+   bb->vma = i915_gem_object_ggtt_pin_ww(bb->obj, ,
+ NULL, 0, 0, 0);
if (IS_ERR(bb->vma)) {
ret = PTR_ERR(bb->vma);
+   if (ret == -EDEADLK) {
+   ret = i915_gem_ww_ctx_backoff();
+   if (!ret)
+   goto retry;
+   }
goto err;
}
 
@@ -545,13 +557,18 @@ static int prepare_shadow_batch_buffer(struct 
intel_vgpu_workload *workload)
  0);
if (ret)
goto err;
+
+   /* No one is going to touch shadow bb from now on. */
+   i915_gem_object_flush_map(bb->obj);
+
+   i915_gem_object_unlock(bb->obj);
+   i915_gem_ww_ctx_fini();
}
 
-   /* No one is going to touch shadow bb from now on. */
-   i915_gem_object_flush_map(bb->obj);
}
return 0;
 err:
+   i915_gem_ww_ctx_fini();
release_shadow_batch_buffer(workload);
return ret;
 }
@@ -578,14 +595,30 @@ static int prepare_shadow_wa_ctx(struct 
intel_shadow_wa_ctx *wa_ctx)
unsigned char *per_ctx_va =
(unsigned char *)wa_ctx->indirect_ctx.shadow_va +
wa_ctx->indirect_ctx.size;
+   struct i915_gem_ww_ctx ww;
+   int ret;
 
if (wa_ctx->indirect_ctx.size == 0)
return 0;
 
-   vma = i915_gem_object_ggtt_pin(wa_ctx->indirect_ctx.obj, NULL,
-  0, CACHELINE_BYTES, 0);
-   if (IS_ERR(vma))
-   return PTR_ERR(vma);
+   i915_gem_ww_ctx_init(, false);
+retry:
+   i915_gem_object_lock(wa_ctx->indirect_ctx.obj, );
+
+   vma = i915_gem_object_ggtt_pin_ww(wa_ctx->indirect_ctx.obj, , NULL,
+ 0, CACHELINE_BYTES, 0);
+   if (IS_ERR(vma)) {
+   ret = PTR_ERR(vma);
+   if (ret == -EDEADLK) {
+   ret = i915_gem_ww_ctx_backoff();
+   if (!ret)
+   goto retry;
+   }
+   return ret;
+   }
+
+   i915_gem_object_unlock(wa_ctx->indirect_ctx.obj);
+   i915_gem_ww_ctx_fini();
 
/* FIXME: we are not tracking our pinned VMA leaving it
 * up to the core to fix up the stray pin_count upon
@@ -619,12 +652,14 @@ static void release_shadow_batch_buffer(struct 
intel_vgpu_workload *workload)
 
list_for_each_entry_safe(bb, pos, >shadow_bb, list) {
if (bb->obj) {
+   i915_gem_object_lock(bb->obj, NULL);
if (bb->va && !IS_ERR(bb->va)

Re: [Intel-gfx] [PATCH v4] drm/i915: Remove i915.enable_ppgtt override

2018-10-09 Thread Zhi Wang
This is ideal and had been discussed in the beginning of upstream. 
Mostly people didn't like this approach because it needs to modify i915 
ppgtt code a lot and have to introduce a lot gvt-only code in i915 ppgtt.


The idea of the series of Joonas patch is to make PPGTT selection 
per-platform. I guess that's the reason why he removed that check.
From his idea, there shouldn't be any platform which has execlist 
support, but is still using aliasing PPGTT.


So it looks like there two approaches.

One is following the idea of this patch series: Platform with execlist 
shouldn't touch aliasing PPGTT anymore, which needs GVT-g to create a 
dummy PPGTT instance. (One dummy PPGTT instance for the architectural 
design)


Another one is keeping the check as workaround like before.

I would like to choose a but b is also reasonable to me.

Thanks,
Zhi.

On 10/08/18 22:15, Zhenyu Wang wrote:

On 2018.10.08 13:58:25 +, Wang, Zhi A wrote:

Thanks for pointing this. My bad.

I take a look on the code and it looks like the GVT-g context is now quite 
similar with the kernel context except the force single submission and ring 
buffer size. (When we upstream the code, there was no kernel context at that 
time. :/) Now there is already one API for single submission. If we can 
introduce another one to configure the ring buffer size. Then maybe we can 
remove the *create_gvt() in i915_gem_context.c and used kernel context instead.

Feel free to drop comments. :)



For ppgtt, you'd better change to use i915 ppgtt interface to handle
shadow pages, then gvt context would be much like normal one.


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4] drm/i915: Remove i915.enable_ppgtt override

2018-09-26 Thread Zhi Wang

Sure. Acked-by: Zhi Wang 

Meanwhile, I could send a patch to remove 
gen8_preallocate_top_level_pdp() in i915_gem_gtt.c, which is only used 
by vGPU with 32bit PPGTT (no one is going to use them after this patch 
is landed)


Thanks,
Zhi.

On 09/26/18 04:02, Joonas Lahtinen wrote:

Quoting He, Min (2018-09-26 04:06:25)

No. We changed to full 48bit ppgtt long time ago. :)


So would that mean the change is OK to do?

Acked-by from you, Zhi, would be good to have for documentation purposes
in that case :)

Regards, Joonas




-Original Message-
From: Wang, Zhi A
Sent: Wednesday, September 26, 2018 2:01 AM
To: Joonas Lahtinen ; Chris Wilson
; intel-gfx@lists.freedesktop.org; Zhenyu Wang

Cc: Auld, Matthew ; He, Min 
Subject: Re: [PATCH v4] drm/i915: Remove i915.enable_ppgtt override

Hi Min:

I remembered the IOTG guest kernel is using aliasing-ppgtt in the last
technical sharing (probably I didn't remember it correctly). Can you
confirm?

Also, thanks Joonas for the reminding. :)

thanks,
Zhi.

On 09/25/18 09:22, Joonas Lahtinen wrote:

+ Zhi and Zhenyu

For me the patch looks ok.

It refuses to load GVT on systems where 48-bit is not supported, for not
worsening the system security when virtualization is enabled (as anybody
would probably expect virtualization to improve that). Please see code.

Do we have such systems in the wild? Should we instruct the user to
updating the hypervisor to specific kernel version when they hit the
error?

Regards, Joonas

Quoting Chris Wilson (2018-09-25 14:48:20)

Now that we are confident in providing full-ppgtt where supported,
remove the ability to override the context isolation.

v2: Remove faked aliasing-ppgtt for testing as it no longer is accepted.
v3: s/USES/HAS/ to match usage and reject attempts to load the module

on

old GVT-g setups that do not provide support for full-ppgtt.

Signed-off-by: Chris Wilson 
Cc: Joonas Lahtinen 
Cc: Matthew Auld 
---
   drivers/gpu/drm/i915/i915_drv.c   | 22 +++--
   drivers/gpu/drm/i915/i915_drv.h   | 14 +--
   drivers/gpu/drm/i915/i915_gem_context.c   |  2 +-
   drivers/gpu/drm/i915/i915_gem_gtt.c   | 88 ++-
   drivers/gpu/drm/i915/i915_gpu_error.c |  4 +-
   drivers/gpu/drm/i915/i915_params.c|  4 -
   drivers/gpu/drm/i915/i915_params.h|  1 -
   drivers/gpu/drm/i915/i915_pci.c   | 17 ++--
   drivers/gpu/drm/i915/intel_device_info.c  |  6 ++
   drivers/gpu/drm/i915/intel_device_info.h  | 11 ++-
   drivers/gpu/drm/i915/intel_lrc.c  | 13 ++-
   drivers/gpu/drm/i915/selftests/huge_pages.c   | 12 +--
   .../gpu/drm/i915/selftests/i915_gem_context.c | 59 +
   .../gpu/drm/i915/selftests/i915_gem_evict.c   |  2 +-
   drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  4 +-
   15 files changed, 62 insertions(+), 197 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c

b/drivers/gpu/drm/i915/i915_drv.c

index 44e2c0f5ec50..3efbbc71c3b4 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -345,7 +345,7 @@ static int i915_getparam_ioctl(struct drm_device

*dev, void *data,

  value = HAS_WT(dev_priv);
  break;
  case I915_PARAM_HAS_ALIASING_PPGTT:
-   value = USES_PPGTT(dev_priv);
+   value = INTEL_PPGTT(dev_priv);
  break;
  case I915_PARAM_HAS_SEMAPHORES:
  value = HAS_LEGACY_SEMAPHORES(dev_priv);
@@ -1049,17 +1049,6 @@ static void i915_driver_cleanup_mmio(struct

drm_i915_private *dev_priv)


   static void intel_sanitize_options(struct drm_i915_private *dev_priv)
   {
-   /*
-* i915.enable_ppgtt is read-only, so do an early pass to validate the
-* user's requested state against the hardware/driver capabilities.

We

-* do this now so that we can print out any log messages once rather
-* than every time we check intel_enable_ppgtt().
-*/
-   i915_modparams.enable_ppgtt =
-   intel_sanitize_enable_ppgtt(dev_priv,
-   i915_modparams.enable_ppgtt);
-   DRM_DEBUG_DRIVER("ppgtt mode: %i\n",

i915_modparams.enable_ppgtt);

-
  intel_gvt_sanitize_options(dev_priv);
   }

@@ -1374,6 +1363,15 @@ static int i915_driver_init_hw(struct

drm_i915_private *dev_priv)


  intel_device_info_runtime_init(mkwrite_device_info(dev_priv));

+   if (HAS_PPGTT(dev_priv)) {
+   if (intel_vgpu_active(dev_priv) &&
+   !intel_vgpu_has_full_48bit_ppgtt(dev_priv)) {
+   i915_report_error(dev_priv,
+ "incompatible vGPU found, support for 
isolated

ppGTT required\n");

+   return -ENXIO;
+   }
+   }
+
  intel_sanitize_options(dev_priv);

  i915_perf_init(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_d

Re: [Intel-gfx] [PATCH v4] drm/i915: Remove i915.enable_ppgtt override

2018-09-25 Thread Zhi Wang

Hi Min:

I remembered the IOTG guest kernel is using aliasing-ppgtt in the last 
technical sharing (probably I didn't remember it correctly). Can you 
confirm?


Also, thanks Joonas for the reminding. :)

thanks,
Zhi.

On 09/25/18 09:22, Joonas Lahtinen wrote:

+ Zhi and Zhenyu

For me the patch looks ok.

It refuses to load GVT on systems where 48-bit is not supported, for not
worsening the system security when virtualization is enabled (as anybody
would probably expect virtualization to improve that). Please see code.

Do we have such systems in the wild? Should we instruct the user to
updating the hypervisor to specific kernel version when they hit the
error?

Regards, Joonas

Quoting Chris Wilson (2018-09-25 14:48:20)

Now that we are confident in providing full-ppgtt where supported,
remove the ability to override the context isolation.

v2: Remove faked aliasing-ppgtt for testing as it no longer is accepted.
v3: s/USES/HAS/ to match usage and reject attempts to load the module on
old GVT-g setups that do not provide support for full-ppgtt.

Signed-off-by: Chris Wilson 
Cc: Joonas Lahtinen 
Cc: Matthew Auld 
---
  drivers/gpu/drm/i915/i915_drv.c   | 22 +++--
  drivers/gpu/drm/i915/i915_drv.h   | 14 +--
  drivers/gpu/drm/i915/i915_gem_context.c   |  2 +-
  drivers/gpu/drm/i915/i915_gem_gtt.c   | 88 ++-
  drivers/gpu/drm/i915/i915_gpu_error.c |  4 +-
  drivers/gpu/drm/i915/i915_params.c|  4 -
  drivers/gpu/drm/i915/i915_params.h|  1 -
  drivers/gpu/drm/i915/i915_pci.c   | 17 ++--
  drivers/gpu/drm/i915/intel_device_info.c  |  6 ++
  drivers/gpu/drm/i915/intel_device_info.h  | 11 ++-
  drivers/gpu/drm/i915/intel_lrc.c  | 13 ++-
  drivers/gpu/drm/i915/selftests/huge_pages.c   | 12 +--
  .../gpu/drm/i915/selftests/i915_gem_context.c | 59 +
  .../gpu/drm/i915/selftests/i915_gem_evict.c   |  2 +-
  drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  4 +-
  15 files changed, 62 insertions(+), 197 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 44e2c0f5ec50..3efbbc71c3b4 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -345,7 +345,7 @@ static int i915_getparam_ioctl(struct drm_device *dev, void 
*data,
 value = HAS_WT(dev_priv);
 break;
 case I915_PARAM_HAS_ALIASING_PPGTT:
-   value = USES_PPGTT(dev_priv);
+   value = INTEL_PPGTT(dev_priv);
 break;
 case I915_PARAM_HAS_SEMAPHORES:
 value = HAS_LEGACY_SEMAPHORES(dev_priv);
@@ -1049,17 +1049,6 @@ static void i915_driver_cleanup_mmio(struct 
drm_i915_private *dev_priv)
  
  static void intel_sanitize_options(struct drm_i915_private *dev_priv)

  {
-   /*
-* i915.enable_ppgtt is read-only, so do an early pass to validate the
-* user's requested state against the hardware/driver capabilities.  We
-* do this now so that we can print out any log messages once rather
-* than every time we check intel_enable_ppgtt().
-*/
-   i915_modparams.enable_ppgtt =
-   intel_sanitize_enable_ppgtt(dev_priv,
-   i915_modparams.enable_ppgtt);
-   DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915_modparams.enable_ppgtt);
-
 intel_gvt_sanitize_options(dev_priv);
  }
  
@@ -1374,6 +1363,15 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
  
 intel_device_info_runtime_init(mkwrite_device_info(dev_priv));
  
+   if (HAS_PPGTT(dev_priv)) {

+   if (intel_vgpu_active(dev_priv) &&
+   !intel_vgpu_has_full_48bit_ppgtt(dev_priv)) {
+   i915_report_error(dev_priv,
+ "incompatible vGPU found, support for 
isolated ppGTT required\n");
+   return -ENXIO;
+   }
+   }
+
 intel_sanitize_options(dev_priv);
  
 i915_perf_init(dev_priv);

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8624b4bdc242..f28b3c2a3cd2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2593,9 +2593,14 @@ intel_info(const struct drm_i915_private *dev_priv)
  
  #define HAS_EXECLISTS(dev_priv) HAS_LOGICAL_RING_CONTEXTS(dev_priv)
  
-#define USES_PPGTT(dev_priv)   (i915_modparams.enable_ppgtt)

-#define USES_FULL_PPGTT(dev_priv)  (i915_modparams.enable_ppgtt >= 2)
-#define USES_FULL_48BIT_PPGTT(dev_priv)(i915_modparams.enable_ppgtt == 
3)
+#define INTEL_PPGTT(dev_priv) (INTEL_INFO(dev_priv)->ppgtt)
+#define HAS_PPGTT(dev_priv) \
+   (INTEL_PPGTT(dev_priv) != INTEL_PPGTT_NONE)
+#define HAS_FULL_PPGTT(dev_priv) \
+   (INTEL_PPGTT(dev_priv) >= INTEL_PPGTT_FULL)
+#define HAS_FULL_48BIT_PPGTT(dev_priv) \
+   (INTEL_PPGTT(dev_priv) >= 

Re: [Intel-gfx] [PULL] gvt-fixes for 4.19-rc5

2018-09-25 Thread Zhi Wang
Thanks for the reminder. :) So much appreciate. :) I just got two small 
code changes which hasn't been tested by QA. So I guess you can send the 
pull request first. Thanks again for the kindly reminding. :)



thanks,

Zhi.


On 09/19/18 02:34, Joonas Lahtinen wrote:

Just a reminder, if you are still planning have gvt-next PR,
tomorrow is your day :)

Regards, Joonas

Quoting Rodrigo Vivi (2018-09-18 18:53:10)

On Tue, Sep 18, 2018 at 03:33:49PM +0800, Zhenyu Wang wrote:

Hi,

Here's more gvt fixes for 4.19. Two more BXT fixes from Colin,
one srcu locking fix and one fix for GGTT clear when destroy vGPU.

pulled, thanks.


p.s, I'll start my vacation from tomorrow. Wang Zhi will cover for gvt pull.

Thanks
--
The following changes since commit 792fab2c0d45758ad3d187bd252570d2bb627fa9:

   drm/i915/gvt: Fix the incorrect length of child_device_config issue 
(2018-09-06 11:17:38 +0800)

are available in the Git repository at:

   https://github.com/intel/gvt-linux.git tags/gvt-fixes-2018-09-18

for you to fetch changes up to 7759ca3aac79648d01c9edcb3b00503c02bec2f5:

   drm/i915/gvt: clear ggtt entries when destroy vgpu (2018-09-18 10:39:44 
+0800)


gvt-fixes-2018-09-18

- Fix initial DPIO PHY register state for BXT (Colin)
- BXT untracked GEN9_CLKGATE_DIS_4 warning fix (Colin)
- Fix srcu lock for GFN valid check (Weinan)
- Should clear GGTT entry value after vGPU destroy (Zhipeng)


Colin Xu (2):
   drm/i915/gvt: Init PHY related registers for BXT
   drm/i915/gvt: Add GEN9_CLKGATE_DIS_4 to default BXT mmio handler

Weinan Li (1):
   drm/i915/gvt: request srcu_read_lock before checking if one gfn is valid

Zhipeng Gong (1):
   drm/i915/gvt: clear ggtt entries when destroy vgpu

  drivers/gpu/drm/i915/gvt/handlers.c |  1 +
  drivers/gpu/drm/i915/gvt/kvmgt.c|  7 ++-
  drivers/gpu/drm/i915/gvt/mmio.c | 28 
  drivers/gpu/drm/i915/gvt/vgpu.c |  1 +
  4 files changed, 36 insertions(+), 1 deletion(-)


--
Open Source Technology Center, Intel ltd.

$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827




___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] Possible use_mm() mis-uses

2018-08-22 Thread Zhi Wang

Hi Linus:

Thanks for letting us know that. We would fix this ASAP. The kvmgt.c 
module is a part of GVT-g code. It's our fault that we didn't find this 
mis-uses, not i915 or KVM guys. Wish they would feel better after seeing 
this message.


Thanks,
Zhi.

On 08/23/18 00:44, Linus Torvalds wrote:

Guys and gals,
  this is a *very* random list of people on the recipients list, but we
had a subtle TLB shootdown issue in the VM, and that brought up some
issues when people then went through the code more carefully.

I think we have a handle on the TLB shootdown bug itself. But when
people were discussing all the possible situations, one thing that
came up was "use_mm()" that takes a mm, and makes it temporarily the
mm for a kernel thread (until "unuse_mm()", duh).

And it turns out that some of those uses are definitely wrong, some of
them are right, and some of them are suspect or at least so overly
complicated that it's hard for the VM people to know if they are ok.

Basically, the rule for "use_mm()" is that the mm in question *has* to
have a valid page table associated with it over the whole use_mm() ->
unuse_mm() sequence. That may sound obvious, and I guess it actually
is so obvious that there isn't even a comment about it, but the actual
users are showing that it's sadly apparently not so obvious after all.

There is one user that uses the "obviously correct" model: the vhost
driver does a "mmget()" and "mmput()" pair around its use of it,
thanks to vhost_dev_set_owner() doing a

 dev->mm = get_task_mm(current);

to look up the mm, and then the teardown case does a

 if (dev->mm)
 mmput(dev->mm);
 dev->mm = NULL;

This is the *right* sequence. A gold star to the vhost people.

Sadly, the vhost people are the only ones who seem to get things
unquestionably right. And some of those gold star people are also
apparently involved in the cases that didn't get things right.

An example of something that *isn't* right, is the i915 kvm interface,
which does

 use_mm(kvm->mm);

on an mm that was initialized in virt/kvm/kvm_main.c using

 mmgrab(current->mm);
 kvm->mm = current->mm;

which is *not* right. Using "mmgrab()" does indeed guarantee the
lifetime of the 'struct mm_struct' itself, but it does *not* guarantee
the lifetime of the page tables. You need to use "mmget()" and
"mmput()", which get the reference to the actual process address
space!

Now, it is *possible* that the kvm use is correct too, because kvm
does register a mmu_notifier chain, and in theory you can avoid the
proper refcounting by just making sure the mmu "release" notifier
kills any existing uses, but I don't really see kvm doing that. Kvm
does register a release notifier, but that just flushes the shadow
page tables, it doesn't kill any use_mm() use by some i915 use case.

So while the vhost use looks right, the kvm/i915 use looks definitely wrong.

The other users of "use_mm()" and "unuse_mm()" are less
black-and-white right vs wrong..

One of the complex ones is the amdgpu driver. It does a
"use_mm(mmptr)" deep deep in the guts of a macro that ends up being
used in fa few places, and it's very hard to tell if it's right.

It looks almost certainly buggy (there is no mmget/mmput to get the
refcount), but there _is_ a "release" mmu_notifier function and that
one - unlike the kvm case - looks like it might actually be trying to
flush the existing pending users of that mm.

But on the whole, I'm suspicious of the amdgpu use. It smells. Jann
Horn pointed out that even if it migth be ok due to the mmu_notifier,
the comments are garbage:


  Where "process" in the uniquely-named "struct queue" is a "struct
  kfd_process"; that struct's definition has this comment in it:

/*
 * Opaque pointer to mm_struct. We don't hold a reference to
 * it so it should never be dereferenced from here. This is
 * only used for looking up processes by their mm.
 */
void *mm;

  So I think either that comment is wrong, or their code is wrong?


so I'm chalking the amdgpu use up in the "broken" column.

It's also actually quite hard to synchronze with some other kernel
worker thread correctly, so just on general principles, if you use
"use_mm()" it really really should be on something that you've
properly gotten a mm refcount on with mmget(). Really. Even if you try
to synchronize things.

The two final cases are two uses in the USB gadget driver. Again, they
don't have the proper mmget/mmput, but they may br ok simply because
the uses are done for AIO, and the VM teardown is preceded by an AIO
teardown, so the proper serialization may come in from that.

Anyway, sorry for the long email, and the big list of participants and
odd mailing lists, but I'd really like people to look at their
"use_mm()" cases, and ask themselves if they have done enough to
guarantee that the full mm exists. Again, "mmgrab()" is *not* enough
on its own. You need either 

[Intel-gfx] [PULL] gvt-next for 4.18

2018-05-13 Thread Zhi Wang

The following changes since commit 0c79f9cb77eae28d48a4f9fc1b3341aacbbd260c:

  drm/i915/gen9: Add WaClearHIZ_WM_CHICKEN3 for bxt and glk (2018-05-13 
10:29:44 +0100)


are available in the git repository at:

  https://github.com/intel/gvt-linux.git tags/gvt-next-2018-05-14

for you to fetch changes up to 41e403d04e7050c8d88682939febcdbe117d4c82:

  Revert "drm/i915/gvt: set max priority for gvt context" (2018-05-14 
05:26:09 +0800)



- Improve the emulation of virtual non-priv register. (Yan)
- Reverse the hack of host of preemption of GVT-g. (Weinan)
- Improve untracked warning message.(Changbin)


Changbin Du (1):
  drm/i915/gvt: Remove disable_warn_untrack and print untracked 
mmio with debug level


Weinan Li (1):
  Revert "drm/i915/gvt: set max priority for gvt context"

Zhao Yan (3):
  drm/i915/gvt: let NOPID be the default value of force_to_nonpriv 
registers
  drm/i915/gvt: do not return error on handling force_to_nonpriv 
registers

  drm/i915/gvt: let force_to_nonpriv cmd handler only valid for LRI cmd

Zhi Wang (1):
  Merge branch 'drm-intel-next-queued' into gvt-next

 drivers/gpu/drm/i915/gvt/cmd_parser.c | 26 +-
 drivers/gpu/drm/i915/gvt/gvt.h|  1 -
 drivers/gpu/drm/i915/gvt/handlers.c   | 35 
++-

 drivers/gpu/drm/i915/gvt/mmio.c   |  2 --
 drivers/gpu/drm/i915/gvt/scheduler.c  |  3 ---
 5 files changed, 39 insertions(+), 28 deletions(-)

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PULL] gvt-next for 4.18

2018-04-24 Thread Zhi Wang

The patch which causes conflict:

---
From 2e8ea2777af45fe651dbd14b8b8e000e94467c24 Mon Sep 17 00:00:00 2001
From: Weinan Li <weinan.z...@intel.com>
Date: Wed, 21 Mar 2018 15:40:32 +0800
Subject: [PATCH] Revert "drm/i915/gvt: set max priority for gvt context"

This reverts commit 11474e9091cf2002e948647fd9f63a7f027e488a.

There are issues which will block the host preemption before, instead of
disabling it use one workaround "setting max priority for gvt context"
to avoid the gvt context be preempted by the host. Now the issues have been
cleared, so revert this patch to enable host preemption.

v2:
- refine description(Zhenyu)

Signed-off-by: Weinan Li <weinan.z...@intel.com>
Signed-off-by: Zhenyu Wang <zhen...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---

has a dependency with the following patch which is missing in git tag 
drm-next-intel-2018-04-13:


---
commit b7268c5eed0ab4f052d614b4b0e3fe8a51c9d5a1
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Wed Apr 18 19:40:52 2018 +0100

drm/i915: Pack params to engine->schedule() into a struct

Today we only want to pass along the priority to 
engine->schedule(), but
in the future we want to have much more control over the various 
aspects

of the GPU during a context's execution, for example controlling the
frequency allowed. As we need an ever growing number of parameters for
scheduling, move those into a struct for convenience.

v2: Move the anonymous struct into its own function for legibility and
ye olde gcc.

Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Link: 
https://patchwork.freedesktop.org/patch/msgid/20180418184052.7129-3-ch...@chris-wilson.co.uk

---

I found it in drm-tip. Looks I have to send another pull request when 
the patch above is in a new drm-intel-next tag.


Thanks for everyone's efforts.

Thanks,
Zhi.

On 04/23/18 16:13, Zhi Wang wrote:

Hi Jani:

I picked out the patch which causes conflicts and may put it back in the 
next back merge from drm-intel-next to gvt-next. So there shouldn't be 
any conflict in this pull. Thanks for your efforts.


Thanks,
Zhi.

On 04/23/18 16:11, Zhi Wang wrote:
The following changes since commit 
fadec6eefe232696c5c471b40df33e6db616e854:


   drm/i915: Update DRIVER_DATE to 20180413 (2018-04-13 12:20:58 +0300)

are available in the git repository at:

   https://github.com/intel/gvt-linux.git tags/gvt-next-2018-04-23

for you to fetch changes up to 3eda0d22ead04f81ea59c9584bcbf5b496745e92:

   drm/i915/gvt: Mark expected switch fall-through in 
handle_g2v_notification (2018-04-23 13:09:36 +0800)



- Minor condition check improvment (Gustavo A. R. Silva)
- Non-priviliged batch buffer scan (Yan Zhao)
- Scheduling optimizations (Zhipeng Gong)


Gustavo A. R. Silva (2):
   drm/i915/gvt/scheduler: Remove unnecessary NULL checks in 
sr_oa_regs
   drm/i915/gvt: Mark expected switch fall-through in 
handle_g2v_notification


Zhao Yan (1):
   drm/i915/gvt: scan non-privileged batch buffer for debug purpose

Zhipeng Gong (2):
   drm/i915/gvt: Use real time to do timer check
   drm/i915/gvt: Update time slice more frequently

  drivers/gpu/drm/i915/gvt/cmd_parser.c   | 55 
---
  drivers/gpu/drm/i915/gvt/debugfs.c  | 67 
+

  drivers/gpu/drm/i915/gvt/gvt.h  |  1 +
  drivers/gpu/drm/i915/gvt/handlers.c |  1 +
  drivers/gpu/drm/i915/gvt/sched_policy.c | 31 ---
  drivers/gpu/drm/i915/gvt/scheduler.c| 66 
+---

  drivers/gpu/drm/i915/gvt/scheduler.h|  1 +
  drivers/gpu/drm/i915/gvt/trace.h| 24 +---
  8 files changed, 193 insertions(+), 53 deletions(-)


___
intel-gvt-dev mailing list
intel-gvt-...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PULL] gvt-next for 4.18

2018-04-23 Thread Zhi Wang

Thanks! :)

On 04/23/18 18:25, Jani Nikula wrote:

On Mon, 23 Apr 2018, Zhi Wang <zhi.a.w...@intel.com> wrote:

Hi Jani:

I picked out the patch which causes conflicts and may put it back in the
next back merge from drm-intel-next to gvt-next. So there shouldn't be
any conflict in this pull. Thanks for your efforts.


Thanks, pulled to drm-intel-next-queued.

Just as a reminder, if you have more stuff for v4.18 the deadline is in
about three weeks.

BR,
Jani.




Thanks,
Zhi.

On 04/23/18 16:11, Zhi Wang wrote:

The following changes since commit
fadec6eefe232696c5c471b40df33e6db616e854:

drm/i915: Update DRIVER_DATE to 20180413 (2018-04-13 12:20:58 +0300)

are available in the git repository at:

https://github.com/intel/gvt-linux.git tags/gvt-next-2018-04-23

for you to fetch changes up to 3eda0d22ead04f81ea59c9584bcbf5b496745e92:

drm/i915/gvt: Mark expected switch fall-through in
handle_g2v_notification (2018-04-23 13:09:36 +0800)


- Minor condition check improvment (Gustavo A. R. Silva)
- Non-priviliged batch buffer scan (Yan Zhao)
- Scheduling optimizations (Zhipeng Gong)


Gustavo A. R. Silva (2):
drm/i915/gvt/scheduler: Remove unnecessary NULL checks in sr_oa_regs
drm/i915/gvt: Mark expected switch fall-through in
handle_g2v_notification

Zhao Yan (1):
drm/i915/gvt: scan non-privileged batch buffer for debug purpose

Zhipeng Gong (2):
drm/i915/gvt: Use real time to do timer check
drm/i915/gvt: Update time slice more frequently

   drivers/gpu/drm/i915/gvt/cmd_parser.c   | 55 ---
   drivers/gpu/drm/i915/gvt/debugfs.c  | 67
+
   drivers/gpu/drm/i915/gvt/gvt.h  |  1 +
   drivers/gpu/drm/i915/gvt/handlers.c |  1 +
   drivers/gpu/drm/i915/gvt/sched_policy.c | 31 ---
   drivers/gpu/drm/i915/gvt/scheduler.c| 66
+---
   drivers/gpu/drm/i915/gvt/scheduler.h|  1 +
   drivers/gpu/drm/i915/gvt/trace.h| 24 +---
   8 files changed, 193 insertions(+), 53 deletions(-)




___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PULL] gvt-next for 4.18

2018-04-23 Thread Zhi Wang

Hi Jani:

I picked out the patch which causes conflicts and may put it back in the 
next back merge from drm-intel-next to gvt-next. So there shouldn't be 
any conflict in this pull. Thanks for your efforts.


Thanks,
Zhi.

On 04/23/18 16:11, Zhi Wang wrote:
The following changes since commit 
fadec6eefe232696c5c471b40df33e6db616e854:


   drm/i915: Update DRIVER_DATE to 20180413 (2018-04-13 12:20:58 +0300)

are available in the git repository at:

   https://github.com/intel/gvt-linux.git tags/gvt-next-2018-04-23

for you to fetch changes up to 3eda0d22ead04f81ea59c9584bcbf5b496745e92:

   drm/i915/gvt: Mark expected switch fall-through in 
handle_g2v_notification (2018-04-23 13:09:36 +0800)



- Minor condition check improvment (Gustavo A. R. Silva)
- Non-priviliged batch buffer scan (Yan Zhao)
- Scheduling optimizations (Zhipeng Gong)


Gustavo A. R. Silva (2):
   drm/i915/gvt/scheduler: Remove unnecessary NULL checks in sr_oa_regs
   drm/i915/gvt: Mark expected switch fall-through in 
handle_g2v_notification


Zhao Yan (1):
   drm/i915/gvt: scan non-privileged batch buffer for debug purpose

Zhipeng Gong (2):
   drm/i915/gvt: Use real time to do timer check
   drm/i915/gvt: Update time slice more frequently

  drivers/gpu/drm/i915/gvt/cmd_parser.c   | 55 ---
  drivers/gpu/drm/i915/gvt/debugfs.c  | 67 
+

  drivers/gpu/drm/i915/gvt/gvt.h  |  1 +
  drivers/gpu/drm/i915/gvt/handlers.c |  1 +
  drivers/gpu/drm/i915/gvt/sched_policy.c | 31 ---
  drivers/gpu/drm/i915/gvt/scheduler.c| 66 
+---

  drivers/gpu/drm/i915/gvt/scheduler.h|  1 +
  drivers/gpu/drm/i915/gvt/trace.h| 24 +---
  8 files changed, 193 insertions(+), 53 deletions(-)


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PULL] gvt-next for 4.18

2018-04-23 Thread Zhi Wang

The following changes since commit fadec6eefe232696c5c471b40df33e6db616e854:

  drm/i915: Update DRIVER_DATE to 20180413 (2018-04-13 12:20:58 +0300)

are available in the git repository at:

  https://github.com/intel/gvt-linux.git tags/gvt-next-2018-04-23

for you to fetch changes up to 3eda0d22ead04f81ea59c9584bcbf5b496745e92:

  drm/i915/gvt: Mark expected switch fall-through in 
handle_g2v_notification (2018-04-23 13:09:36 +0800)



- Minor condition check improvment (Gustavo A. R. Silva)
- Non-priviliged batch buffer scan (Yan Zhao)
- Scheduling optimizations (Zhipeng Gong)


Gustavo A. R. Silva (2):
  drm/i915/gvt/scheduler: Remove unnecessary NULL checks in sr_oa_regs
  drm/i915/gvt: Mark expected switch fall-through in 
handle_g2v_notification


Zhao Yan (1):
  drm/i915/gvt: scan non-privileged batch buffer for debug purpose

Zhipeng Gong (2):
  drm/i915/gvt: Use real time to do timer check
  drm/i915/gvt: Update time slice more frequently

 drivers/gpu/drm/i915/gvt/cmd_parser.c   | 55 ---
 drivers/gpu/drm/i915/gvt/debugfs.c  | 67 
+

 drivers/gpu/drm/i915/gvt/gvt.h  |  1 +
 drivers/gpu/drm/i915/gvt/handlers.c |  1 +
 drivers/gpu/drm/i915/gvt/sched_policy.c | 31 ---
 drivers/gpu/drm/i915/gvt/scheduler.c| 66 
+---

 drivers/gpu/drm/i915/gvt/scheduler.h|  1 +
 drivers/gpu/drm/i915/gvt/trace.h| 24 +---
 8 files changed, 193 insertions(+), 53 deletions(-)

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PULL] gvt-next for 4.17

2018-04-19 Thread Zhi Wang
Weird. I try to apply the patches one by one on 
drm-intel-next-2018-04-13. I didn't get any conflicts... Let me dig more..


On 04/19/18 17:50, Zhi Wang wrote:
Thanks, Let me discuss with Zhenyu about how to deal with this. It must 
be the git rebase I've done which causes the commiter change without new 
signoff-by.


Thanks,
Zhi.

On 04/19/18 17:34, Jani Nikula wrote:

On Thu, 19 Apr 2018, Zhi Wang <zhi.a.w...@intel.com> wrote:

Hi:

Here is the pull request of gvt-next for 4.17 with some new features and
optimizations.

Thanks,
Zhi.

--
The following changes since commit 
fadec6eefe232696c5c471b40df33e6db616e854:


drm/i915: Update DRIVER_DATE to 20180413 (2018-04-13 12:20:58 +0300)

are available in the git repository at:

https://github.com/intel/gvt-linux.git tags/gvt-next-2018-04-19

for you to fetch changes up to c0fb4098fc47dcaeb47085c08d8fafa42fa8e471:

drm/i915/gvt: Mark expected switch fall-through in
handle_g2v_notification (2018-04-19 16:35:55 +0800)


- Minor condition check improvment (Gustavo A. R. Silva)
- Reverting GVT context priority hack (Weinan Li)
- Non-priviliged batch buffer scan (Yan Zhao)
- Scheduling optimizations (Zhipeng Gong)


Gustavo A. R. Silva (2):
drm/i915/gvt/scheduler: Remove unnecessary NULL checks in 
sr_oa_regs

drm/i915/gvt: Mark expected switch fall-through in
handle_g2v_notification

Weinan Li (1):
Revert "drm/i915/gvt: set max priority for gvt context"


This reverts a commit in v4.15. Why is it in a -next pull and not a
-fixes pull?

It also conflicts, please advise how to resolve:

diff --cc drivers/gpu/drm/i915/gvt/scheduler.c
index f3d21849b0cb,080fb5027d9c..
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@@ -1134,9 -1156,6 +1156,12 @@@ int intel_vgpu_setup_submission(struct
 if (IS_ERR(s->shadow_ctx))
 return PTR_ERR(s->shadow_ctx);
++<<<<<<< HEAD
  +  if (HAS_LOGICAL_RING_PREEMPTION(vgpu->gvt->dev_priv))
  +  s->shadow_ctx->sched.priority = INT_MAX;
  +
++===
++>>>>>>> c2f6410ef67740ebcbf5d92dffc2679d4a0e288c
 bitmap_zero(s->shadow_ctx_desc_updated, I915_NUM_ENGINES);
 s->workloads = kmem_cache_create_usercopy("gvt-g_vgpu_workload",

Finally, it's committed by Zhi Wang <zhi.a.w...@intel.com> but without
his Signed-off-by.


BR,
Jani.




Zhao Yan (1):
drm/i915/gvt: scan non-privileged batch buffer for debug purpose

Zhipeng Gong (2):
drm/i915/gvt: Use real time to do timer check
drm/i915/gvt: Update time slice more frequently

   drivers/gpu/drm/i915/gvt/cmd_parser.c   | 55 
+++---

   drivers/gpu/drm/i915/gvt/debugfs.c  | 67

   drivers/gpu/drm/i915/gvt/gvt.h  |  1 +
   drivers/gpu/drm/i915/gvt/handlers.c |  1 +
   drivers/gpu/drm/i915/gvt/sched_policy.c | 31 ---
   drivers/gpu/drm/i915/gvt/scheduler.c| 69
+
   drivers/gpu/drm/i915/gvt/scheduler.h|  1 +
   drivers/gpu/drm/i915/gvt/trace.h| 24 +---
   8 files changed, 193 insertions(+), 56 deletions(-)



___
intel-gvt-dev mailing list
intel-gvt-...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PULL] gvt-next for 4.17

2018-04-19 Thread Zhi Wang
Thanks, Let me discuss with Zhenyu about how to deal with this. It must 
be the git rebase I've done which causes the commiter change without new 
signoff-by.


Thanks,
Zhi.

On 04/19/18 17:34, Jani Nikula wrote:

On Thu, 19 Apr 2018, Zhi Wang <zhi.a.w...@intel.com> wrote:

Hi:

Here is the pull request of gvt-next for 4.17 with some new features and
optimizations.

Thanks,
Zhi.

--
The following changes since commit fadec6eefe232696c5c471b40df33e6db616e854:

drm/i915: Update DRIVER_DATE to 20180413 (2018-04-13 12:20:58 +0300)

are available in the git repository at:

https://github.com/intel/gvt-linux.git tags/gvt-next-2018-04-19

for you to fetch changes up to c0fb4098fc47dcaeb47085c08d8fafa42fa8e471:

drm/i915/gvt: Mark expected switch fall-through in
handle_g2v_notification (2018-04-19 16:35:55 +0800)


- Minor condition check improvment (Gustavo A. R. Silva)
- Reverting GVT context priority hack (Weinan Li)
- Non-priviliged batch buffer scan (Yan Zhao)
- Scheduling optimizations (Zhipeng Gong)


Gustavo A. R. Silva (2):
drm/i915/gvt/scheduler: Remove unnecessary NULL checks in sr_oa_regs
drm/i915/gvt: Mark expected switch fall-through in
handle_g2v_notification

Weinan Li (1):
Revert "drm/i915/gvt: set max priority for gvt context"


This reverts a commit in v4.15. Why is it in a -next pull and not a
-fixes pull?

It also conflicts, please advise how to resolve:

diff --cc drivers/gpu/drm/i915/gvt/scheduler.c
index f3d21849b0cb,080fb5027d9c..
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@@ -1134,9 -1156,6 +1156,12 @@@ int intel_vgpu_setup_submission(struct
 if (IS_ERR(s->shadow_ctx))
 return PTR_ERR(s->shadow_ctx);
   
++<<<<<<< HEAD

  +  if (HAS_LOGICAL_RING_PREEMPTION(vgpu->gvt->dev_priv))
  +  s->shadow_ctx->sched.priority = INT_MAX;
  +
++===
++>>>>>>> c2f6410ef67740ebcbf5d92dffc2679d4a0e288c
 bitmap_zero(s->shadow_ctx_desc_updated, I915_NUM_ENGINES);
   
 s->workloads = kmem_cache_create_usercopy("gvt-g_vgpu_workload",


Finally, it's committed by Zhi Wang <zhi.a.w...@intel.com> but without
his Signed-off-by.


BR,
Jani.




Zhao Yan (1):
drm/i915/gvt: scan non-privileged batch buffer for debug purpose

Zhipeng Gong (2):
drm/i915/gvt: Use real time to do timer check
drm/i915/gvt: Update time slice more frequently

   drivers/gpu/drm/i915/gvt/cmd_parser.c   | 55 +++---
   drivers/gpu/drm/i915/gvt/debugfs.c  | 67

   drivers/gpu/drm/i915/gvt/gvt.h  |  1 +
   drivers/gpu/drm/i915/gvt/handlers.c |  1 +
   drivers/gpu/drm/i915/gvt/sched_policy.c | 31 ---
   drivers/gpu/drm/i915/gvt/scheduler.c| 69
+
   drivers/gpu/drm/i915/gvt/scheduler.h|  1 +
   drivers/gpu/drm/i915/gvt/trace.h| 24 +---
   8 files changed, 193 insertions(+), 56 deletions(-)



___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PULL] gvt-next for 4.17

2018-04-19 Thread Zhi Wang

Sorry it's gvt-next, so it should be for 4.18.

Thanks,
Zhi.

On 04/19/18 17:17, Zhi Wang wrote:

Hi:

Here is the pull request of gvt-next for 4.17 with some new features and 
optimizations.


Thanks,
Zhi.

--
The following changes since commit 
fadec6eefe232696c5c471b40df33e6db616e854:


   drm/i915: Update DRIVER_DATE to 20180413 (2018-04-13 12:20:58 +0300)

are available in the git repository at:

   https://github.com/intel/gvt-linux.git tags/gvt-next-2018-04-19

for you to fetch changes up to c0fb4098fc47dcaeb47085c08d8fafa42fa8e471:

   drm/i915/gvt: Mark expected switch fall-through in 
handle_g2v_notification (2018-04-19 16:35:55 +0800)



- Minor condition check improvment (Gustavo A. R. Silva)
- Reverting GVT context priority hack (Weinan Li)
- Non-priviliged batch buffer scan (Yan Zhao)
- Scheduling optimizations (Zhipeng Gong)


Gustavo A. R. Silva (2):
   drm/i915/gvt/scheduler: Remove unnecessary NULL checks in sr_oa_regs
   drm/i915/gvt: Mark expected switch fall-through in 
handle_g2v_notification


Weinan Li (1):
   Revert "drm/i915/gvt: set max priority for gvt context"

Zhao Yan (1):
   drm/i915/gvt: scan non-privileged batch buffer for debug purpose

Zhipeng Gong (2):
   drm/i915/gvt: Use real time to do timer check
   drm/i915/gvt: Update time slice more frequently

  drivers/gpu/drm/i915/gvt/cmd_parser.c   | 55 +++---
  drivers/gpu/drm/i915/gvt/debugfs.c  | 67 


  drivers/gpu/drm/i915/gvt/gvt.h  |  1 +
  drivers/gpu/drm/i915/gvt/handlers.c |  1 +
  drivers/gpu/drm/i915/gvt/sched_policy.c | 31 ---
  drivers/gpu/drm/i915/gvt/scheduler.c| 69 
+

  drivers/gpu/drm/i915/gvt/scheduler.h|  1 +
  drivers/gpu/drm/i915/gvt/trace.h| 24 +---
  8 files changed, 193 insertions(+), 56 deletions(-)
___
intel-gvt-dev mailing list
intel-gvt-...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PULL] gvt-next for 4.17

2018-04-19 Thread Zhi Wang

Hi:

Here is the pull request of gvt-next for 4.17 with some new features and 
optimizations.


Thanks,
Zhi.

--
The following changes since commit fadec6eefe232696c5c471b40df33e6db616e854:

  drm/i915: Update DRIVER_DATE to 20180413 (2018-04-13 12:20:58 +0300)

are available in the git repository at:

  https://github.com/intel/gvt-linux.git tags/gvt-next-2018-04-19

for you to fetch changes up to c0fb4098fc47dcaeb47085c08d8fafa42fa8e471:

  drm/i915/gvt: Mark expected switch fall-through in 
handle_g2v_notification (2018-04-19 16:35:55 +0800)



- Minor condition check improvment (Gustavo A. R. Silva)
- Reverting GVT context priority hack (Weinan Li)
- Non-priviliged batch buffer scan (Yan Zhao)
- Scheduling optimizations (Zhipeng Gong)


Gustavo A. R. Silva (2):
  drm/i915/gvt/scheduler: Remove unnecessary NULL checks in sr_oa_regs
  drm/i915/gvt: Mark expected switch fall-through in 
handle_g2v_notification


Weinan Li (1):
  Revert "drm/i915/gvt: set max priority for gvt context"

Zhao Yan (1):
  drm/i915/gvt: scan non-privileged batch buffer for debug purpose

Zhipeng Gong (2):
  drm/i915/gvt: Use real time to do timer check
  drm/i915/gvt: Update time slice more frequently

 drivers/gpu/drm/i915/gvt/cmd_parser.c   | 55 +++---
 drivers/gpu/drm/i915/gvt/debugfs.c  | 67 


 drivers/gpu/drm/i915/gvt/gvt.h  |  1 +
 drivers/gpu/drm/i915/gvt/handlers.c |  1 +
 drivers/gpu/drm/i915/gvt/sched_policy.c | 31 ---
 drivers/gpu/drm/i915/gvt/scheduler.c| 69 
+

 drivers/gpu/drm/i915/gvt/scheduler.h|  1 +
 drivers/gpu/drm/i915/gvt/trace.h| 24 +---
 8 files changed, 193 insertions(+), 56 deletions(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] The behavior of i915_wait_request() after calling i915_gem_suspend_request()

2018-03-27 Thread Zhi Wang

Hi Chris and Joonas:
Thanks for the discussion in the IRC for the suspend/resume request 
APIs. I just a bit curious about the behavior of i915_wait_request() 
after a caller suspend an i915 request. Will the caller of 
i915_wait_request() be woken up at this time? or not? This behavior 
decides how we are going to use those APIs. :)


Thanks again for the discussion and efforts. :)

Thanks,
Zhi.
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PULL] gvt-next-fixes for 4.16

2018-02-06 Thread Zhi Wang

Hi guys:
Here are the latest gvt-next-fixes pull. It contains vGPU reset 
enhancement, which refines vGPU reset flow and the support of virtual 
aperture read/write when x-no-mmap=on is set in KVM, which is required 
by a test case from Redhat and also another fix for virtual OpRegion.


Thanks,
Zhi.

The following changes since commit 751b01cb07ebf0dbbe4a4fbfeaa509388e4a2b0a:

  drm/i915/ppgtt: Pin page directories before allocation (2018-02-01 
07:33:04 -0800)


are available in the git repository at:

  http://github.com/intel/gvt-linux.git tags/gvt-next-fixes-2018-02-04

for you to fetch changes up to 47419494f216812b42f5d1c5a2984cd46253b4cc:

  drm/i915/gvt: Use KVM r/w to access guest opregion (2018-02-06 
13:14:47 +0800)



- vGPU reset refinement. (Weinan)
- Support aperture read/write emulation when x-no-mmap=on. (Changbin)
- Use guest memory read/write in GVT MPT to access OpRegion. (Tina)


Changbin Du (1):
  drm/i915/gvt: Fix aperture read/write emulation when enable 
x-no-mmap=on


Tina Zhang (1):
  drm/i915/gvt: Use KVM r/w to access guest opregion

Weinan Li (2):
  drm/i915/gvt: refine intel_vgpu_submission_ops as per engine ops
  drm/i915/gvt: only reset execlist state of one engine during VM 
engine reset


 drivers/gpu/drm/i915/gvt/cfg_space.c| 15 +
 drivers/gpu/drm/i915/gvt/execlist.c | 22 
 drivers/gpu/drm/i915/gvt/gvt.h  |  6 +-
 drivers/gpu/drm/i915/gvt/handlers.c |  7 +--
 drivers/gpu/drm/i915/gvt/kvmgt.c| 36 +++-
 drivers/gpu/drm/i915/gvt/mmio.c | 42 --
 drivers/gpu/drm/i915/gvt/opregion.c | 98 
+++--

 drivers/gpu/drm/i915/gvt/sched_policy.c | 14 -
 drivers/gpu/drm/i915/gvt/scheduler.c| 19 ---
 drivers/gpu/drm/i915/gvt/scheduler.h|  1 +
 drivers/gpu/drm/i915/gvt/vgpu.c |  3 +-
 11 files changed, 144 insertions(+), 119 deletions(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [GIT PULL] gvt fix for 4.14-rc6

2017-10-26 Thread Zhi Wang

Hi:
Here are some fixes for 4.14-rc6. Zhenyu's patch fixes the 
per_ctx_bb check in GVT-g since the usage of per_ctx_bb in i915 has been 
changed recently. Another two patches from Xiong fix the GPU hang of 
linxu guest when it's running large workload.


Thanks,
Zhi.

The following changes since commit 7277f755048da562eb2489becacd38d0d05e1e06:

  drm/i915/perf: fix perf enable/disable ioctls with 32bits userspace 
(2017-10-25 08:16:13 -0700)


are available in the git repository at:

  https://github.com/intel/gvt-linux.git tags/gvt-fixes-2017-10-26

for you to fetch changes up to d928347d52b5a1d3cee4e4ccf45d4ae1563cfb6f:

  drm/i915/gvt: Adding ACTHD mmio read handler (2017-10-27 01:39:02 +0800)


Xiong Zhang (2):
  drm/i915/gvt: Extract mmio_read_from_hw() common function
  drm/i915/gvt: Adding ACTHD mmio read handler

Zhenyu Wang (1):
  drm/i915/gvt: properly check per_ctx bb valid state

Zhi Wang (1):
  drm/i915/gvt: Refine MMIO_RING_F()

 drivers/gpu/drm/i915/gvt/cmd_parser.c |  3 ++
 drivers/gpu/drm/i915/gvt/execlist.c   |  3 +-
 drivers/gpu/drm/i915/gvt/handlers.c   | 70 
+--

 drivers/gpu/drm/i915/gvt/reg.h|  3 --
 drivers/gpu/drm/i915/gvt/scheduler.h  |  1 +
 5 files changed, 15 insertions(+), 65 deletions(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915/gvt: use ARRAY_SIZE

2017-10-23 Thread Zhi Wang

Thanks, applied!

On 10/16/17 10:32, Jérémy Lefaure wrote:

Using the ARRAY_SIZE macro improves the readability of the code. Also,
it's useless to use a variable to store this constant calculated at
compile time.

Found with Coccinelle with the following semantic patch:
@r depends on (org || report)@
type T;
T[] E;
position p;
@@
(
  (sizeof(E)@p /sizeof(*E))
|
  (sizeof(E)@p /sizeof(E[...]))
|
  (sizeof(E)@p /sizeof(T))
)

Signed-off-by: Jérémy Lefaure 
---
This patch was part of a bigger patch [1].

[1]: https://patchwork.kernel.org/patch/9979843/

  drivers/gpu/drm/i915/gvt/vgpu.c | 9 -
  1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 02c61a1ad56a..b32c1c889ea8 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -31,6 +31,7 @@
   *
   */
  
+#include 

  #include "i915_drv.h"
  #include "gvt.h"
  #include "i915_pvinfo.h"
@@ -98,7 +99,6 @@ static struct {
   */
  int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
  {
-   unsigned int num_types;
unsigned int i, low_avail, high_avail;
unsigned int min_low;
  
@@ -116,15 +116,14 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)

 */
low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE;
high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE;
-   num_types = sizeof(vgpu_types) / sizeof(vgpu_types[0]);
  
-	gvt->types = kzalloc(num_types * sizeof(struct intel_vgpu_type),

-GFP_KERNEL);
+   gvt->types = kzalloc(ARRAY_SIZE(vgpu_types) *
+sizeof(struct intel_vgpu_type), GFP_KERNEL);
if (!gvt->types)
return -ENOMEM;
  
  	min_low = MB_TO_BYTES(32);

-   for (i = 0; i < num_types; ++i) {
+   for (i = 0; i < ARRAY_SIZE(vgpu_types); ++i) {
if (low_avail / vgpu_types[i].low_mm == 0)
break;
  


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915/gvt: Clean up dead code in cmd_parser

2017-10-23 Thread Zhi Wang

Thanks, applied! :)

On 10/16/17 06:32, Christos Gkekas wrote:

Delete variables 'gma_bottom' that are set but never used.

Signed-off-by: Christos Gkekas 
---
  drivers/gpu/drm/i915/gvt/cmd_parser.c | 6 ++
  1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c 
b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index 2c0ccbb..d75ce70 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -2511,7 +2511,7 @@ static int command_scan(struct parser_exec_state *s,
  
  static int scan_workload(struct intel_vgpu_workload *workload)

  {
-   unsigned long gma_head, gma_tail, gma_bottom;
+   unsigned long gma_head, gma_tail;
struct parser_exec_state s;
int ret = 0;
  
@@ -2521,7 +2521,6 @@ static int scan_workload(struct intel_vgpu_workload *workload)
  
  	gma_head = workload->rb_start + workload->rb_head;

gma_tail = workload->rb_start + workload->rb_tail;
-   gma_bottom = workload->rb_start +  _RING_CTL_BUF_SIZE(workload->rb_ctl);
  
  	s.buf_type = RING_BUFFER_INSTRUCTION;

s.buf_addr_type = GTT_BUFFER;
@@ -2557,7 +2556,7 @@ static int scan_workload(struct intel_vgpu_workload 
*workload)
  static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
  {
  
-	unsigned long gma_head, gma_tail, gma_bottom, ring_size, ring_tail;

+   unsigned long gma_head, gma_tail, ring_size, ring_tail;
struct parser_exec_state s;
int ret = 0;
struct intel_vgpu_workload *workload = container_of(wa_ctx,
@@ -2573,7 +2572,6 @@ static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
PAGE_SIZE);
gma_head = wa_ctx->indirect_ctx.guest_gma;
gma_tail = wa_ctx->indirect_ctx.guest_gma + ring_tail;
-   gma_bottom = wa_ctx->indirect_ctx.guest_gma + ring_size;
  
  	s.buf_type = RING_BUFFER_INSTRUCTION;

s.buf_addr_type = GTT_BUFFER;


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [GIT PULL] gvt fix for 4.14-rc5

2017-10-16 Thread Zhi Wang

Hi:

Here is a fix of one bug for 4.14-rc5 which fixes a GPU hang after 
resuing one vGPU across different guest OSes.


Thanks.

---

The following changes since commit ea850f64c2722278f150dc11de2141baeb24211c:

  drm/i915/bios: parse DDI ports also for CHV for HDMI DDC pin and DP 
AUX channel (2017-10-11 10:32:57 -0700)


are available in the git repository at:

  https://github.com/01org/gvt-linux.git tags/gvt-fixes-2017-10-16

for you to fetch changes up to ba3ee00683bc2dad4c14fba805c2241ae23acff9:

  drm/i915/gvt: Fix GPU hang after reusing vGPU instance across 
different guest OS (2017-10-17 00:44:10 +0800)



Changbin Du (1):
  drm/i915/gvt: Fix GPU hang after reusing vGPU instance across 
different guest OS


 drivers/gpu/drm/i915/gvt/sched_policy.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 00/18] use ARRAY_SIZE macro

2017-10-02 Thread Zhi Wang
Thanks for the patch! :)

2017-10-01 22:30 GMT+03:00 Jérémy Lefaure :

> Hi everyone,
> Using ARRAY_SIZE improves the code readability. I used coccinelle (I
> made a change to the array_size.cocci file [1]) to find several places
> where ARRAY_SIZE could be used instead of other macros or sizeof
> division.
>
> I tried to divide the changes into a patch per subsystem (excepted for
> staging). If one of the patch should be split into several patches, let
> me know.
>
> In order to reduce the size of the To: and Cc: lines, each patch of the
> series is sent only to the maintainers and lists concerned by the patch.
> This cover letter is sent to every list concerned by this series.
>
> This series is based on linux-next next-20170929. Each patch has been
> tested by building the relevant files with W=1.
>
> This series contains the following patches:
> [PATCH 01/18] sound: use ARRAY_SIZE
> [PATCH 02/18] tracing/filter: use ARRAY_SIZE
> [PATCH 03/18] media: use ARRAY_SIZE
> [PATCH 04/18] IB/mlx5: Use ARRAY_SIZE
> [PATCH 05/18] net: use ARRAY_SIZE
> [PATCH 06/18] drm: use ARRAY_SIZE
> [PATCH 07/18] scsi: bfa: use ARRAY_SIZE
> [PATCH 08/18] ecryptfs: use ARRAY_SIZE
> [PATCH 09/18] nfsd: use ARRAY_SIZE
> [PATCH 10/18] orangefs: use ARRAY_SIZE
> [PATCH 11/18] dm space map metadata: use ARRAY_SIZE
> [PATCH 12/18] x86: use ARRAY_SIZE
> [PATCH 13/18] tpm: use ARRAY_SIZE
> [PATCH 14/18] ipmi: use ARRAY_SIZE
> [PATCH 15/18] acpi: use ARRAY_SIZE
> [PATCH 16/18] media: staging: atomisp: use ARRAY_SIZE
> [PATCH 17/18] staging: rtl8723bs: use ARRAY_SIZE
> [PATCH 18/18] staging: rtlwifi: use ARRAY_SIZE
>
>
> [1]: https://lkml.org/lkml/2017/9/13/689
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v18 1/2] drm/i915: Do not allocate unused PPAT entries

2017-09-21 Thread Zhi Wang
Only PPAT entries 0/2/3/4 are using. Remove extra PPAT entry allocation
during initialization.

v17:

- Refine ppat_index() and move the comments. (Joonas)

v8:

- Move ppat_index() into i915_gem_gtt.c. (Chris)
- Change the name of ppat_bits_to_index to ppat_index.

Suggested-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 52 ++---
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 731ce22..43e0d23 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -230,9 +230,11 @@ static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
 
switch (level) {
case I915_CACHE_NONE:
+   /* Uncached objects, mostly for scanout */
pte |= PPAT_UNCACHED;
break;
case I915_CACHE_WT:
+   /* for scanout with eLLC */
pte |= PPAT_DISPLAY_ELLC;
break;
default:
@@ -249,6 +251,7 @@ static gen8_pde_t gen8_pde_encode(const dma_addr_t addr,
gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
pde |= addr;
if (level != I915_CACHE_NONE)
+   /* for normal objects, no eLLC */
pde |= PPAT_CACHED_PDE;
else
pde |= PPAT_UNCACHED;
@@ -2988,6 +2991,14 @@ static unsigned int chv_private_pat_match(u8 src, u8 dst)
INTEL_PPAT_PERFECT_MATCH : 0;
 }
 
+/* PPAT index = 4 * PAT + 2 * PCD + PWT */
+static inline unsigned int ppat_index(unsigned int bits)
+{
+   return (4 * !!(bits & _PAGE_PAT) +
+   2 * !!(bits & _PAGE_PCD) +
+   !!(bits & _PAGE_PWT));
+}
+
 static void cnl_setup_private_ppat(struct intel_ppat *ppat)
 {
ppat->max_entries = 8;
@@ -2997,18 +3008,14 @@ static void cnl_setup_private_ppat(struct intel_ppat 
*ppat)
 
/* XXX: spec is unclear if this is still needed for CNL+ */
if (!USES_PPGTT(ppat->i915)) {
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), 
GEN8_PPAT_UC);
return;
}
 
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC);
-   __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);
-   __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);
-   __alloc_ppat_entry(ppat, 3, GEN8_PPAT_UC);
-   __alloc_ppat_entry(ppat, 4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(0));
-   __alloc_ppat_entry(ppat, 5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(1));
-   __alloc_ppat_entry(ppat, 6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(2));
-   __alloc_ppat_entry(ppat, 7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(3));
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), GEN8_PPAT_WB | 
GEN8_PPAT_LLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_DISPLAY_ELLC), GEN8_PPAT_WT | 
GEN8_PPAT_LLCELLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_UNCACHED), GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED), GEN8_PPAT_WB | 
GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0));
 }
 
 /* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability
@@ -3035,18 +3042,14 @@ static void bdw_setup_private_ppat(struct intel_ppat 
*ppat)
 * So we can still hold onto all our assumptions wrt cpu
 * clflushing on LLC machines.
 */
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), 
GEN8_PPAT_UC);
return;
}
 
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC);  /* for 
normal objects, no eLLC */
-   __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);  /* for 
something pointing to ptes? */
-   __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);  /* for 
scanout with eLLC */
-   __alloc_ppat_entry(ppat, 3, GEN8_PPAT_UC);  /* 
Uncached objects, mostly for scanout */
-   __alloc_ppat_entry(ppat, 4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(0));
-   __alloc_ppat_entry(ppat, 5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(1));
-   __alloc_ppat_entry(ppat, 6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(2));
-   __alloc_ppat_entry(ppat, 7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(3));
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), GEN8_PPAT_WB | 
GEN8_PPAT_LLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_DISPLAY_ELLC), GEN8_PPA

[Intel-gfx] [PATCH v18 2/2] drm/i915/selftests: Introduce live tests of private PAT management

2017-09-21 Thread Zhi Wang
Introduce two live tests of private PAT management:

igt_ppat_init - This test is to check if all the PPAT configurations are
written into HW.

igt_ppat_get - This test performs several sub-tests on intel_ppat_get()
and intel_ppat_put().

The "perfect match" test case will try to get a PPAT entry with an existing
value, then check if the returned PPAT entry is the same one.

The "alloc entries" test case will run out of PPAT table, and check if all
the requested values are put into the newly allocated PPAT entries.

The negative test case will try to generate a new PPAT value, and get it
when PPAT table is full.

The "partial match" test case will generate a parital matched value from
the existing PPAT table and try to match it.

The "re-alloc" test case will try to free and then allocate a new entry
when the PPAT table is full.

The "put entries" test case will free all the PPAT entries that allocated
in "alloc entries" test case. It will check if the values of freed PPAT
entries turn into ppat->clear_value.

v18:

- Refine the test to catch a corner case.

v10:

- Refine code structure.
- Introduce "re-alloc" test case. (Chris)

v9:

- Refine generate_new_value(). (Chris)
- Refine failure output. (Chris)
- Refine test flow of "perfect match". (Chris)
- Introduce another negative test case after "partial match". (Chris)

v8:

- Remove noisy output. (Chris)
- Add negative test case. (Chris)

Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 372 ++
 1 file changed, 372 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 6b132ca..75cb2d6 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -1094,6 +1094,376 @@ static int igt_ggtt_page(void *arg)
return err;
 }
 
+static int check_cnl_ppat(struct drm_i915_private *dev_priv)
+{
+   struct intel_ppat *ppat = _priv->ppat;
+   int i;
+
+   for (i = 0; i < ppat->max_entries; i++) {
+   u32 value = I915_READ(GEN10_PAT_INDEX(i));
+
+   if (value != ppat->entries[i].value) {
+   pr_err("check PPAT failed: expected %x found %x\n",
+   ppat->entries[i].value, value);
+   return -EINVAL;
+   }
+   }
+   return 0;
+}
+
+static int check_bdw_ppat(struct drm_i915_private *dev_priv)
+{
+   struct intel_ppat *ppat = _priv->ppat;
+   u64 pat, hw_pat;
+   int i;
+
+   pat = hw_pat = 0;
+
+   for (i = 0; i < ppat->max_entries; i++)
+   pat |= GEN8_PPAT(i, ppat->entries[i].value);
+
+   hw_pat = I915_READ(GEN8_PRIVATE_PAT_HI);
+   hw_pat <<= 32;
+   hw_pat |= I915_READ(GEN8_PRIVATE_PAT_LO);
+
+   if (pat != hw_pat) {
+   pr_err("check PPAT failed: expected %llx found %llx\n",
+   pat, hw_pat);
+   return -EINVAL;
+   }
+   return 0;
+}
+
+static int igt_ppat_check(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   int ret;
+
+   if (!i915->ppat.max_entries)
+   return 0;
+
+   if (INTEL_GEN(i915) >= 10)
+   ret = check_cnl_ppat(i915);
+   else
+   ret = check_bdw_ppat(i915);
+
+   if (ret)
+   pr_err("check PPAT failed\n");
+
+   return ret;
+}
+
+static bool value_is_new(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   for_each_set_bit(i, ppat->used, ppat->max_entries) {
+   if (value != ppat->entries[i].value)
+   continue;
+
+   return false;
+   }
+   return true;
+}
+
+static bool value_for_partial_test(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   if (!value_is_new(ppat, value))
+   return false;
+
+   /*
+* At least, there should be one entry whose cache attribute is
+* same with the required value.
+*/
+   for_each_set_bit(i, ppat->used, ppat->max_entries) {
+   if (GEN8_PPAT_GET_CA(value) !=
+   GEN8_PPAT_GET_CA(ppat->entries[i].value))
+   continue;
+
+   return true;
+   }
+   return false;
+}
+
+static bool value_for_negative_test(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   if (!value_is_new(ppat, value))
+   return false;
+
+   /*
+* cache attribute has to be different, so i915_ppat_get() would
+ 

[Intel-gfx] [PATCH] drm/i915: Return the correct score in i915_ppat_get()

2017-09-21 Thread Zhi Wang
The cache attribute of the required entry has to be the same with the
existing value. After this requirement is met, the futher comparison
should be performed. After this fix, the refined test case can pass.

v2:

- Refine the tittle and comments. (Rodrigo)

Fixes: 4395890a4855 ("drm/i915: Introduce private PAT management")
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 5923b51..636ad7d 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2965,7 +2965,7 @@ static unsigned int bdw_private_pat_match(u8 src, u8 dst)
};
 
/* Cache attribute has to be matched. */
-   if (GEN8_PPAT_GET_CA(src) == GEN8_PPAT_GET_CA(dst))
+   if (GEN8_PPAT_GET_CA(src) != GEN8_PPAT_GET_CA(dst))
return 0;
 
score |= CA_MATCH;
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/2] drm/i915/selftests: Refine the i915_ppat_get test case

2017-09-21 Thread Zhi Wang
Refine the i915_ppat_get test case to catch a bug recently intrduced by
me. If the PPAT page table is filled first, then there will be PPAT
entries which has the same attributes with another one. If we try to
get our entry at this time. Tested on my SKL NUC box.

Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 28 +++
 1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index cd7eeb6..75cb2d6 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -1284,7 +1284,7 @@ static int perform_perfect_match_test(struct intel_ppat 
*ppat)
 {
struct drm_i915_private *i915 = ppat->i915;
const struct intel_ppat_entry *entry;
-   int ret, i;
+   int i;
 
for_each_set_bit(i, ppat->used, ppat->max_entries) {
entry = intel_ppat_get(i915, ppat->entries[i].value);
@@ -1296,9 +1296,7 @@ static int perform_perfect_match_test(struct intel_ppat 
*ppat)
intel_ppat_put(entry);
return -EINVAL;
}
-   ret = put_and_check_entry(entry);
-   if (ret)
-   return ret;
+   intel_ppat_put(entry);
}
return 0;
 }
@@ -1328,7 +1326,6 @@ static int perform_partial_match_test(struct intel_ppat 
*ppat)
struct drm_i915_private *i915 = ppat->i915;
const struct intel_ppat_entry *entry;
u8 value;
-   int ret;
 
value = generate_new_value(ppat, value_for_partial_test);
if (!value) {
@@ -1350,10 +1347,7 @@ static int perform_partial_match_test(struct intel_ppat 
*ppat)
return -EINVAL;
}
 
-   ret = put_and_check_entry(entry);
-   if (ret)
-   return ret;
-
+   intel_ppat_put(entry);
return 0;
 }
 
@@ -1373,14 +1367,7 @@ static int igt_ppat_get(void *arg)
if (ret)
return ret;
 
-   /* case 1: perfect match */
-   ret = perform_perfect_match_test(ppat);
-   if (ret) {
-   pr_err("fail on perfect match test\n");
-   return ret;
-   }
-
-   /* case 2: alloc new entries */
+   /* case 1: alloc new entries */
entries = NULL;
ret = 0;
 
@@ -1407,6 +1394,13 @@ static int igt_ppat_get(void *arg)
*p = entry;
}
 
+   /* case 2: perfect match */
+   ret = perform_perfect_match_test(ppat);
+   if (ret) {
+   pr_err("fail on perfect match test\n");
+   return ret;
+   }
+
/* case 3: negative test 1, suppose PPAT table is full now */
ret = perform_negative_test(ppat);
if (ret) {
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v18 1/2] drm/i915: Do not allocate unused PPAT entries

2017-09-21 Thread Zhi Wang
Only PPAT entries 0/2/3/4 are using. Remove extra PPAT entry allocation
during initialization.

v17:

- Refine ppat_index() and move the comments. (Joonas)

v8:

- Move ppat_index() into i915_gem_gtt.c. (Chris)
- Change the name of ppat_bits_to_index to ppat_index.

Suggested-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 52 ++---
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 731ce22..43e0d23 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -230,9 +230,11 @@ static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
 
switch (level) {
case I915_CACHE_NONE:
+   /* Uncached objects, mostly for scanout */
pte |= PPAT_UNCACHED;
break;
case I915_CACHE_WT:
+   /* for scanout with eLLC */
pte |= PPAT_DISPLAY_ELLC;
break;
default:
@@ -249,6 +251,7 @@ static gen8_pde_t gen8_pde_encode(const dma_addr_t addr,
gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
pde |= addr;
if (level != I915_CACHE_NONE)
+   /* for normal objects, no eLLC */
pde |= PPAT_CACHED_PDE;
else
pde |= PPAT_UNCACHED;
@@ -2988,6 +2991,14 @@ static unsigned int chv_private_pat_match(u8 src, u8 dst)
INTEL_PPAT_PERFECT_MATCH : 0;
 }
 
+/* PPAT index = 4 * PAT + 2 * PCD + PWT */
+static inline unsigned int ppat_index(unsigned int bits)
+{
+   return (4 * !!(bits & _PAGE_PAT) +
+   2 * !!(bits & _PAGE_PCD) +
+   !!(bits & _PAGE_PWT));
+}
+
 static void cnl_setup_private_ppat(struct intel_ppat *ppat)
 {
ppat->max_entries = 8;
@@ -2997,18 +3008,14 @@ static void cnl_setup_private_ppat(struct intel_ppat 
*ppat)
 
/* XXX: spec is unclear if this is still needed for CNL+ */
if (!USES_PPGTT(ppat->i915)) {
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), 
GEN8_PPAT_UC);
return;
}
 
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC);
-   __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);
-   __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);
-   __alloc_ppat_entry(ppat, 3, GEN8_PPAT_UC);
-   __alloc_ppat_entry(ppat, 4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(0));
-   __alloc_ppat_entry(ppat, 5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(1));
-   __alloc_ppat_entry(ppat, 6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(2));
-   __alloc_ppat_entry(ppat, 7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(3));
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), GEN8_PPAT_WB | 
GEN8_PPAT_LLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_DISPLAY_ELLC), GEN8_PPAT_WT | 
GEN8_PPAT_LLCELLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_UNCACHED), GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED), GEN8_PPAT_WB | 
GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0));
 }
 
 /* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability
@@ -3035,18 +3042,14 @@ static void bdw_setup_private_ppat(struct intel_ppat 
*ppat)
 * So we can still hold onto all our assumptions wrt cpu
 * clflushing on LLC machines.
 */
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), 
GEN8_PPAT_UC);
return;
}
 
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC);  /* for 
normal objects, no eLLC */
-   __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);  /* for 
something pointing to ptes? */
-   __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);  /* for 
scanout with eLLC */
-   __alloc_ppat_entry(ppat, 3, GEN8_PPAT_UC);  /* 
Uncached objects, mostly for scanout */
-   __alloc_ppat_entry(ppat, 4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(0));
-   __alloc_ppat_entry(ppat, 5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(1));
-   __alloc_ppat_entry(ppat, 6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(2));
-   __alloc_ppat_entry(ppat, 7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(3));
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), GEN8_PPAT_WB | 
GEN8_PPAT_LLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_DISPLAY_ELLC), GEN8_PPA

[Intel-gfx] [PATCH] drm/i915: Return the correct score in i915_ppat_get()

2017-09-18 Thread Zhi Wang
The cache attribute of the required entry has to be the same with the
existing value. After this requirement is met, the futher comparison
should be performed. After this fix, the refined test case can pass.

v2:

- Refine the tittle and comments. (Rodrigo)

Fixes: 4395890a4855 ("drm/i915: Introduce private PAT management")
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 5923b51..636ad7d 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2965,7 +2965,7 @@ static unsigned int bdw_private_pat_match(u8 src, u8 dst)
};
 
/* Cache attribute has to be matched. */
-   if (GEN8_PPAT_GET_CA(src) == GEN8_PPAT_GET_CA(dst))
+   if (GEN8_PPAT_GET_CA(src) != GEN8_PPAT_GET_CA(dst))
return 0;
 
score |= CA_MATCH;
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 2/2] drm/i915: add lockdep_assert_held in i915_ppat_{get, put}

2017-09-14 Thread Zhi Wang
struct_mutext needs to be held before call these two APIs.

Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 37cd086..b43d3c9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2869,6 +2869,7 @@ intel_ppat_get(struct drm_i915_private *i915, u8 value)
unsigned int scanned, best_score;
int i;
 
+   lockdep_assert_held(>drm.struct_mutex);
GEM_BUG_ON(!ppat->max_entries);
 
scanned = best_score = 0;
@@ -2924,6 +2925,7 @@ void intel_ppat_put(const struct intel_ppat_entry *entry)
struct intel_ppat *ppat = entry->ppat;
unsigned int index = entry - ppat->entries;
 
+   lockdep_assert_held(>i915->drm.struct_mutex);
GEM_BUG_ON(!ppat->max_entries);
 
kref_put(>entries[index].ref, release_ppat);
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 1/2] drm/i915: Return the correct score in i915_ppat_get()

2017-09-14 Thread Zhi Wang
The cache attribute of the required entry has to be the same with the
existing value. After this requirement is met, the futher comparison
should be performed.

v2:

- Refine the tittle and comments. (Rodrigo)

Fixes: 4395890a4855 ("drm/i915: Introduce private PAT management")
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 729ebaf..37cd086 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2965,7 +2965,7 @@ static unsigned int bdw_private_pat_match(u8 src, u8 dst)
};
 
/* Cache attribute has to be matched. */
-   if (GEN8_PPAT_GET_CA(src) == GEN8_PPAT_GET_CA(dst))
+   if (GEN8_PPAT_GET_CA(src) != GEN8_PPAT_GET_CA(dst))
return 0;
 
score |= CA_MATCH;
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/2] drm/i915: add lockdep_assert_held in i915_ppat_{get, put}

2017-09-14 Thread Zhi Wang
struct_mutext needs to be held before call these two APIs.

Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 37cd086..b43d3c9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2869,6 +2869,7 @@ intel_ppat_get(struct drm_i915_private *i915, u8 value)
unsigned int scanned, best_score;
int i;
 
+   lockdep_assert_held(>drm.struct_mutex);
GEM_BUG_ON(!ppat->max_entries);
 
scanned = best_score = 0;
@@ -2924,6 +2925,7 @@ void intel_ppat_put(const struct intel_ppat_entry *entry)
struct intel_ppat *ppat = entry->ppat;
unsigned int index = entry - ppat->entries;
 
+   lockdep_assert_held(>i915->drm.struct_mutex);
GEM_BUG_ON(!ppat->max_entries);
 
kref_put(>entries[index].ref, release_ppat);
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/2] drm/i915: Fix a typo in i915_ppat_get()

2017-09-14 Thread Zhi Wang
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 729ebaf..37cd086 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2965,7 +2965,7 @@ static unsigned int bdw_private_pat_match(u8 src, u8 dst)
};
 
/* Cache attribute has to be matched. */
-   if (GEN8_PPAT_GET_CA(src) == GEN8_PPAT_GET_CA(dst))
+   if (GEN8_PPAT_GET_CA(src) != GEN8_PPAT_GET_CA(dst))
return 0;
 
score |= CA_MATCH;
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v17 2/4] drm/i915: Remove the "INDEX" suffix from PPAT marcos

2017-09-14 Thread Zhi Wang
Remove the "INDEX" suffix from PPAT marcos as they are bits actually, not
indexes.

Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gvt/gtt.c  |  2 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c | 10 +-
 drivers/gpu/drm/i915/i915_gem_gtt.h |  8 
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 0bd028f..2801d70 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -1971,7 +1971,7 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu,
 */
se.val64 |= _PAGE_PRESENT | _PAGE_RW;
if (type == GTT_TYPE_PPGTT_PDE_PT)
-   se.val64 |= PPAT_CACHED_INDEX;
+   se.val64 |= PPAT_CACHED;
 
for (i = 0; i < page_entry_num; i++)
ops->set_entry(scratch_pt, , i, false, 0, vgpu);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index c726cb4..2639f67 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -230,13 +230,13 @@ static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
 
switch (level) {
case I915_CACHE_NONE:
-   pte |= PPAT_UNCACHED_INDEX;
+   pte |= PPAT_UNCACHED;
break;
case I915_CACHE_WT:
-   pte |= PPAT_DISPLAY_ELLC_INDEX;
+   pte |= PPAT_DISPLAY_ELLC;
break;
default:
-   pte |= PPAT_CACHED_INDEX;
+   pte |= PPAT_CACHED;
break;
}
 
@@ -249,9 +249,9 @@ static gen8_pde_t gen8_pde_encode(const dma_addr_t addr,
gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
pde |= addr;
if (level != I915_CACHE_NONE)
-   pde |= PPAT_CACHED_PDE_INDEX;
+   pde |= PPAT_CACHED_PDE;
else
-   pde |= PPAT_UNCACHED_INDEX;
+   pde |= PPAT_UNCACHED;
return pde;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index f3943b6..f62fb90 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -126,10 +126,10 @@ typedef u64 gen8_ppgtt_pml4e_t;
  * tables */
 #define GEN8_PDPE_MASK 0x1ff
 
-#define PPAT_UNCACHED_INDEX(_PAGE_PWT | _PAGE_PCD)
-#define PPAT_CACHED_PDE_INDEX  0 /* WB LLC */
-#define PPAT_CACHED_INDEX  _PAGE_PAT /* WB LLCeLLC */
-#define PPAT_DISPLAY_ELLC_INDEX_PAGE_PCD /* WT eLLC */
+#define PPAT_UNCACHED  (_PAGE_PWT | _PAGE_PCD)
+#define PPAT_CACHED_PDE0 /* WB LLC */
+#define PPAT_CACHED_PAGE_PAT /* WB LLCeLLC */
+#define PPAT_DISPLAY_ELLC  _PAGE_PCD /* WT eLLC */
 
 #define CHV_PPAT_SNOOP (1<<6)
 #define GEN8_PPAT_AGE(x)   ((x)<<4)
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/2] drm/i915: Fix a typo in i915_ppat_get()

2017-09-14 Thread Zhi Wang
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 729ebaf..37cd086 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2965,7 +2965,7 @@ static unsigned int bdw_private_pat_match(u8 src, u8 dst)
};
 
/* Cache attribute has to be matched. */
-   if (GEN8_PPAT_GET_CA(src) == GEN8_PPAT_GET_CA(dst))
+   if (GEN8_PPAT_GET_CA(src) != GEN8_PPAT_GET_CA(dst))
return 0;
 
score |= CA_MATCH;
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/2] drm/i915: add lockdep_assert_held in i915_ppat_{get, put}

2017-09-14 Thread Zhi Wang
struct_mutext needs to be held before call these two APIs.

Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 37cd086..b43d3c9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2869,6 +2869,7 @@ intel_ppat_get(struct drm_i915_private *i915, u8 value)
unsigned int scanned, best_score;
int i;
 
+   lockdep_assert_held(>drm.struct_mutex);
GEM_BUG_ON(!ppat->max_entries);
 
scanned = best_score = 0;
@@ -2924,6 +2925,7 @@ void intel_ppat_put(const struct intel_ppat_entry *entry)
struct intel_ppat *ppat = entry->ppat;
unsigned int index = entry - ppat->entries;
 
+   lockdep_assert_held(>i915->drm.struct_mutex);
GEM_BUG_ON(!ppat->max_entries);
 
kref_put(>entries[index].ref, release_ppat);
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v17 1/4] drm/i915: Introduce private PAT management

2017-09-14 Thread Zhi Wang
The private PAT management is to support PPAT entry manipulation. Two
APIs are introduced for dynamically managing PPAT entries: intel_ppat_get
and intel_ppat_put.

intel_ppat_get will search for an existing PPAT entry which perfectly
matches the required PPAT value. If not, it will try to allocate a new
entry if there is any available PPAT indexs, or return a partially
matched PPAT entry if there is no available PPAT indexes.

intel_ppat_put will put back the PPAT entry which comes from
intel_ppat_get. If it's dynamically allocated, the reference count will
be decreased. If the reference count turns into zero, the PPAT index is
freed again.

Besides, another two callbacks are introduced to support the private PAT
management framework. One is ppat->update_hw(), which writes the PPAT
configurations in ppat->entries into HW. Another one is ppat->match, which
will return a score to show how two PPAT values match with each other.

v17:

- Refine the comparision of score of BDW. (Joonas)

v16:

- Fix a bug in PPAT match function of BDW. (Joonas)

v15:

- Refine some code flow. (Joonas)

v12:

- Fix a problem "not returning the entry of best score". (Zhenyu)

v7:

- Keep all the register writes unchanged in this patch. (Joonas)

v6:

- Address all comments from Chris:
http://www.spinics.net/lists/intel-gfx/msg136850.html

- Address all comments from Joonas:
http://www.spinics.net/lists/intel-gfx/msg136845.html

v5:

- Add check and warnnings for those platforms which don't have PPAT.

v3:

- Introduce dirty bitmap for PPAT registers. (Chris)
- Change the name of the pointer "dev_priv" to "i915". (Chris)
- intel_ppat_{get, put} returns/takes a const intel_ppat_entry *. (Chris)

v2:

- API re-design. (Chris)

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk> #v7
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |   2 +
 drivers/gpu/drm/i915/i915_gem_gtt.c | 285 +---
 drivers/gpu/drm/i915/i915_gem_gtt.h |  36 +
 3 files changed, 274 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1cc31a5..de1fb0f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2354,6 +2354,8 @@ struct drm_i915_private {
DECLARE_HASHTABLE(mm_structs, 7);
struct mutex mm_lock;
 
+   struct intel_ppat ppat;
+
/* Kernel Modesetting */
 
struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 09e524d..c726cb4 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2819,41 +2819,209 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, 
u64 size)
return 0;
 }
 
-static void cnl_setup_private_ppat(struct drm_i915_private *dev_priv)
+static struct intel_ppat_entry *
+__alloc_ppat_entry(struct intel_ppat *ppat, unsigned int index, u8 value)
 {
+   struct intel_ppat_entry *entry = >entries[index];
+
+   GEM_BUG_ON(index >= ppat->max_entries);
+   GEM_BUG_ON(test_bit(index, ppat->used));
+
+   entry->ppat = ppat;
+   entry->value = value;
+   kref_init(>ref);
+   set_bit(index, ppat->used);
+   set_bit(index, ppat->dirty);
+
+   return entry;
+}
+
+static void __free_ppat_entry(struct intel_ppat_entry *entry)
+{
+   struct intel_ppat *ppat = entry->ppat;
+   unsigned int index = entry - ppat->entries;
+
+   GEM_BUG_ON(index >= ppat->max_entries);
+   GEM_BUG_ON(!test_bit(index, ppat->used));
+
+   entry->value = ppat->clear_value;
+   clear_bit(index, ppat->used);
+   set_bit(index, ppat->dirty);
+}
+
+/**
+ * intel_ppat_get - get a usable PPAT entry
+ * @i915: i915 device instance
+ * @value: the PPAT value required by the caller
+ *
+ * The function tries to search if there is an existing PPAT entry which
+ * matches with the required value. If perfectly matched, the existing PPAT
+ * entry will be used. If only partially matched, it will try to check if
+ * there is any available PPAT index. If yes, it will allocate a new PPAT
+ * index for the required entry and update the HW. If not, the partially
+ * matched entry will be used.
+ */
+const struct intel_ppat_entry *
+intel_ppat_get(struct drm_i915_private *i915, u8 value)
+{
+   struct intel_ppat *ppat = >ppat;
+   struct intel_ppat_entry *entry;
+   unsigned int scanned, best_score;
+   int i;
+
+   GEM_BUG_ON(!ppat->max_entries);
+
+   scanned = best_score = 0;
+   f

[Intel-gfx] [PATCH v17 3/4] drm/i915: Do not allocate unused PPAT entries

2017-09-14 Thread Zhi Wang
Only PPAT entries 0/2/3/4 are using. Remove extra PPAT entry allocation
during initialization.

v8:

- Move ppat_index() into i915_gem_gtt.c. (Chris)
- Change the name of ppat_bits_to_index to ppat_index.

Suggested-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 52 ++---
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 2639f67..789d724 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -230,9 +230,11 @@ static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
 
switch (level) {
case I915_CACHE_NONE:
+   /* Uncached objects, mostly for scanout */
pte |= PPAT_UNCACHED;
break;
case I915_CACHE_WT:
+   /* for scanout with eLLC */
pte |= PPAT_DISPLAY_ELLC;
break;
default:
@@ -249,6 +251,7 @@ static gen8_pde_t gen8_pde_encode(const dma_addr_t addr,
gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
pde |= addr;
if (level != I915_CACHE_NONE)
+   /* for normal objects, no eLLC */
pde |= PPAT_CACHED_PDE;
else
pde |= PPAT_UNCACHED;
@@ -2988,6 +2991,14 @@ static unsigned int chv_private_pat_match(u8 src, u8 dst)
INTEL_PPAT_PERFECT_MATCH : 0;
 }
 
+/* PPAT index = 4 * PAT + 2 * PCD + PWT */
+static inline unsigned int ppat_index(unsigned int bits)
+{
+   return (4 * !!(bits & _PAGE_PAT) +
+   2 * !!(bits & _PAGE_PCD) +
+   !!(bits & _PAGE_PWT));
+}
+
 static void cnl_setup_private_ppat(struct intel_ppat *ppat)
 {
ppat->max_entries = 8;
@@ -2997,18 +3008,14 @@ static void cnl_setup_private_ppat(struct intel_ppat 
*ppat)
 
/* XXX: spec is unclear if this is still needed for CNL+ */
if (!USES_PPGTT(ppat->i915)) {
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), 
GEN8_PPAT_UC);
return;
}
 
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC);
-   __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);
-   __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);
-   __alloc_ppat_entry(ppat, 3, GEN8_PPAT_UC);
-   __alloc_ppat_entry(ppat, 4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(0));
-   __alloc_ppat_entry(ppat, 5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(1));
-   __alloc_ppat_entry(ppat, 6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(2));
-   __alloc_ppat_entry(ppat, 7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(3));
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), GEN8_PPAT_WB | 
GEN8_PPAT_LLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_DISPLAY_ELLC), GEN8_PPAT_WT | 
GEN8_PPAT_LLCELLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_UNCACHED), GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED), GEN8_PPAT_WB | 
GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0));
 }
 
 /* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability
@@ -3035,18 +3042,14 @@ static void bdw_setup_private_ppat(struct intel_ppat 
*ppat)
 * So we can still hold onto all our assumptions wrt cpu
 * clflushing on LLC machines.
 */
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), 
GEN8_PPAT_UC);
return;
}
 
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC);  /* for 
normal objects, no eLLC */
-   __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);  /* for 
something pointing to ptes? */
-   __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);  /* for 
scanout with eLLC */
-   __alloc_ppat_entry(ppat, 3, GEN8_PPAT_UC);  /* 
Uncached objects, mostly for scanout */
-   __alloc_ppat_entry(ppat, 4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(0));
-   __alloc_ppat_entry(ppat, 5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(1));
-   __alloc_ppat_entry(ppat, 6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(2));
-   __alloc_ppat_entry(ppat, 7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(3));
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), GEN8_PPAT_WB | 
GEN8_PPAT_LLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_DISPLAY_ELLC), GEN8_PPAT_WT | 
GEN8_PPAT_LLCELLC);
+   __alloc_pp

[Intel-gfx] [PATCH v17 1/4] drm/i915: Introduce private PAT management

2017-09-14 Thread Zhi Wang
The private PAT management is to support PPAT entry manipulation. Two
APIs are introduced for dynamically managing PPAT entries: intel_ppat_get
and intel_ppat_put.

intel_ppat_get will search for an existing PPAT entry which perfectly
matches the required PPAT value. If not, it will try to allocate a new
entry if there is any available PPAT indexs, or return a partially
matched PPAT entry if there is no available PPAT indexes.

intel_ppat_put will put back the PPAT entry which comes from
intel_ppat_get. If it's dynamically allocated, the reference count will
be decreased. If the reference count turns into zero, the PPAT index is
freed again.

Besides, another two callbacks are introduced to support the private PAT
management framework. One is ppat->update_hw(), which writes the PPAT
configurations in ppat->entries into HW. Another one is ppat->match, which
will return a score to show how two PPAT values match with each other.

v17:

- Refine the comparision of score of BDW. (Joonas)

v16:

- Fix a bug in PPAT match function of BDW. (Joonas)

v15:

- Refine some code flow. (Joonas)

v12:

- Fix a problem "not returning the entry of best score". (Zhenyu)

v7:

- Keep all the register writes unchanged in this patch. (Joonas)

v6:

- Address all comments from Chris:
http://www.spinics.net/lists/intel-gfx/msg136850.html

- Address all comments from Joonas:
http://www.spinics.net/lists/intel-gfx/msg136845.html

v5:

- Add check and warnnings for those platforms which don't have PPAT.

v3:

- Introduce dirty bitmap for PPAT registers. (Chris)
- Change the name of the pointer "dev_priv" to "i915". (Chris)
- intel_ppat_{get, put} returns/takes a const intel_ppat_entry *. (Chris)

v2:

- API re-design. (Chris)

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk> #v7
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |   2 +
 drivers/gpu/drm/i915/i915_gem_gtt.c | 285 +---
 drivers/gpu/drm/i915/i915_gem_gtt.h |  36 +
 3 files changed, 274 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1cc31a5..de1fb0f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2354,6 +2354,8 @@ struct drm_i915_private {
DECLARE_HASHTABLE(mm_structs, 7);
struct mutex mm_lock;
 
+   struct intel_ppat ppat;
+
/* Kernel Modesetting */
 
struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 09e524d..c726cb4 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2819,41 +2819,209 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, 
u64 size)
return 0;
 }
 
-static void cnl_setup_private_ppat(struct drm_i915_private *dev_priv)
+static struct intel_ppat_entry *
+__alloc_ppat_entry(struct intel_ppat *ppat, unsigned int index, u8 value)
 {
+   struct intel_ppat_entry *entry = >entries[index];
+
+   GEM_BUG_ON(index >= ppat->max_entries);
+   GEM_BUG_ON(test_bit(index, ppat->used));
+
+   entry->ppat = ppat;
+   entry->value = value;
+   kref_init(>ref);
+   set_bit(index, ppat->used);
+   set_bit(index, ppat->dirty);
+
+   return entry;
+}
+
+static void __free_ppat_entry(struct intel_ppat_entry *entry)
+{
+   struct intel_ppat *ppat = entry->ppat;
+   unsigned int index = entry - ppat->entries;
+
+   GEM_BUG_ON(index >= ppat->max_entries);
+   GEM_BUG_ON(!test_bit(index, ppat->used));
+
+   entry->value = ppat->clear_value;
+   clear_bit(index, ppat->used);
+   set_bit(index, ppat->dirty);
+}
+
+/**
+ * intel_ppat_get - get a usable PPAT entry
+ * @i915: i915 device instance
+ * @value: the PPAT value required by the caller
+ *
+ * The function tries to search if there is an existing PPAT entry which
+ * matches with the required value. If perfectly matched, the existing PPAT
+ * entry will be used. If only partially matched, it will try to check if
+ * there is any available PPAT index. If yes, it will allocate a new PPAT
+ * index for the required entry and update the HW. If not, the partially
+ * matched entry will be used.
+ */
+const struct intel_ppat_entry *
+intel_ppat_get(struct drm_i915_private *i915, u8 value)
+{
+   struct intel_ppat *ppat = >ppat;
+   struct intel_ppat_entry *entry;
+   unsigned int scanned, best_score;
+   int i;
+
+   GEM_BUG_ON(!ppat->max_entries);
+
+   scanned = best_score = 0;
+   f

[Intel-gfx] [PATCH v17 4/4] drm/i915/selftests: Introduce live tests of private PAT management

2017-09-14 Thread Zhi Wang
Introduce two live tests of private PAT management:

igt_ppat_init - This test is to check if all the PPAT configurations are
written into HW.

igt_ppat_get - This test performs several sub-tests on intel_ppat_get()
and intel_ppat_put().

The "perfect match" test case will try to get a PPAT entry with an existing
value, then check if the returned PPAT entry is the same one.

The "alloc entries" test case will run out of PPAT table, and check if all
the requested values are put into the newly allocated PPAT entries.

The negative test case will try to generate a new PPAT value, and get it
when PPAT table is full.

The "partial match" test case will generate a parital matched value from
the existing PPAT table and try to match it.

The "re-alloc" test case will try to free and then allocate a new entry
when the PPAT table is full.

The "put entries" test case will free all the PPAT entries that allocated
in "alloc entries" test case. It will check if the values of freed PPAT
entries turn into ppat->clear_value.

v11:

- Fix one indent problem in v10.

v10:

- Refine code structure.
- Introduce "re-alloc" test case. (Chris)

v9:

- Refine generate_new_value(). (Chris)
- Refine failure output. (Chris)
- Refine test flow of "perfect match". (Chris)
- Introduce another negative test case after "partial match". (Chris)

v8:

- Remove noisy output. (Chris)
- Add negative test case. (Chris)

Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 378 ++
 1 file changed, 378 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 6b132ca..cd7eeb6 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -1094,6 +1094,382 @@ static int igt_ggtt_page(void *arg)
return err;
 }
 
+static int check_cnl_ppat(struct drm_i915_private *dev_priv)
+{
+   struct intel_ppat *ppat = _priv->ppat;
+   int i;
+
+   for (i = 0; i < ppat->max_entries; i++) {
+   u32 value = I915_READ(GEN10_PAT_INDEX(i));
+
+   if (value != ppat->entries[i].value) {
+   pr_err("check PPAT failed: expected %x found %x\n",
+   ppat->entries[i].value, value);
+   return -EINVAL;
+   }
+   }
+   return 0;
+}
+
+static int check_bdw_ppat(struct drm_i915_private *dev_priv)
+{
+   struct intel_ppat *ppat = _priv->ppat;
+   u64 pat, hw_pat;
+   int i;
+
+   pat = hw_pat = 0;
+
+   for (i = 0; i < ppat->max_entries; i++)
+   pat |= GEN8_PPAT(i, ppat->entries[i].value);
+
+   hw_pat = I915_READ(GEN8_PRIVATE_PAT_HI);
+   hw_pat <<= 32;
+   hw_pat |= I915_READ(GEN8_PRIVATE_PAT_LO);
+
+   if (pat != hw_pat) {
+   pr_err("check PPAT failed: expected %llx found %llx\n",
+   pat, hw_pat);
+   return -EINVAL;
+   }
+   return 0;
+}
+
+static int igt_ppat_check(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   int ret;
+
+   if (!i915->ppat.max_entries)
+   return 0;
+
+   if (INTEL_GEN(i915) >= 10)
+   ret = check_cnl_ppat(i915);
+   else
+   ret = check_bdw_ppat(i915);
+
+   if (ret)
+   pr_err("check PPAT failed\n");
+
+   return ret;
+}
+
+static bool value_is_new(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   for_each_set_bit(i, ppat->used, ppat->max_entries) {
+   if (value != ppat->entries[i].value)
+   continue;
+
+   return false;
+   }
+   return true;
+}
+
+static bool value_for_partial_test(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   if (!value_is_new(ppat, value))
+   return false;
+
+   /*
+* At least, there should be one entry whose cache attribute is
+* same with the required value.
+*/
+   for_each_set_bit(i, ppat->used, ppat->max_entries) {
+   if (GEN8_PPAT_GET_CA(value) !=
+   GEN8_PPAT_GET_CA(ppat->entries[i].value))
+   continue;
+
+   return true;
+   }
+   return false;
+}
+
+static bool value_for_negative_test(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   if (!value_is_new(ppat, value))
+   return false;
+
+   /*
+* cache attribute has to be different, so i915_ppat_get() would
+ 

[Intel-gfx] [PATCH v17 2/4] drm/i915: Remove the "INDEX" suffix from PPAT marcos

2017-09-14 Thread Zhi Wang
Remove the "INDEX" suffix from PPAT marcos as they are bits actually, not
indexes.

Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gvt/gtt.c  |  2 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c | 10 +-
 drivers/gpu/drm/i915/i915_gem_gtt.h |  8 
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 0bd028f..2801d70 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -1971,7 +1971,7 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu,
 */
se.val64 |= _PAGE_PRESENT | _PAGE_RW;
if (type == GTT_TYPE_PPGTT_PDE_PT)
-   se.val64 |= PPAT_CACHED_INDEX;
+   se.val64 |= PPAT_CACHED;
 
for (i = 0; i < page_entry_num; i++)
ops->set_entry(scratch_pt, , i, false, 0, vgpu);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index c726cb4..2639f67 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -230,13 +230,13 @@ static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
 
switch (level) {
case I915_CACHE_NONE:
-   pte |= PPAT_UNCACHED_INDEX;
+   pte |= PPAT_UNCACHED;
break;
case I915_CACHE_WT:
-   pte |= PPAT_DISPLAY_ELLC_INDEX;
+   pte |= PPAT_DISPLAY_ELLC;
break;
default:
-   pte |= PPAT_CACHED_INDEX;
+   pte |= PPAT_CACHED;
break;
}
 
@@ -249,9 +249,9 @@ static gen8_pde_t gen8_pde_encode(const dma_addr_t addr,
gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
pde |= addr;
if (level != I915_CACHE_NONE)
-   pde |= PPAT_CACHED_PDE_INDEX;
+   pde |= PPAT_CACHED_PDE;
else
-   pde |= PPAT_UNCACHED_INDEX;
+   pde |= PPAT_UNCACHED;
return pde;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index f3943b6..f62fb90 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -126,10 +126,10 @@ typedef u64 gen8_ppgtt_pml4e_t;
  * tables */
 #define GEN8_PDPE_MASK 0x1ff
 
-#define PPAT_UNCACHED_INDEX(_PAGE_PWT | _PAGE_PCD)
-#define PPAT_CACHED_PDE_INDEX  0 /* WB LLC */
-#define PPAT_CACHED_INDEX  _PAGE_PAT /* WB LLCeLLC */
-#define PPAT_DISPLAY_ELLC_INDEX_PAGE_PCD /* WT eLLC */
+#define PPAT_UNCACHED  (_PAGE_PWT | _PAGE_PCD)
+#define PPAT_CACHED_PDE0 /* WB LLC */
+#define PPAT_CACHED_PAGE_PAT /* WB LLCeLLC */
+#define PPAT_DISPLAY_ELLC  _PAGE_PCD /* WT eLLC */
 
 #define CHV_PPAT_SNOOP (1<<6)
 #define GEN8_PPAT_AGE(x)   ((x)<<4)
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v16 4/4] drm/i915/selftests: Introduce live tests of private PAT management

2017-09-13 Thread Zhi Wang
Introduce two live tests of private PAT management:

igt_ppat_init - This test is to check if all the PPAT configurations are
written into HW.

igt_ppat_get - This test performs several sub-tests on intel_ppat_get()
and intel_ppat_put().

The "perfect match" test case will try to get a PPAT entry with an existing
value, then check if the returned PPAT entry is the same one.

The "alloc entries" test case will run out of PPAT table, and check if all
the requested values are put into the newly allocated PPAT entries.

The negative test case will try to generate a new PPAT value, and get it
when PPAT table is full.

The "partial match" test case will generate a parital matched value from
the existing PPAT table and try to match it.

The "re-alloc" test case will try to free and then allocate a new entry
when the PPAT table is full.

The "put entries" test case will free all the PPAT entries that allocated
in "alloc entries" test case. It will check if the values of freed PPAT
entries turn into ppat->clear_value.

v11:

- Fix one indent problem in v10.

v10:

- Refine code structure.
- Introduce "re-alloc" test case. (Chris)

v9:

- Refine generate_new_value(). (Chris)
- Refine failure output. (Chris)
- Refine test flow of "perfect match". (Chris)
- Introduce another negative test case after "partial match". (Chris)

v8:

- Remove noisy output. (Chris)
- Add negative test case. (Chris)

Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 378 ++
 1 file changed, 378 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 6b132ca..cd7eeb6 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -1094,6 +1094,382 @@ static int igt_ggtt_page(void *arg)
return err;
 }
 
+static int check_cnl_ppat(struct drm_i915_private *dev_priv)
+{
+   struct intel_ppat *ppat = _priv->ppat;
+   int i;
+
+   for (i = 0; i < ppat->max_entries; i++) {
+   u32 value = I915_READ(GEN10_PAT_INDEX(i));
+
+   if (value != ppat->entries[i].value) {
+   pr_err("check PPAT failed: expected %x found %x\n",
+   ppat->entries[i].value, value);
+   return -EINVAL;
+   }
+   }
+   return 0;
+}
+
+static int check_bdw_ppat(struct drm_i915_private *dev_priv)
+{
+   struct intel_ppat *ppat = _priv->ppat;
+   u64 pat, hw_pat;
+   int i;
+
+   pat = hw_pat = 0;
+
+   for (i = 0; i < ppat->max_entries; i++)
+   pat |= GEN8_PPAT(i, ppat->entries[i].value);
+
+   hw_pat = I915_READ(GEN8_PRIVATE_PAT_HI);
+   hw_pat <<= 32;
+   hw_pat |= I915_READ(GEN8_PRIVATE_PAT_LO);
+
+   if (pat != hw_pat) {
+   pr_err("check PPAT failed: expected %llx found %llx\n",
+   pat, hw_pat);
+   return -EINVAL;
+   }
+   return 0;
+}
+
+static int igt_ppat_check(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   int ret;
+
+   if (!i915->ppat.max_entries)
+   return 0;
+
+   if (INTEL_GEN(i915) >= 10)
+   ret = check_cnl_ppat(i915);
+   else
+   ret = check_bdw_ppat(i915);
+
+   if (ret)
+   pr_err("check PPAT failed\n");
+
+   return ret;
+}
+
+static bool value_is_new(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   for_each_set_bit(i, ppat->used, ppat->max_entries) {
+   if (value != ppat->entries[i].value)
+   continue;
+
+   return false;
+   }
+   return true;
+}
+
+static bool value_for_partial_test(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   if (!value_is_new(ppat, value))
+   return false;
+
+   /*
+* At least, there should be one entry whose cache attribute is
+* same with the required value.
+*/
+   for_each_set_bit(i, ppat->used, ppat->max_entries) {
+   if (GEN8_PPAT_GET_CA(value) !=
+   GEN8_PPAT_GET_CA(ppat->entries[i].value))
+   continue;
+
+   return true;
+   }
+   return false;
+}
+
+static bool value_for_negative_test(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   if (!value_is_new(ppat, value))
+   return false;
+
+   /*
+* cache attribute has to be different, so i915_ppat_get() would
+ 

[Intel-gfx] [PATCH v16 3/4] drm/i915: Do not allocate unused PPAT entries

2017-09-13 Thread Zhi Wang
Only PPAT entries 0/2/3/4 are using. Remove extra PPAT entry allocation
during initialization.

v8:

- Move ppat_index() into i915_gem_gtt.c. (Chris)
- Change the name of ppat_bits_to_index to ppat_index.

Suggested-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 52 ++---
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 462d520..3c2585d 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -230,9 +230,11 @@ static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
 
switch (level) {
case I915_CACHE_NONE:
+   /* Uncached objects, mostly for scanout */
pte |= PPAT_UNCACHED;
break;
case I915_CACHE_WT:
+   /* for scanout with eLLC */
pte |= PPAT_DISPLAY_ELLC;
break;
default:
@@ -249,6 +251,7 @@ static gen8_pde_t gen8_pde_encode(const dma_addr_t addr,
gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
pde |= addr;
if (level != I915_CACHE_NONE)
+   /* for normal objects, no eLLC */
pde |= PPAT_CACHED_PDE;
else
pde |= PPAT_UNCACHED;
@@ -2983,6 +2986,14 @@ static unsigned int chv_private_pat_match(u8 src, u8 dst)
INTEL_PPAT_PERFECT_MATCH : 0;
 }
 
+/* PPAT index = 4 * PAT + 2 * PCD + PWT */
+static inline unsigned int ppat_index(unsigned int bits)
+{
+   return (4 * !!(bits & _PAGE_PAT) +
+   2 * !!(bits & _PAGE_PCD) +
+   !!(bits & _PAGE_PWT));
+}
+
 static void cnl_setup_private_ppat(struct intel_ppat *ppat)
 {
ppat->max_entries = 8;
@@ -2992,18 +3003,14 @@ static void cnl_setup_private_ppat(struct intel_ppat 
*ppat)
 
/* XXX: spec is unclear if this is still needed for CNL+ */
if (!USES_PPGTT(ppat->i915)) {
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), 
GEN8_PPAT_UC);
return;
}
 
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC);
-   __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);
-   __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);
-   __alloc_ppat_entry(ppat, 3, GEN8_PPAT_UC);
-   __alloc_ppat_entry(ppat, 4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(0));
-   __alloc_ppat_entry(ppat, 5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(1));
-   __alloc_ppat_entry(ppat, 6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(2));
-   __alloc_ppat_entry(ppat, 7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(3));
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), GEN8_PPAT_WB | 
GEN8_PPAT_LLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_DISPLAY_ELLC), GEN8_PPAT_WT | 
GEN8_PPAT_LLCELLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_UNCACHED), GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED), GEN8_PPAT_WB | 
GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0));
 }
 
 /* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability
@@ -3030,18 +3037,14 @@ static void bdw_setup_private_ppat(struct intel_ppat 
*ppat)
 * So we can still hold onto all our assumptions wrt cpu
 * clflushing on LLC machines.
 */
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), 
GEN8_PPAT_UC);
return;
}
 
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC);  /* for 
normal objects, no eLLC */
-   __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);  /* for 
something pointing to ptes? */
-   __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);  /* for 
scanout with eLLC */
-   __alloc_ppat_entry(ppat, 3, GEN8_PPAT_UC);  /* 
Uncached objects, mostly for scanout */
-   __alloc_ppat_entry(ppat, 4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(0));
-   __alloc_ppat_entry(ppat, 5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(1));
-   __alloc_ppat_entry(ppat, 6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(2));
-   __alloc_ppat_entry(ppat, 7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(3));
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), GEN8_PPAT_WB | 
GEN8_PPAT_LLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_DISPLAY_ELLC), GEN8_PPAT_WT | 
GEN8_PPAT_LLCELLC);
+   __alloc_pp

[Intel-gfx] [PATCH v16 2/4] drm/i915: Remove the "INDEX" suffix from PPAT marcos

2017-09-13 Thread Zhi Wang
Remove the "INDEX" suffix from PPAT marcos as they are bits actually, not
indexes.

Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gvt/gtt.c  |  2 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c | 10 +-
 drivers/gpu/drm/i915/i915_gem_gtt.h |  8 
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 0bd028f..2801d70 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -1971,7 +1971,7 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu,
 */
se.val64 |= _PAGE_PRESENT | _PAGE_RW;
if (type == GTT_TYPE_PPGTT_PDE_PT)
-   se.val64 |= PPAT_CACHED_INDEX;
+   se.val64 |= PPAT_CACHED;
 
for (i = 0; i < page_entry_num; i++)
ops->set_entry(scratch_pt, , i, false, 0, vgpu);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 8e9573d..462d520 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -230,13 +230,13 @@ static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
 
switch (level) {
case I915_CACHE_NONE:
-   pte |= PPAT_UNCACHED_INDEX;
+   pte |= PPAT_UNCACHED;
break;
case I915_CACHE_WT:
-   pte |= PPAT_DISPLAY_ELLC_INDEX;
+   pte |= PPAT_DISPLAY_ELLC;
break;
default:
-   pte |= PPAT_CACHED_INDEX;
+   pte |= PPAT_CACHED;
break;
}
 
@@ -249,9 +249,9 @@ static gen8_pde_t gen8_pde_encode(const dma_addr_t addr,
gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
pde |= addr;
if (level != I915_CACHE_NONE)
-   pde |= PPAT_CACHED_PDE_INDEX;
+   pde |= PPAT_CACHED_PDE;
else
-   pde |= PPAT_UNCACHED_INDEX;
+   pde |= PPAT_UNCACHED;
return pde;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index f3943b6..f62fb90 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -126,10 +126,10 @@ typedef u64 gen8_ppgtt_pml4e_t;
  * tables */
 #define GEN8_PDPE_MASK 0x1ff
 
-#define PPAT_UNCACHED_INDEX(_PAGE_PWT | _PAGE_PCD)
-#define PPAT_CACHED_PDE_INDEX  0 /* WB LLC */
-#define PPAT_CACHED_INDEX  _PAGE_PAT /* WB LLCeLLC */
-#define PPAT_DISPLAY_ELLC_INDEX_PAGE_PCD /* WT eLLC */
+#define PPAT_UNCACHED  (_PAGE_PWT | _PAGE_PCD)
+#define PPAT_CACHED_PDE0 /* WB LLC */
+#define PPAT_CACHED_PAGE_PAT /* WB LLCeLLC */
+#define PPAT_DISPLAY_ELLC  _PAGE_PCD /* WT eLLC */
 
 #define CHV_PPAT_SNOOP (1<<6)
 #define GEN8_PPAT_AGE(x)   ((x)<<4)
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v16 1/4] drm/i915: Introduce private PAT management

2017-09-13 Thread Zhi Wang
The private PAT management is to support PPAT entry manipulation. Two
APIs are introduced for dynamically managing PPAT entries: intel_ppat_get
and intel_ppat_put.

intel_ppat_get will search for an existing PPAT entry which perfectly
matches the required PPAT value. If not, it will try to allocate a new
entry if there is any available PPAT indexs, or return a partially
matched PPAT entry if there is no available PPAT indexes.

intel_ppat_put will put back the PPAT entry which comes from
intel_ppat_get. If it's dynamically allocated, the reference count will
be decreased. If the reference count turns into zero, the PPAT index is
freed again.

Besides, another two callbacks are introduced to support the private PAT
management framework. One is ppat->update_hw(), which writes the PPAT
configurations in ppat->entries into HW. Another one is ppat->match, which
will return a score to show how two PPAT values match with each other.

v16:

- Fix a bug in PPAT match function of BDW. (Joonas)

v15:

- Refine some code flow. (Joonas)

v12:

- Fix a problem "not returning the entry of best score". (Zhenyu)

v7:

- Keep all the register writes unchanged in this patch. (Joonas)

v6:

- Address all comments from Chris:
http://www.spinics.net/lists/intel-gfx/msg136850.html

- Address all comments from Joonas:
http://www.spinics.net/lists/intel-gfx/msg136845.html

v5:

- Add check and warnnings for those platforms which don't have PPAT.

v3:

- Introduce dirty bitmap for PPAT registers. (Chris)
- Change the name of the pointer "dev_priv" to "i915". (Chris)
- intel_ppat_{get, put} returns/takes a const intel_ppat_entry *. (Chris)

v2:

- API re-design. (Chris)

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk> #v7
Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |   2 +
 drivers/gpu/drm/i915/i915_gem_gtt.c | 280 +---
 drivers/gpu/drm/i915/i915_gem_gtt.h |  36 +
 3 files changed, 269 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1cc31a5..de1fb0f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2354,6 +2354,8 @@ struct drm_i915_private {
DECLARE_HASHTABLE(mm_structs, 7);
struct mutex mm_lock;
 
+   struct intel_ppat ppat;
+
/* Kernel Modesetting */
 
struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 09e524d..8e9573d 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2819,41 +2819,204 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, 
u64 size)
return 0;
 }
 
-static void cnl_setup_private_ppat(struct drm_i915_private *dev_priv)
+static struct intel_ppat_entry *
+__alloc_ppat_entry(struct intel_ppat *ppat, unsigned int index, u8 value)
 {
+   struct intel_ppat_entry *entry = >entries[index];
+
+   GEM_BUG_ON(index >= ppat->max_entries);
+   GEM_BUG_ON(test_bit(index, ppat->used));
+
+   entry->ppat = ppat;
+   entry->value = value;
+   kref_init(>ref);
+   set_bit(index, ppat->used);
+   set_bit(index, ppat->dirty);
+
+   return entry;
+}
+
+static void __free_ppat_entry(struct intel_ppat_entry *entry)
+{
+   struct intel_ppat *ppat = entry->ppat;
+   unsigned int index = entry - ppat->entries;
+
+   GEM_BUG_ON(index >= ppat->max_entries);
+   GEM_BUG_ON(!test_bit(index, ppat->used));
+
+   entry->value = ppat->clear_value;
+   clear_bit(index, ppat->used);
+   set_bit(index, ppat->dirty);
+}
+
+/**
+ * intel_ppat_get - get a usable PPAT entry
+ * @i915: i915 device instance
+ * @value: the PPAT value required by the caller
+ *
+ * The function tries to search if there is an existing PPAT entry which
+ * matches with the required value. If perfectly matched, the existing PPAT
+ * entry will be used. If only partially matched, it will try to check if
+ * there is any available PPAT index. If yes, it will allocate a new PPAT
+ * index for the required entry and update the HW. If not, the partially
+ * matched entry will be used.
+ */
+const struct intel_ppat_entry *
+intel_ppat_get(struct drm_i915_private *i915, u8 value)
+{
+   struct intel_ppat *ppat = >ppat;
+   struct intel_ppat_entry *entry;
+   unsigned int scanned, best_score;
+   int i;
+
+   GEM_BUG_ON(!ppat->max_entries);
+
+   scanned = best_score = 0;
+   for_each_set_bit(i, ppat->used, ppat->max_entries)

Re: [Intel-gfx] [PATCH v13 2/5] drm/i915: Introduce private PAT management

2017-09-12 Thread Zhi Wang

On 09/11/17 16:59, Joonas Lahtinen wrote:

On Mon, 2017-09-11 at 12:26 +0800, Zhi Wang wrote:

The private PAT management is to support PPAT entry manipulation. Two
APIs are introduced for dynamically managing PPAT entries: intel_ppat_get
and intel_ppat_put.

intel_ppat_get will search for an existing PPAT entry which perfectly
matches the required PPAT value. If not, it will try to allocate a new
entry if there is any available PPAT indexs, or return a partially
matched PPAT entry if there is no available PPAT indexes.

intel_ppat_put will put back the PPAT entry which comes from
intel_ppat_get. If it's dynamically allocated, the reference count will
be decreased. If the reference count turns into zero, the PPAT index is
freed again.

Besides, another two callbacks are introduced to support the private PAT
management framework. One is ppat->update_hw(), which writes the PPAT
configurations in ppat->entries into HW. Another one is ppat->match, which
will return a score to show how two PPAT values match with each other.

v12:

- Fix a problem "not returning the entry of best score". (Zhenyu)

This change should have resulted in adding an indication that Chris
reviewed only a previous version of the patch.


v7:

- Keep all the register writes unchanged in this patch. (Joonas)

v6:

- Address all comments from Chris:
http://www.spinics.net/lists/intel-gfx/msg136850.html

- Address all comments from Joonas:
http://www.spinics.net/lists/intel-gfx/msg136845.html

v5:

- Add check and warnnings for those platforms which don't have PPAT.

v3:

- Introduce dirty bitmap for PPAT registers. (Chris)
- Change the name of the pointer "dev_priv" to "i915". (Chris)
- intel_ppat_{get, put} returns/takes a const intel_ppat_entry *. (Chris)

v2:

- API re-design. (Chris)

Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>




+/**
+ * intel_ppat_get - get a usable PPAT entry
+ * @i915: i915 device instance
+ * @value: the PPAT value required by the caller
+ *
+ * The function tries to search if there is an existing PPAT entry which
+ * matches with the required value. If perfectly matched, the existing PPAT
+ * entry will be used. If only partially matched, it will try to check if
+ * there is any available PPAT index. If yes, it will allocate a new PPAT
+ * index for the required entry and update the HW. If not, the partially
+ * matched entry will be used.
+ */
+const struct intel_ppat_entry *
+intel_ppat_get(struct drm_i915_private *i915, u8 value)
+{
+   struct intel_ppat *ppat = >ppat;
+   struct intel_ppat_entry *entry;
+   unsigned int scanned, best_score;
+   int i;
+
+   GEM_BUG_ON(!ppat->max_entries);
+
+   scanned = best_score = 0;

You can drop this extra newline.


+   for_each_set_bit(i, ppat->used, ppat->max_entries) {
+   unsigned int score;
+
+   score = ppat->match(ppat->entries[i].value, value);
+   if (score > best_score) {

If you set "entry = >entries[i];" here already.


+   if (score == INTEL_PPAT_PERFECT_MATCH) {
+   kref_get(>entries[i].ref);
+   return >entries[i];

These become "kref_get(>ref);" and "return entry;"


+static unsigned int bdw_private_pat_match(u8 src, u8 dst)
+{
+   unsigned int score = 0;
+
+   /* Cache attribute has to be matched. */
+   if (GEN8_PPAT_GET_CA(src) != GEN8_PPAT_GET_CA(dst))
+   return 0;

We're not giving any points for when only cache attribute matches? Does
not this result in ENOSPC when we would have an entry with matching
"cache attribute", but no other matching entries while PPAT is full.

so maybe score += 4 here?

Aiha. cache attribute of src == cache attribute of dst is mandatory 
since the mismatch of other attribute only causes performance drop, but 
mismatch of cache attribute causes problem of correctness.

+
+   if (GEN8_PPAT_GET_TC(src) == GEN8_PPAT_GET_TC(dst))
+   score += 2;
+
+   if (GEN8_PPAT_GET_AGE(src) == GEN8_PPAT_GET_AGE(dst))
+   score += 1;
+
+   if (score == 3)

(score == 7) respectively.


+   return INTEL_PPAT_PERFECT_MATCH;
+
+   return score;
+}
+
+static unsigned int chv_private_pat_match(u8 src, u8 dst)
+{
+   return (CHV_PPAT_GET_SNOOP(src) == CHV_PPAT_GET_SNOOP(dst)) ?
+   INTEL_PPAT_PERFECT_MATCH : 0;

This handles the situation correctly, when snooping is the only
attribute looked for.

With the BDW attribute fix scoring, this is;

Reviewed-by: Joonas Lahtinen <joonas.lahti...@linux.intel.

[Intel-gfx] [PATCH v2 7/9] drm/i915/gvt: Rename reserved ring buffer

2017-09-11 Thread Zhi Wang
"reserved" means reserve something from somewhere. Actually they are
buffers used by command scanner. Rename it to ring_scan_buffer.

v2:

- Remove the usage of an extra variable. (Zhenyu)

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/gvt/cmd_parser.c | 16 
 drivers/gpu/drm/i915/gvt/execlist.c   | 22 +++---
 drivers/gpu/drm/i915/gvt/gvt.h|  6 +++---
 3 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c 
b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index 22d33be..23922ac 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -2619,21 +2619,21 @@ static int shadow_workload_ring_buffer(struct 
intel_vgpu_workload *workload)
gma_tail = workload->rb_start + workload->rb_tail;
gma_top = workload->rb_start + guest_rb_size;
 
-   if (workload->rb_len > vgpu->reserve_ring_buffer_size[ring_id]) {
-   void *va, *p;
+   if (workload->rb_len > vgpu->ring_scan_buffer_size[ring_id]) {
+   void *p;
 
/* realloc the new ring buffer if needed */
-   va = vgpu->reserve_ring_buffer_va[ring_id];
-   p = krealloc(va, workload->rb_len, GFP_KERNEL);
+   p = krealloc(vgpu->ring_scan_buffer[ring_id], workload->rb_len,
+   GFP_KERNEL);
if (!p) {
-   gvt_vgpu_err("fail to alloc reserve ring buffer\n");
+   gvt_vgpu_err("fail to re-alloc ring scan buffer\n");
return -ENOMEM;
}
-   vgpu->reserve_ring_buffer_va[ring_id] = p;
-   vgpu->reserve_ring_buffer_size[ring_id] = workload->rb_len;
+   vgpu->ring_scan_buffer[ring_id] = p;
+   vgpu->ring_scan_buffer_size[ring_id] = workload->rb_len;
}
 
-   shadow_ring_buffer_va = vgpu->reserve_ring_buffer_va[ring_id];
+   shadow_ring_buffer_va = vgpu->ring_scan_buffer[ring_id];
 
/* get shadow ring buffer va */
workload->shadow_ring_buffer_va = shadow_ring_buffer_va;
diff --git a/drivers/gpu/drm/i915/gvt/execlist.c 
b/drivers/gpu/drm/i915/gvt/execlist.c
index d28bc89..733be7b 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.c
+++ b/drivers/gpu/drm/i915/gvt/execlist.c
@@ -865,9 +865,9 @@ void intel_vgpu_clean_execlist(struct intel_vgpu *vgpu)
clean_workloads(vgpu, ALL_ENGINES);
 
for_each_engine(engine, vgpu->gvt->dev_priv, i) {
-   kfree(vgpu->reserve_ring_buffer_va[i]);
-   vgpu->reserve_ring_buffer_va[i] = NULL;
-   vgpu->reserve_ring_buffer_size[i] = 0;
+   kfree(vgpu->ring_scan_buffer[i]);
+   vgpu->ring_scan_buffer[i] = NULL;
+   vgpu->ring_scan_buffer_size[i] = 0;
}
 }
 
@@ -882,21 +882,21 @@ int intel_vgpu_init_execlist(struct intel_vgpu *vgpu)
 
/* each ring has a shadow ring buffer until vgpu destroyed */
for_each_engine(engine, vgpu->gvt->dev_priv, i) {
-   vgpu->reserve_ring_buffer_va[i] =
+   vgpu->ring_scan_buffer[i] =
kmalloc(RESERVE_RING_BUFFER_SIZE, GFP_KERNEL);
-   if (!vgpu->reserve_ring_buffer_va[i]) {
-   gvt_vgpu_err("fail to alloc reserve ring buffer\n");
+   if (!vgpu->ring_scan_buffer[i]) {
+   gvt_vgpu_err("fail to alloc ring scan buffer\n");
goto out;
}
-   vgpu->reserve_ring_buffer_size[i] = RESERVE_RING_BUFFER_SIZE;
+   vgpu->ring_scan_buffer_size[i] = RESERVE_RING_BUFFER_SIZE;
}
return 0;
 out:
for_each_engine(engine, vgpu->gvt->dev_priv, i) {
-   if (vgpu->reserve_ring_buffer_size[i]) {
-   kfree(vgpu->reserve_ring_buffer_va[i]);
-   vgpu->reserve_ring_buffer_va[i] = NULL;
-   vgpu->reserve_ring_buffer_size[i] = 0;
+   if (vgpu->ring_scan_buffer_size[i]) {
+   kfree(vgpu->ring_scan_buffer[i]);
+   vgpu->ring_scan_buffer[i] = NULL;
+   vgpu->ring_scan_buffer_size[i] = 0;
}
}
return -ENOMEM;
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 93ff530..5b723fa 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -172,9 +172,9 @@ struct intel_vgpu {
struct intel_vgpu_opregion opregion;
struct intel_vgpu_display display;
struct intel_vgpu_submission submission;
-   /* 1/2K for each reserve ring buffer */
-   void *reserve_ring_buffer_va[I915_NUM_E

[Intel-gfx] [PATCH v2 3/9] drm/i915/gvt: Move workload cache init/clean into intel_vgpu_{setup, clean}_submission()

2017-09-11 Thread Zhi Wang
Move vGPU workload cache initialization/de-initialization into
intel_vgpu_{setup, clean}_submission() since they are not specific to
execlist stuffs.

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/gvt/execlist.c  | 15 +--
 drivers/gpu/drm/i915/gvt/scheduler.c | 24 +++-
 2 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/execlist.c 
b/drivers/gpu/drm/i915/gvt/execlist.c
index 9402aa5..bdf78ab 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.c
+++ b/drivers/gpu/drm/i915/gvt/execlist.c
@@ -857,14 +857,12 @@ void intel_vgpu_clean_execlist(struct intel_vgpu *vgpu)
struct intel_engine_cs *engine;
 
clean_workloads(vgpu, ALL_ENGINES);
-   kmem_cache_destroy(vgpu->workloads);
 
for_each_engine(engine, vgpu->gvt->dev_priv, i) {
kfree(vgpu->reserve_ring_buffer_va[i]);
vgpu->reserve_ring_buffer_va[i] = NULL;
vgpu->reserve_ring_buffer_size[i] = 0;
}
-
 }
 
 #define RESERVE_RING_BUFFER_SIZE   ((1 * PAGE_SIZE)/8)
@@ -873,19 +871,8 @@ int intel_vgpu_init_execlist(struct intel_vgpu *vgpu)
enum intel_engine_id i;
struct intel_engine_cs *engine;
 
-   /* each ring has a virtual execlist engine */
-   for_each_engine(engine, vgpu->gvt->dev_priv, i) {
+   for_each_engine(engine, vgpu->gvt->dev_priv, i)
init_vgpu_execlist(vgpu, i);
-   INIT_LIST_HEAD(>workload_q_head[i]);
-   }
-
-   vgpu->workloads = kmem_cache_create("gvt-g_vgpu_workload",
-   sizeof(struct intel_vgpu_workload), 0,
-   SLAB_HWCACHE_ALIGN,
-   NULL);
-
-   if (!vgpu->workloads)
-   return -ENOMEM;
 
/* each ring has a shadow ring buffer until vgpu destroyed */
for_each_engine(engine, vgpu->gvt->dev_priv, i) {
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c 
b/drivers/gpu/drm/i915/gvt/scheduler.c
index d14d910..c5d7baf 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -718,6 +718,7 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
 void intel_vgpu_clean_submission(struct intel_vgpu *vgpu)
 {
i915_gem_context_put(vgpu->shadow_ctx);
+   kmem_cache_destroy(vgpu->workloads);
 }
 
 /**
@@ -732,7 +733,9 @@ void intel_vgpu_clean_submission(struct intel_vgpu *vgpu)
  */
 int intel_vgpu_setup_submission(struct intel_vgpu *vgpu)
 {
-   atomic_set(>running_workload_num, 0);
+   enum intel_engine_id i;
+   struct intel_engine_cs *engine;
+   int ret;
 
vgpu->shadow_ctx = i915_gem_context_create_gvt(
>gvt->dev_priv->drm);
@@ -743,5 +746,24 @@ int intel_vgpu_setup_submission(struct intel_vgpu *vgpu)
 
bitmap_zero(vgpu->shadow_ctx_desc_updated, I915_NUM_ENGINES);
 
+   vgpu->workloads = kmem_cache_create("gvt-g_vgpu_workload",
+   sizeof(struct intel_vgpu_workload), 0,
+   SLAB_HWCACHE_ALIGN,
+   NULL);
+
+   if (!vgpu->workloads) {
+   ret = -ENOMEM;
+   goto out_shadow_ctx;
+   }
+
+   for_each_engine(engine, vgpu->gvt->dev_priv, i)
+   INIT_LIST_HEAD(>workload_q_head[i]);
+
+   atomic_set(>running_workload_num, 0);
+
return 0;
+
+out_shadow_ctx:
+   i915_gem_context_put(vgpu->shadow_ctx);
+   return ret;
 }
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 2/9] drm/i915/gvt: Rename intel_vgpu_{init, clean}_gvt_context()

2017-09-11 Thread Zhi Wang
To move workload related functions into scheduler.c, an expected way is
to collect all the init/clean functions related to vGPU workload
submission into fewer functions.

Rename intel_vgpu_{init, clean}_gvt_context() for above usage in future.

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/gvt/scheduler.c | 21 +++--
 drivers/gpu/drm/i915/gvt/scheduler.h |  4 ++--
 drivers/gpu/drm/i915/gvt/vgpu.c  |  6 +++---
 3 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c 
b/drivers/gpu/drm/i915/gvt/scheduler.c
index 6fb9b58..d14d910 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -708,12 +708,29 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt 
*gvt)
return ret;
 }
 
-void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu)
+/**
+ * intel_vgpu_clean_submission - free submission-related resource for vGPU
+ * @vgpu: a vGPU
+ *
+ * This function is called when a vGPU is being destroyed.
+ *
+ */
+void intel_vgpu_clean_submission(struct intel_vgpu *vgpu)
 {
i915_gem_context_put(vgpu->shadow_ctx);
 }
 
-int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
+/**
+ * intel_vgpu_setup_submission - setup submission-related resource for vGPU
+ * @vgpu: a vGPU
+ *
+ * This function is called when a vGPU is being created.
+ *
+ * Returns:
+ * Zero on success, negative error code if failed.
+ *
+ */
+int intel_vgpu_setup_submission(struct intel_vgpu *vgpu)
 {
atomic_set(>running_workload_num, 0);
 
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.h 
b/drivers/gpu/drm/i915/gvt/scheduler.h
index f36b85f..b6ca44e 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.h
+++ b/drivers/gpu/drm/i915/gvt/scheduler.h
@@ -136,9 +136,9 @@ void intel_gvt_clean_workload_scheduler(struct intel_gvt 
*gvt);
 
 void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu);
 
-int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu);
+int intel_vgpu_setup_submission(struct intel_vgpu *vgpu);
 
-void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu);
+void intel_vgpu_clean_submission(struct intel_vgpu *vgpu);
 
 void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx);
 #endif
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 02c61a1..3d69871 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -254,7 +254,7 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
 
idr_remove(>vgpu_idr, vgpu->id);
intel_vgpu_clean_sched_policy(vgpu);
-   intel_vgpu_clean_gvt_context(vgpu);
+   intel_vgpu_clean_submission(vgpu);
intel_vgpu_clean_execlist(vgpu);
intel_vgpu_clean_display(vgpu);
intel_vgpu_clean_opregion(vgpu);
@@ -376,7 +376,7 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct 
intel_gvt *gvt,
if (ret)
goto out_clean_display;
 
-   ret = intel_vgpu_init_gvt_context(vgpu);
+   ret = intel_vgpu_setup_submission(vgpu);
if (ret)
goto out_clean_execlist;
 
@@ -389,7 +389,7 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct 
intel_gvt *gvt,
return vgpu;
 
 out_clean_shadow_ctx:
-   intel_vgpu_clean_gvt_context(vgpu);
+   intel_vgpu_clean_submission(vgpu);
 out_clean_execlist:
intel_vgpu_clean_execlist(vgpu);
 out_clean_display:
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 1/9] drm/i915/gvt: Make elsp_dwords in the right order

2017-09-11 Thread Zhi Wang
The context descriptors in elsp_dwords are stored in a reversed order and
the definition of context descriptor is also reversed. The revesred stuff
is hard to be used and might cause misunderstanding. Make them in the right
oder for following code re-factoring.

Tested on my SKL NUC.

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/gvt/execlist.c | 22 +++---
 drivers/gpu/drm/i915/gvt/execlist.h |  8 
 drivers/gpu/drm/i915/gvt/handlers.c |  2 +-
 3 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/execlist.c 
b/drivers/gpu/drm/i915/gvt/execlist.c
index 5ec07ec..9402aa5 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.c
+++ b/drivers/gpu/drm/i915/gvt/execlist.c
@@ -511,8 +511,8 @@ static int prepare_execlist_workload(struct 
intel_vgpu_workload *workload)
if (!workload->emulate_schedule_in)
return 0;
 
-   ctx[0] = *get_desc_from_elsp_dwords(>elsp_dwords, 1);
-   ctx[1] = *get_desc_from_elsp_dwords(>elsp_dwords, 0);
+   ctx[0] = *get_desc_from_elsp_dwords(>elsp_dwords, 0);
+   ctx[1] = *get_desc_from_elsp_dwords(>elsp_dwords, 1);
 
ret = emulate_execlist_schedule_in(>execlist[ring_id], ctx);
if (!ret)
@@ -771,21 +771,21 @@ static int submit_context(struct intel_vgpu *vgpu, int 
ring_id,
 int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id)
 {
struct intel_vgpu_execlist *execlist = >execlist[ring_id];
-   struct execlist_ctx_descriptor_format desc[2];
+   struct execlist_ctx_descriptor_format *desc[2];
int i, ret;
 
-   desc[0] = *get_desc_from_elsp_dwords(>elsp_dwords, 1);
-   desc[1] = *get_desc_from_elsp_dwords(>elsp_dwords, 0);
+   desc[0] = get_desc_from_elsp_dwords(>elsp_dwords, 0);
+   desc[1] = get_desc_from_elsp_dwords(>elsp_dwords, 1);
 
-   if (!desc[0].valid) {
+   if (!desc[0]->valid) {
gvt_vgpu_err("invalid elsp submission, desc0 is invalid\n");
goto inv_desc;
}
 
for (i = 0; i < ARRAY_SIZE(desc); i++) {
-   if (!desc[i].valid)
+   if (!desc[i]->valid)
continue;
-   if (!desc[i].privilege_access) {
+   if (!desc[i]->privilege_access) {
gvt_vgpu_err("unexpected GGTT elsp submission\n");
goto inv_desc;
}
@@ -793,9 +793,9 @@ int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int 
ring_id)
 
/* submit workload */
for (i = 0; i < ARRAY_SIZE(desc); i++) {
-   if (!desc[i].valid)
+   if (!desc[i]->valid)
continue;
-   ret = submit_context(vgpu, ring_id, [i], i == 0);
+   ret = submit_context(vgpu, ring_id, desc[i], i == 0);
if (ret) {
gvt_vgpu_err("failed to submit desc %d\n", i);
return ret;
@@ -806,7 +806,7 @@ int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int 
ring_id)
 
 inv_desc:
gvt_vgpu_err("descriptors content: desc0 %08x %08x desc1 %08x %08x\n",
-desc[0].udw, desc[0].ldw, desc[1].udw, desc[1].ldw);
+desc[0]->udw, desc[0]->ldw, desc[1]->udw, desc[1]->ldw);
return -EINVAL;
 }
 
diff --git a/drivers/gpu/drm/i915/gvt/execlist.h 
b/drivers/gpu/drm/i915/gvt/execlist.h
index 7eced40..427e40e 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.h
+++ b/drivers/gpu/drm/i915/gvt/execlist.h
@@ -37,10 +37,6 @@
 
 struct execlist_ctx_descriptor_format {
union {
-   u32 udw;
-   u32 context_id;
-   };
-   union {
u32 ldw;
struct {
u32 valid  : 1;
@@ -54,6 +50,10 @@ struct execlist_ctx_descriptor_format {
u32 lrca   : 20;
};
};
+   union {
+   u32 udw;
+   u32 context_id;
+   };
 };
 
 struct execlist_status_format {
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index 2294466..dcee645 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -1464,7 +1464,7 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, 
unsigned int offset,
 
execlist = >execlist[ring_id];
 
-   execlist->elsp_dwords.data[execlist->elsp_dwords.index] = data;
+   execlist->elsp_dwords.data[3 - execlist->elsp_dwords.index] = data;
if (execlist->elsp_dwords.index == 3) {
ret = intel_vgpu_submit_execlist(vgpu, ring_id);
if(ret)
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 9/9] drm/i915/gvt: Do not allocate initial ring scan buffer

2017-09-11 Thread Zhi Wang
Theoretically, the largest bulk of commands in the ring buffer of an
engine might be the first submission, which usually contains a lot
of commands to initialize the HW. After removing the initial allocation
of the ring scan buffer and let krealloc() do everything we need, we
still have a big chance to get the buffer of suitable size in the first
submission.

Tested on my SKL NUC.

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/gvt/execlist.c | 21 -
 drivers/gpu/drm/i915/gvt/gvt.h  |  1 -
 2 files changed, 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/execlist.c 
b/drivers/gpu/drm/i915/gvt/execlist.c
index fae7459..86d3cc8 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.c
+++ b/drivers/gpu/drm/i915/gvt/execlist.c
@@ -873,36 +873,15 @@ void intel_vgpu_clean_execlist(struct intel_vgpu *vgpu)
}
 }
 
-#define RESERVE_RING_BUFFER_SIZE   ((1 * PAGE_SIZE)/8)
 int intel_vgpu_init_execlist(struct intel_vgpu *vgpu)
 {
-   struct intel_vgpu_submission *s = >submission;
enum intel_engine_id i;
struct intel_engine_cs *engine;
 
for_each_engine(engine, vgpu->gvt->dev_priv, i)
init_vgpu_execlist(vgpu, i);
 
-   /* each ring has a shadow ring buffer until vgpu destroyed */
-   for_each_engine(engine, vgpu->gvt->dev_priv, i) {
-   s->ring_scan_buffer[i] =
-   kmalloc(RESERVE_RING_BUFFER_SIZE, GFP_KERNEL);
-   if (!s->ring_scan_buffer[i]) {
-   gvt_vgpu_err("fail to alloc ring scan buffer\n");
-   goto out;
-   }
-   s->ring_scan_buffer_size[i] = RESERVE_RING_BUFFER_SIZE;
-   }
return 0;
-out:
-   for_each_engine(engine, vgpu->gvt->dev_priv, i) {
-   if (s->ring_scan_buffer_size[i]) {
-   kfree(s->ring_scan_buffer[i]);
-   s->ring_scan_buffer[i] = NULL;
-   s->ring_scan_buffer_size[i] = 0;
-   }
-   }
-   return -ENOMEM;
 }
 
 void intel_vgpu_reset_execlist(struct intel_vgpu *vgpu,
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 49fe548..7a770b1 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -150,7 +150,6 @@ struct intel_vgpu_submission {
struct i915_gem_context *shadow_ctx;
DECLARE_BITMAP(shadow_ctx_desc_updated, I915_NUM_ENGINES);
DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES);
-   /* 1/2K for each engine */
void *ring_scan_buffer[I915_NUM_ENGINES];
int ring_scan_buffer_size[I915_NUM_ENGINES];
 };
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 4/9] drm/i915/gvt: Introduce intel_vgpu_submission

2017-09-11 Thread Zhi Wang
Introduce intel_vgpu_submission to hold all members related to submission
in struct intel_vgpu before.

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/gvt/execlist.c  | 30 +---
 drivers/gpu/drm/i915/gvt/gvt.h   | 17 +
 drivers/gpu/drm/i915/gvt/handlers.c  |  2 +-
 drivers/gpu/drm/i915/gvt/kvmgt.c |  2 +-
 drivers/gpu/drm/i915/gvt/render.c|  9 ++---
 drivers/gpu/drm/i915/gvt/scheduler.c | 67 
 drivers/gpu/drm/i915/gvt/scheduler.h |  2 +-
 drivers/gpu/drm/i915/gvt/vgpu.c  |  4 +--
 8 files changed, 76 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/execlist.c 
b/drivers/gpu/drm/i915/gvt/execlist.c
index bdf78ab..d28bc89 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.c
+++ b/drivers/gpu/drm/i915/gvt/execlist.c
@@ -362,7 +362,7 @@ static void free_workload(struct intel_vgpu_workload 
*workload)
 {
intel_vgpu_unpin_mm(workload->shadow_mm);
intel_gvt_mm_unreference(workload->shadow_mm);
-   kmem_cache_free(workload->vgpu->workloads, workload);
+   kmem_cache_free(workload->vgpu->submission.workloads, workload);
 }
 
 #define get_desc_from_elsp_dwords(ed, i) \
@@ -401,7 +401,8 @@ static int update_wa_ctx_2_shadow_ctx(struct 
intel_shadow_wa_ctx *wa_ctx)
struct intel_vgpu_workload,
wa_ctx);
int ring_id = workload->ring_id;
-   struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx;
+   struct intel_vgpu_submission *s = >vgpu->submission;
+   struct i915_gem_context *shadow_ctx = s->shadow_ctx;
struct drm_i915_gem_object *ctx_obj =
shadow_ctx->engine[ring_id].state->obj;
struct execlist_ring_context *shadow_ring_context;
@@ -474,6 +475,7 @@ static void release_shadow_batch_buffer(struct 
intel_vgpu_workload *workload)
 static int prepare_execlist_workload(struct intel_vgpu_workload *workload)
 {
struct intel_vgpu *vgpu = workload->vgpu;
+   struct intel_vgpu_submission *s = >submission;
struct execlist_ctx_descriptor_format ctx[2];
int ring_id = workload->ring_id;
int ret;
@@ -514,7 +516,7 @@ static int prepare_execlist_workload(struct 
intel_vgpu_workload *workload)
ctx[0] = *get_desc_from_elsp_dwords(>elsp_dwords, 0);
ctx[1] = *get_desc_from_elsp_dwords(>elsp_dwords, 1);
 
-   ret = emulate_execlist_schedule_in(>execlist[ring_id], ctx);
+   ret = emulate_execlist_schedule_in(>execlist[ring_id], ctx);
if (!ret)
goto out;
else
@@ -533,7 +535,8 @@ static int complete_execlist_workload(struct 
intel_vgpu_workload *workload)
 {
struct intel_vgpu *vgpu = workload->vgpu;
int ring_id = workload->ring_id;
-   struct intel_vgpu_execlist *execlist = >execlist[ring_id];
+   struct intel_vgpu_submission *s = >submission;
+   struct intel_vgpu_execlist *execlist = >execlist[ring_id];
struct intel_vgpu_workload *next_workload;
struct list_head *next = workload_q_head(vgpu, ring_id)->next;
bool lite_restore = false;
@@ -652,6 +655,7 @@ static int submit_context(struct intel_vgpu *vgpu, int 
ring_id,
struct execlist_ctx_descriptor_format *desc,
bool emulate_schedule_in)
 {
+   struct intel_vgpu_submission *s = >submission;
struct list_head *q = workload_q_head(vgpu, ring_id);
struct intel_vgpu_workload *last_workload = get_last_workload(q);
struct intel_vgpu_workload *workload = NULL;
@@ -689,7 +693,7 @@ static int submit_context(struct intel_vgpu *vgpu, int 
ring_id,
 
gvt_dbg_el("ring id %d begin a new workload\n", ring_id);
 
-   workload = kmem_cache_zalloc(vgpu->workloads, GFP_KERNEL);
+   workload = kmem_cache_zalloc(s->workloads, GFP_KERNEL);
if (!workload)
return -ENOMEM;
 
@@ -739,7 +743,7 @@ static int submit_context(struct intel_vgpu *vgpu, int 
ring_id,
}
 
if (emulate_schedule_in)
-   workload->elsp_dwords = vgpu->execlist[ring_id].elsp_dwords;
+   workload->elsp_dwords = s->execlist[ring_id].elsp_dwords;
 
gvt_dbg_el("workload %p ring id %d head %x tail %x start %x ctl %x\n",
workload, ring_id, head, tail, start, ctl);
@@ -749,7 +753,7 @@ static int submit_context(struct intel_vgpu *vgpu, int 
ring_id,
 
ret = prepare_mm(workload);
if (ret) {
-   kmem_cache_free(vgpu->workloads, workload);
+   kmem_cache_free(s->workloads, workload);
return ret;
}
 
@@ -770,7 +774,8 @@ static int submit_context(struct intel_vgpu *vgpu, int 
ring_id,
 
 int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id)
 {
-   struct intel_v

[Intel-gfx] [PATCH v2 6/9] drm/i915/gvt: Fix a memory leak in cmd_parser.c

2017-09-11 Thread Zhi Wang
The pointer points to the original memory can never take the return value
of krealloc().

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/gvt/cmd_parser.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c 
b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index 2c0ccbb..22d33be 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -2620,14 +2620,16 @@ static int shadow_workload_ring_buffer(struct 
intel_vgpu_workload *workload)
gma_top = workload->rb_start + guest_rb_size;
 
if (workload->rb_len > vgpu->reserve_ring_buffer_size[ring_id]) {
-   void *va = vgpu->reserve_ring_buffer_va[ring_id];
+   void *va, *p;
+
/* realloc the new ring buffer if needed */
-   vgpu->reserve_ring_buffer_va[ring_id] =
-   krealloc(va, workload->rb_len, GFP_KERNEL);
-   if (!vgpu->reserve_ring_buffer_va[ring_id]) {
+   va = vgpu->reserve_ring_buffer_va[ring_id];
+   p = krealloc(va, workload->rb_len, GFP_KERNEL);
+   if (!p) {
gvt_vgpu_err("fail to alloc reserve ring buffer\n");
return -ENOMEM;
}
+   vgpu->reserve_ring_buffer_va[ring_id] = p;
vgpu->reserve_ring_buffer_size[ring_id] = workload->rb_len;
}
 
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 5/9] drm/i915/gvt: Move tlb_handle_pending into intel_vgpu_submission

2017-09-11 Thread Zhi Wang
Move tlb_handle_pending into intel_vgpu_submssion since it belongs to a
part of vGPU submission stuffs

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/gvt/gvt.h   | 2 +-
 drivers/gpu/drm/i915/gvt/handlers.c  | 2 +-
 drivers/gpu/drm/i915/gvt/render.c| 3 ++-
 drivers/gpu/drm/i915/gvt/scheduler.c | 1 +
 drivers/gpu/drm/i915/gvt/vgpu.c  | 1 -
 5 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index c3f84f2..93ff530 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -149,6 +149,7 @@ struct intel_vgpu_submission {
atomic_t running_workload_num;
struct i915_gem_context *shadow_ctx;
DECLARE_BITMAP(shadow_ctx_desc_updated, I915_NUM_ENGINES);
+   DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES);
 };
 
 struct intel_vgpu {
@@ -174,7 +175,6 @@ struct intel_vgpu {
/* 1/2K for each reserve ring buffer */
void *reserve_ring_buffer_va[I915_NUM_ENGINES];
int reserve_ring_buffer_size[I915_NUM_ENGINES];
-   DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES);
 
 
 #if IS_ENABLED(CONFIG_DRM_I915_GVT_KVMGT)
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index a1963fc..2ee494b 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -1537,7 +1537,7 @@ static int gvt_reg_tlb_control_handler(struct intel_vgpu 
*vgpu,
default:
return -EINVAL;
}
-   set_bit(id, (void *)vgpu->tlb_handle_pending);
+   set_bit(id, (void *)vgpu->submission.tlb_handle_pending);
 
return 0;
 }
diff --git a/drivers/gpu/drm/i915/gvt/render.c 
b/drivers/gpu/drm/i915/gvt/render.c
index 7ed76ae..3910832 100644
--- a/drivers/gpu/drm/i915/gvt/render.c
+++ b/drivers/gpu/drm/i915/gvt/render.c
@@ -147,6 +147,7 @@ static u32 gen9_render_mocs_L3[32];
 static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id)
 {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
+   struct intel_vgpu_submission *s = >submission;
enum forcewake_domains fw;
i915_reg_t reg;
u32 regs[] = {
@@ -160,7 +161,7 @@ static void handle_tlb_pending_event(struct intel_vgpu 
*vgpu, int ring_id)
if (WARN_ON(ring_id >= ARRAY_SIZE(regs)))
return;
 
-   if (!test_and_clear_bit(ring_id, (void *)vgpu->tlb_handle_pending))
+   if (!test_and_clear_bit(ring_id, (void *)s->tlb_handle_pending))
return;
 
reg = _MMIO(regs[ring_id]);
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c 
b/drivers/gpu/drm/i915/gvt/scheduler.c
index 3527daf..c880866 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -767,6 +767,7 @@ int intel_vgpu_setup_submission(struct intel_vgpu *vgpu)
INIT_LIST_HEAD(>workload_q_head[i]);
 
atomic_set(>running_workload_num, 0);
+   bitmap_zero(s->tlb_handle_pending, I915_NUM_ENGINES);
 
return 0;
 
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 35a5ec2..1c9818d 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -346,7 +346,6 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct 
intel_gvt *gvt,
vgpu->handle = param->handle;
vgpu->gvt = gvt;
vgpu->sched_ctl.weight = param->weight;
-   bitmap_zero(vgpu->tlb_handle_pending, I915_NUM_ENGINES);
 
intel_vgpu_init_cfg_space(vgpu, param->primary);
 
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 8/9] drm/i915/gvt: Move ring scan buffers into intel_vgpu_submission

2017-09-11 Thread Zhi Wang
Move ring scan buffers into intel_vgpu_submission since they belongs to
a part of vGPU submission stuffs.

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/gvt/cmd_parser.c | 11 ++-
 drivers/gpu/drm/i915/gvt/execlist.c   | 23 +--
 drivers/gpu/drm/i915/gvt/gvt.h|  7 +++
 3 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c 
b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index 23922ac..136367f 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -2604,6 +2604,7 @@ static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload)
 {
struct intel_vgpu *vgpu = workload->vgpu;
+   struct intel_vgpu_submission *s = >submission;
unsigned long gma_head, gma_tail, gma_top, guest_rb_size;
void *shadow_ring_buffer_va;
int ring_id = workload->ring_id;
@@ -2619,21 +2620,21 @@ static int shadow_workload_ring_buffer(struct 
intel_vgpu_workload *workload)
gma_tail = workload->rb_start + workload->rb_tail;
gma_top = workload->rb_start + guest_rb_size;
 
-   if (workload->rb_len > vgpu->ring_scan_buffer_size[ring_id]) {
+   if (workload->rb_len > s->ring_scan_buffer_size[ring_id]) {
void *p;
 
/* realloc the new ring buffer if needed */
-   p = krealloc(vgpu->ring_scan_buffer[ring_id], workload->rb_len,
+   p = krealloc(s->ring_scan_buffer[ring_id], workload->rb_len,
GFP_KERNEL);
if (!p) {
gvt_vgpu_err("fail to re-alloc ring scan buffer\n");
return -ENOMEM;
}
-   vgpu->ring_scan_buffer[ring_id] = p;
-   vgpu->ring_scan_buffer_size[ring_id] = workload->rb_len;
+   s->ring_scan_buffer[ring_id] = p;
+   s->ring_scan_buffer_size[ring_id] = workload->rb_len;
}
 
-   shadow_ring_buffer_va = vgpu->ring_scan_buffer[ring_id];
+   shadow_ring_buffer_va = s->ring_scan_buffer[ring_id];
 
/* get shadow ring buffer va */
workload->shadow_ring_buffer_va = shadow_ring_buffer_va;
diff --git a/drivers/gpu/drm/i915/gvt/execlist.c 
b/drivers/gpu/drm/i915/gvt/execlist.c
index 733be7b..fae7459 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.c
+++ b/drivers/gpu/drm/i915/gvt/execlist.c
@@ -865,15 +865,18 @@ void intel_vgpu_clean_execlist(struct intel_vgpu *vgpu)
clean_workloads(vgpu, ALL_ENGINES);
 
for_each_engine(engine, vgpu->gvt->dev_priv, i) {
-   kfree(vgpu->ring_scan_buffer[i]);
-   vgpu->ring_scan_buffer[i] = NULL;
-   vgpu->ring_scan_buffer_size[i] = 0;
+   struct intel_vgpu_submission *s = >submission;
+
+   kfree(s->ring_scan_buffer[i]);
+   s->ring_scan_buffer[i] = NULL;
+   s->ring_scan_buffer_size[i] = 0;
}
 }
 
 #define RESERVE_RING_BUFFER_SIZE   ((1 * PAGE_SIZE)/8)
 int intel_vgpu_init_execlist(struct intel_vgpu *vgpu)
 {
+   struct intel_vgpu_submission *s = >submission;
enum intel_engine_id i;
struct intel_engine_cs *engine;
 
@@ -882,21 +885,21 @@ int intel_vgpu_init_execlist(struct intel_vgpu *vgpu)
 
/* each ring has a shadow ring buffer until vgpu destroyed */
for_each_engine(engine, vgpu->gvt->dev_priv, i) {
-   vgpu->ring_scan_buffer[i] =
+   s->ring_scan_buffer[i] =
kmalloc(RESERVE_RING_BUFFER_SIZE, GFP_KERNEL);
-   if (!vgpu->ring_scan_buffer[i]) {
+   if (!s->ring_scan_buffer[i]) {
gvt_vgpu_err("fail to alloc ring scan buffer\n");
goto out;
}
-   vgpu->ring_scan_buffer_size[i] = RESERVE_RING_BUFFER_SIZE;
+   s->ring_scan_buffer_size[i] = RESERVE_RING_BUFFER_SIZE;
}
return 0;
 out:
for_each_engine(engine, vgpu->gvt->dev_priv, i) {
-   if (vgpu->ring_scan_buffer_size[i]) {
-   kfree(vgpu->ring_scan_buffer[i]);
-   vgpu->ring_scan_buffer[i] = NULL;
-   vgpu->ring_scan_buffer_size[i] = 0;
+   if (s->ring_scan_buffer_size[i]) {
+   kfree(s->ring_scan_buffer[i]);
+   s->ring_scan_buffer[i] = NULL;
+   s->ring_scan_buffer_size[i] = 0;
}
}
return -ENOMEM;
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 5b723fa..49fe548 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/driver

[Intel-gfx] [PATCH v14 5/5] drm/i915/selftests: Introduce live tests of private PAT management

2017-09-11 Thread Zhi Wang
Introduce two live tests of private PAT management:

igt_ppat_init - This test is to check if all the PPAT configurations are
written into HW.

igt_ppat_get - This test performs several sub-tests on intel_ppat_get()
and intel_ppat_put().

The "perfect match" test case will try to get a PPAT entry with an existing
value, then check if the returned PPAT entry is the same one.

The "alloc entries" test case will run out of PPAT table, and check if all
the requested values are put into the newly allocated PPAT entries.

The negative test case will try to generate a new PPAT value, and get it
when PPAT table is full.

The "partial match" test case will generate a parital matched value from
the existing PPAT table and try to match it.

The "re-alloc" test case will try to free and then allocate a new entry
when the PPAT table is full.

The "put entries" test case will free all the PPAT entries that allocated
in "alloc entries" test case. It will check if the values of freed PPAT
entries turn into ppat->clear_value.

v11:

- Fix one indent problem in v10.

v10:

- Refine code structure.
- Introduce "re-alloc" test case. (Chris)

v9:

- Refine generate_new_value(). (Chris)
- Refine failure output. (Chris)
- Refine test flow of "perfect match". (Chris)
- Introduce another negative test case after "partial match". (Chris)

v8:

- Remove noisy output. (Chris)
- Add negative test case. (Chris)

Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 378 ++
 1 file changed, 378 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 6b132ca..cd7eeb6 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -1094,6 +1094,382 @@ static int igt_ggtt_page(void *arg)
return err;
 }
 
+static int check_cnl_ppat(struct drm_i915_private *dev_priv)
+{
+   struct intel_ppat *ppat = _priv->ppat;
+   int i;
+
+   for (i = 0; i < ppat->max_entries; i++) {
+   u32 value = I915_READ(GEN10_PAT_INDEX(i));
+
+   if (value != ppat->entries[i].value) {
+   pr_err("check PPAT failed: expected %x found %x\n",
+   ppat->entries[i].value, value);
+   return -EINVAL;
+   }
+   }
+   return 0;
+}
+
+static int check_bdw_ppat(struct drm_i915_private *dev_priv)
+{
+   struct intel_ppat *ppat = _priv->ppat;
+   u64 pat, hw_pat;
+   int i;
+
+   pat = hw_pat = 0;
+
+   for (i = 0; i < ppat->max_entries; i++)
+   pat |= GEN8_PPAT(i, ppat->entries[i].value);
+
+   hw_pat = I915_READ(GEN8_PRIVATE_PAT_HI);
+   hw_pat <<= 32;
+   hw_pat |= I915_READ(GEN8_PRIVATE_PAT_LO);
+
+   if (pat != hw_pat) {
+   pr_err("check PPAT failed: expected %llx found %llx\n",
+   pat, hw_pat);
+   return -EINVAL;
+   }
+   return 0;
+}
+
+static int igt_ppat_check(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   int ret;
+
+   if (!i915->ppat.max_entries)
+   return 0;
+
+   if (INTEL_GEN(i915) >= 10)
+   ret = check_cnl_ppat(i915);
+   else
+   ret = check_bdw_ppat(i915);
+
+   if (ret)
+   pr_err("check PPAT failed\n");
+
+   return ret;
+}
+
+static bool value_is_new(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   for_each_set_bit(i, ppat->used, ppat->max_entries) {
+   if (value != ppat->entries[i].value)
+   continue;
+
+   return false;
+   }
+   return true;
+}
+
+static bool value_for_partial_test(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   if (!value_is_new(ppat, value))
+   return false;
+
+   /*
+* At least, there should be one entry whose cache attribute is
+* same with the required value.
+*/
+   for_each_set_bit(i, ppat->used, ppat->max_entries) {
+   if (GEN8_PPAT_GET_CA(value) !=
+   GEN8_PPAT_GET_CA(ppat->entries[i].value))
+   continue;
+
+   return true;
+   }
+   return false;
+}
+
+static bool value_for_negative_test(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   if (!value_is_new(ppat, value))
+   return false;
+
+   /*
+* cache attribute has to be different, so i915_ppat_get() would
+ 

[Intel-gfx] [PATCH v14 4/5] drm/i915: Do not allocate unused PPAT entries

2017-09-11 Thread Zhi Wang
Only PPAT entries 0/2/3/4 are using. Remove extra PPAT entry allocation
during initialization.

v8:

- Move ppat_index() into i915_gem_gtt.c. (Chris)
- Change the name of ppat_bits_to_index to ppat_index.

Suggested-by: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 53 +++--
 1 file changed, 27 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 8b388aa..56fdfc6 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2979,6 +2979,13 @@ static unsigned int chv_private_pat_match(u8 src, u8 dst)
INTEL_PPAT_PERFECT_MATCH : 0;
 }
 
+/* PPAT index = 4 * PAT + 2 * PCD + PWT */
+static inline unsigned int ppat_index(unsigned int bits)
+{
+   return (4 * !!(bits & _PAGE_PAT) + 2 * !!(bits & _PAGE_PCD)
+   + !!(bits & _PAGE_PWT));
+}
+
 static void cnl_setup_private_ppat(struct intel_ppat *ppat)
 {
ppat->max_entries = 8;
@@ -2988,18 +2995,15 @@ static void cnl_setup_private_ppat(struct intel_ppat 
*ppat)
 
/* XXX: spec is unclear if this is still needed for CNL+ */
if (!USES_PPGTT(ppat->i915)) {
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), 
GEN8_PPAT_UC);
return;
}
 
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC);
-   __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);
-   __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);
-   __alloc_ppat_entry(ppat, 3, GEN8_PPAT_UC);
-   __alloc_ppat_entry(ppat, 4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(0));
-   __alloc_ppat_entry(ppat, 5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(1));
-   __alloc_ppat_entry(ppat, 6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(2));
-   __alloc_ppat_entry(ppat, 7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(3));
+   /* See gen8_pte_encode() for the mapping from cache-level to PPAT */
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), GEN8_PPAT_WB | 
GEN8_PPAT_LLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_DISPLAY_ELLC), GEN8_PPAT_WT | 
GEN8_PPAT_LLCELLC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_UNCACHED), GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED), GEN8_PPAT_WB | 
GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0));
 }
 
 /* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability
@@ -3026,18 +3030,18 @@ static void bdw_setup_private_ppat(struct intel_ppat 
*ppat)
 * So we can still hold onto all our assumptions wrt cpu
 * clflushing on LLC machines.
 */
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), 
GEN8_PPAT_UC);
return;
}
 
-   __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC);  /* for 
normal objects, no eLLC */
-   __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);  /* for 
something pointing to ptes? */
-   __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);  /* for 
scanout with eLLC */
-   __alloc_ppat_entry(ppat, 3, GEN8_PPAT_UC);  /* 
Uncached objects, mostly for scanout */
-   __alloc_ppat_entry(ppat, 4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(0));
-   __alloc_ppat_entry(ppat, 5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(1));
-   __alloc_ppat_entry(ppat, 6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(2));
-   __alloc_ppat_entry(ppat, 7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | 
GEN8_PPAT_AGE(3));
+   /* See gen8_pte_encode() for the mapping from cache-level to PPAT */
+   /* for normal objects, no eLLC */
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED_PDE), GEN8_PPAT_WB | 
GEN8_PPAT_LLC);
+   /* for scanout with eLLC */
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_DISPLAY_ELLC), GEN8_PPAT_WT | 
GEN8_PPAT_LLCELLC);
+   /* Uncached objects, mostly for scanout */
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_UNCACHED), GEN8_PPAT_UC);
+   __alloc_ppat_entry(ppat, ppat_index(PPAT_CACHED), GEN8_PPAT_WB | 
GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0));
 }
 
 static void chv_setup_private_ppat(struct intel_ppat *ppat)
@@ -3066,14 +3070,11 @@ static void chv_setup_private_ppat(struct intel_ppat 
*ppat)
 * in order to keep the global status page working.
 */
 
-   __alloc_ppat_entry(ppat, 0, CHV_PPAT_SNOOP);
-   __alloc_ppat_entry(ppat, 1, 0);
-   __alloc_ppat_entry(ppat, 2, 0);
-   __alloc_pp

[Intel-gfx] [PATCH v14 1/5] drm/i915: Factor out setup_private_pat()

2017-09-11 Thread Zhi Wang
Factor out setup_private_pat() for introducing the following patches.

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk>
Reviewed-by: Ben Widawsky <benjamin.widaw...@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index c33c2f9..2fc0656 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2915,6 +2915,16 @@ static void gen6_gmch_remove(struct i915_address_space 
*vm)
cleanup_scratch_page(vm);
 }
 
+static void setup_private_pat(struct drm_i915_private *dev_priv)
+{
+   if (INTEL_GEN(dev_priv) >= 10)
+   cnl_setup_private_ppat(dev_priv);
+   else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
+   chv_setup_private_ppat(dev_priv);
+   else
+   bdw_setup_private_ppat(dev_priv);
+}
+
 static int gen8_gmch_probe(struct i915_ggtt *ggtt)
 {
struct drm_i915_private *dev_priv = ggtt->base.i915;
@@ -2947,14 +2957,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
}
 
ggtt->base.total = (size / sizeof(gen8_pte_t)) << PAGE_SHIFT;
-
-   if (INTEL_GEN(dev_priv) >= 10)
-   cnl_setup_private_ppat(dev_priv);
-   else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
-   chv_setup_private_ppat(dev_priv);
-   else
-   bdw_setup_private_ppat(dev_priv);
-
ggtt->base.cleanup = gen6_gmch_remove;
ggtt->base.bind_vma = ggtt_bind_vma;
ggtt->base.unbind_vma = ggtt_unbind_vma;
@@ -2975,6 +2977,8 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
 
ggtt->invalidate = gen6_ggtt_invalidate;
 
+   setup_private_pat(dev_priv);
+
return ggtt_probe_common(ggtt, size);
 }
 
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v14 2/5] drm/i915: Introduce private PAT management

2017-09-11 Thread Zhi Wang
The private PAT management is to support PPAT entry manipulation. Two
APIs are introduced for dynamically managing PPAT entries: intel_ppat_get
and intel_ppat_put.

intel_ppat_get will search for an existing PPAT entry which perfectly
matches the required PPAT value. If not, it will try to allocate a new
entry if there is any available PPAT indexs, or return a partially
matched PPAT entry if there is no available PPAT indexes.

intel_ppat_put will put back the PPAT entry which comes from
intel_ppat_get. If it's dynamically allocated, the reference count will
be decreased. If the reference count turns into zero, the PPAT index is
freed again.

Besides, another two callbacks are introduced to support the private PAT
management framework. One is ppat->update_hw(), which writes the PPAT
configurations in ppat->entries into HW. Another one is ppat->match, which
will return a score to show how two PPAT values match with each other.

v12:

- Fix a problem "not returning the entry of best score". (Zhenyu)

v7:

- Keep all the register writes unchanged in this patch. (Joonas)

v6:

- Address all comments from Chris:
http://www.spinics.net/lists/intel-gfx/msg136850.html

- Address all comments from Joonas:
http://www.spinics.net/lists/intel-gfx/msg136845.html

v5:

- Add check and warnnings for those platforms which don't have PPAT.

v3:

- Introduce dirty bitmap for PPAT registers. (Chris)
- Change the name of the pointer "dev_priv" to "i915". (Chris)
- intel_ppat_{get, put} returns/takes a const intel_ppat_entry *. (Chris)

v2:

- API re-design. (Chris)

Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_drv.h |   2 +
 drivers/gpu/drm/i915/i915_gem_gtt.c | 279 +---
 drivers/gpu/drm/i915/i915_gem_gtt.h |  36 +
 3 files changed, 268 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 63ca2ff..3c10b82 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2347,6 +2347,8 @@ struct drm_i915_private {
DECLARE_HASHTABLE(mm_structs, 7);
struct mutex mm_lock;
 
+   struct intel_ppat ppat;
+
/* Kernel Modesetting */
 
struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 2fc0656..da3808c 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2816,41 +2816,203 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, 
u64 size)
return 0;
 }
 
-static void cnl_setup_private_ppat(struct drm_i915_private *dev_priv)
+static struct intel_ppat_entry *
+__alloc_ppat_entry(struct intel_ppat *ppat, unsigned int index, u8 value)
 {
+   struct intel_ppat_entry *entry = >entries[index];
+
+   GEM_BUG_ON(index >= ppat->max_entries);
+   GEM_BUG_ON(test_bit(index, ppat->used));
+
+   entry->ppat = ppat;
+   entry->value = value;
+   kref_init(>ref);
+   set_bit(index, ppat->used);
+   set_bit(index, ppat->dirty);
+
+   return entry;
+}
+
+static void __free_ppat_entry(struct intel_ppat_entry *entry)
+{
+   struct intel_ppat *ppat = entry->ppat;
+   unsigned int index = entry - ppat->entries;
+
+   GEM_BUG_ON(index >= ppat->max_entries);
+   GEM_BUG_ON(!test_bit(index, ppat->used));
+
+   entry->value = ppat->clear_value;
+   clear_bit(index, ppat->used);
+   set_bit(index, ppat->dirty);
+}
+
+/**
+ * intel_ppat_get - get a usable PPAT entry
+ * @i915: i915 device instance
+ * @value: the PPAT value required by the caller
+ *
+ * The function tries to search if there is an existing PPAT entry which
+ * matches with the required value. If perfectly matched, the existing PPAT
+ * entry will be used. If only partially matched, it will try to check if
+ * there is any available PPAT index. If yes, it will allocate a new PPAT
+ * index for the required entry and update the HW. If not, the partially
+ * matched entry will be used.
+ */
+const struct intel_ppat_entry *
+intel_ppat_get(struct drm_i915_private *i915, u8 value)
+{
+   struct intel_ppat *ppat = >ppat;
+   struct intel_ppat_entry *entry;
+   unsigned int scanned, best_score;
+   int i;
+
+   GEM_BUG_ON(!ppat->max_entries);
+
+   scanned = best_score = 0;
+
+   for_each_set_bit(i, ppat->used, ppat->max_entries) {
+   unsigned int score;
+
+   score = ppat->match(ppat->entries[i].value, value);
+   if (score > best_score) {
+   

[Intel-gfx] [PATCH v14 3/5] drm/i915: Remove the "INDEX" suffix from PPAT marcos

2017-09-11 Thread Zhi Wang
Remove the "INDEX" suffix from PPAT marcos as they are bits actually, not
indexes.

Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gvt/gtt.c  |  2 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c | 10 +-
 drivers/gpu/drm/i915/i915_gem_gtt.h |  8 
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 0bd028f..2801d70 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -1971,7 +1971,7 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu,
 */
se.val64 |= _PAGE_PRESENT | _PAGE_RW;
if (type == GTT_TYPE_PPGTT_PDE_PT)
-   se.val64 |= PPAT_CACHED_INDEX;
+   se.val64 |= PPAT_CACHED;
 
for (i = 0; i < page_entry_num; i++)
ops->set_entry(scratch_pt, , i, false, 0, vgpu);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index da3808c..8b388aa 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -230,13 +230,13 @@ static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
 
switch (level) {
case I915_CACHE_NONE:
-   pte |= PPAT_UNCACHED_INDEX;
+   pte |= PPAT_UNCACHED;
break;
case I915_CACHE_WT:
-   pte |= PPAT_DISPLAY_ELLC_INDEX;
+   pte |= PPAT_DISPLAY_ELLC;
break;
default:
-   pte |= PPAT_CACHED_INDEX;
+   pte |= PPAT_CACHED;
break;
}
 
@@ -249,9 +249,9 @@ static gen8_pde_t gen8_pde_encode(const dma_addr_t addr,
gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
pde |= addr;
if (level != I915_CACHE_NONE)
-   pde |= PPAT_CACHED_PDE_INDEX;
+   pde |= PPAT_CACHED_PDE;
else
-   pde |= PPAT_UNCACHED_INDEX;
+   pde |= PPAT_UNCACHED;
return pde;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index e10ca89..0178416 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -126,10 +126,10 @@ typedef u64 gen8_ppgtt_pml4e_t;
  * tables */
 #define GEN8_PDPE_MASK 0x1ff
 
-#define PPAT_UNCACHED_INDEX(_PAGE_PWT | _PAGE_PCD)
-#define PPAT_CACHED_PDE_INDEX  0 /* WB LLC */
-#define PPAT_CACHED_INDEX  _PAGE_PAT /* WB LLCeLLC */
-#define PPAT_DISPLAY_ELLC_INDEX_PAGE_PCD /* WT eLLC */
+#define PPAT_UNCACHED  (_PAGE_PWT | _PAGE_PCD)
+#define PPAT_CACHED_PDE0 /* WB LLC */
+#define PPAT_CACHED_PAGE_PAT /* WB LLCeLLC */
+#define PPAT_DISPLAY_ELLC  _PAGE_PCD /* WT eLLC */
 
 #define CHV_PPAT_SNOOP (1<<6)
 #define GEN8_PPAT_AGE(x)   (x<<4)
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v13 3/5] drm/i915: Remove the "INDEX" suffix from PPAT marcos

2017-09-10 Thread Zhi Wang
Remove the "INDEX" suffix from PPAT marcos as they are bits actually, not
indexes.

Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk>
Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/gvt/gtt.c  |  2 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c | 10 +-
 drivers/gpu/drm/i915/i915_gem_gtt.h |  8 
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 0bd028f..2801d70 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -1971,7 +1971,7 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu,
 */
se.val64 |= _PAGE_PRESENT | _PAGE_RW;
if (type == GTT_TYPE_PPGTT_PDE_PT)
-   se.val64 |= PPAT_CACHED_INDEX;
+   se.val64 |= PPAT_CACHED;
 
for (i = 0; i < page_entry_num; i++)
ops->set_entry(scratch_pt, , i, false, 0, vgpu);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index da3808c..8b388aa 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -230,13 +230,13 @@ static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
 
switch (level) {
case I915_CACHE_NONE:
-   pte |= PPAT_UNCACHED_INDEX;
+   pte |= PPAT_UNCACHED;
break;
case I915_CACHE_WT:
-   pte |= PPAT_DISPLAY_ELLC_INDEX;
+   pte |= PPAT_DISPLAY_ELLC;
break;
default:
-   pte |= PPAT_CACHED_INDEX;
+   pte |= PPAT_CACHED;
break;
}
 
@@ -249,9 +249,9 @@ static gen8_pde_t gen8_pde_encode(const dma_addr_t addr,
gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
pde |= addr;
if (level != I915_CACHE_NONE)
-   pde |= PPAT_CACHED_PDE_INDEX;
+   pde |= PPAT_CACHED_PDE;
else
-   pde |= PPAT_UNCACHED_INDEX;
+   pde |= PPAT_UNCACHED;
return pde;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index e10ca89..0178416 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -126,10 +126,10 @@ typedef u64 gen8_ppgtt_pml4e_t;
  * tables */
 #define GEN8_PDPE_MASK 0x1ff
 
-#define PPAT_UNCACHED_INDEX(_PAGE_PWT | _PAGE_PCD)
-#define PPAT_CACHED_PDE_INDEX  0 /* WB LLC */
-#define PPAT_CACHED_INDEX  _PAGE_PAT /* WB LLCeLLC */
-#define PPAT_DISPLAY_ELLC_INDEX_PAGE_PCD /* WT eLLC */
+#define PPAT_UNCACHED  (_PAGE_PWT | _PAGE_PCD)
+#define PPAT_CACHED_PDE0 /* WB LLC */
+#define PPAT_CACHED_PAGE_PAT /* WB LLCeLLC */
+#define PPAT_DISPLAY_ELLC  _PAGE_PCD /* WT eLLC */
 
 #define CHV_PPAT_SNOOP (1<<6)
 #define GEN8_PPAT_AGE(x)   (x<<4)
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v13 5/5] drm/i915/selftests: Introduce live tests of private PAT management

2017-09-10 Thread Zhi Wang
Introduce two live tests of private PAT management:

igt_ppat_init - This test is to check if all the PPAT configurations are
written into HW.

igt_ppat_get - This test performs several sub-tests on intel_ppat_get()
and intel_ppat_put().

The "perfect match" test case will try to get a PPAT entry with an existing
value, then check if the returned PPAT entry is the same one.

The "alloc entries" test case will run out of PPAT table, and check if all
the requested values are put into the newly allocated PPAT entries.

The negative test case will try to generate a new PPAT value, and get it
when PPAT table is full.

The "partial match" test case will generate a parital matched value from
the existing PPAT table and try to match it.

The "re-alloc" test case will try to free and then allocate a new entry
when the PPAT table is full.

The "put entries" test case will free all the PPAT entries that allocated
in "alloc entries" test case. It will check if the values of freed PPAT
entries turn into ppat->clear_value.

v11:

- Fix one indent problem in v10.

v10:

- Refine code structure.
- Introduce "re-alloc" test case. (Chris)

v9:

- Refine generate_new_value(). (Chris)
- Refine failure output. (Chris)
- Refine test flow of "perfect match". (Chris)
- Introduce another negative test case after "partial match". (Chris)

v8:

- Remove noisy output. (Chris)
- Add negative test case. (Chris)

Cc: Ben Widawsky <benjamin.widaw...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk>
Signed-off-by: Zhi Wang <zhi.a.w...@intel.com>
---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 378 ++
 1 file changed, 378 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 6b132ca..cd7eeb6 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -1094,6 +1094,382 @@ static int igt_ggtt_page(void *arg)
return err;
 }
 
+static int check_cnl_ppat(struct drm_i915_private *dev_priv)
+{
+   struct intel_ppat *ppat = _priv->ppat;
+   int i;
+
+   for (i = 0; i < ppat->max_entries; i++) {
+   u32 value = I915_READ(GEN10_PAT_INDEX(i));
+
+   if (value != ppat->entries[i].value) {
+   pr_err("check PPAT failed: expected %x found %x\n",
+   ppat->entries[i].value, value);
+   return -EINVAL;
+   }
+   }
+   return 0;
+}
+
+static int check_bdw_ppat(struct drm_i915_private *dev_priv)
+{
+   struct intel_ppat *ppat = _priv->ppat;
+   u64 pat, hw_pat;
+   int i;
+
+   pat = hw_pat = 0;
+
+   for (i = 0; i < ppat->max_entries; i++)
+   pat |= GEN8_PPAT(i, ppat->entries[i].value);
+
+   hw_pat = I915_READ(GEN8_PRIVATE_PAT_HI);
+   hw_pat <<= 32;
+   hw_pat |= I915_READ(GEN8_PRIVATE_PAT_LO);
+
+   if (pat != hw_pat) {
+   pr_err("check PPAT failed: expected %llx found %llx\n",
+   pat, hw_pat);
+   return -EINVAL;
+   }
+   return 0;
+}
+
+static int igt_ppat_check(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   int ret;
+
+   if (!i915->ppat.max_entries)
+   return 0;
+
+   if (INTEL_GEN(i915) >= 10)
+   ret = check_cnl_ppat(i915);
+   else
+   ret = check_bdw_ppat(i915);
+
+   if (ret)
+   pr_err("check PPAT failed\n");
+
+   return ret;
+}
+
+static bool value_is_new(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   for_each_set_bit(i, ppat->used, ppat->max_entries) {
+   if (value != ppat->entries[i].value)
+   continue;
+
+   return false;
+   }
+   return true;
+}
+
+static bool value_for_partial_test(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   if (!value_is_new(ppat, value))
+   return false;
+
+   /*
+* At least, there should be one entry whose cache attribute is
+* same with the required value.
+*/
+   for_each_set_bit(i, ppat->used, ppat->max_entries) {
+   if (GEN8_PPAT_GET_CA(value) !=
+   GEN8_PPAT_GET_CA(ppat->entries[i].value))
+   continue;
+
+   return true;
+   }
+   return false;
+}
+
+static bool value_for_negative_test(struct intel_ppat *ppat, u8 value)
+{
+   int i;
+
+   if (!value_is_new(ppat, value))
+   return false;
+
+   /*
+* cache attribute has to be different, so i915_ppat_get() would
+ 

  1   2   3   4   5   >