[PATCH] drm/i915/guc/rc: Use i915_probe_error instead of drm_error

2022-05-05 Thread Vinay Belgaumkar
To avoid false positives in error injection cases.

Signed-off-by: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
index e00661fb0853..8f8dd05835c5 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
@@ -49,7 +49,6 @@ static int guc_action_control_gucrc(struct intel_guc *guc, 
bool enable)
 static int __guc_rc_control(struct intel_guc *guc, bool enable)
 {
struct intel_gt *gt = guc_to_gt(guc);
-   struct drm_device *drm = _to_gt(guc)->i915->drm;
int ret;
 
if (!intel_uc_uses_guc_rc(>uc))
@@ -60,8 +59,8 @@ static int __guc_rc_control(struct intel_guc *guc, bool 
enable)
 
ret = guc_action_control_gucrc(guc, enable);
if (ret) {
-   drm_err(drm, "Failed to %s GuC RC (%pe)\n",
-   str_enable_disable(enable), ERR_PTR(ret));
+   i915_probe_error(guc_to_gt(guc)->i915, "Failed to %s GuC RC 
(%pe)\n",
+str_enable_disable(enable), ERR_PTR(ret));
return ret;
}
 
-- 
2.35.1



[no subject]

2022-05-05 Thread Dave Airlie
Hey Linus,

pretty quiet week, one fbdev, msm, kconfig, and 2 amdgpu fixes, about
what I'd expect for rc6.

Regards,
Dave.

drm-fixes-2022-05-06:
drm fixes for 5.18-rc6

fbdev:
- hotunplugging fix

amdgpu:
- Fix a xen dom0 regression on APUs
- Fix a potential array overflow if a receiver were to
  send an erroneous audio channel count

msm:
- lockdep fix.

it6505:
- kconfig fix
The following changes since commit 672c0c5173427e6b3e2a9bbb7be51ceeec78093a:

  Linux 5.18-rc5 (2022-05-01 13:57:58 -0700)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2022-05-06

for you to fetch changes up to 5727375215b0915f28806c337a7ba9835efd340b:

  Merge tag 'drm-msm-fixes-2022-04-30' of
https://gitlab.freedesktop.org/drm/msm into drm-fixes (2022-05-06
11:22:03 +1000)


drm fixes for 5.18-rc6

fbdev:
- hotunplugging fix

amdgpu:
- Fix a xen dom0 regression on APUs
- Fix a potential array overflow if a receiver were to
  send an erroneous audio channel count

msm:
- lockdep fix.

it6505:
- kconfig fix


Dave Airlie (3):
  Merge tag 'amd-drm-fixes-5.18-2022-05-04' of
https://gitlab.freedesktop.org/agd5f/linux into drm-fixes
  Merge tag 'drm-misc-fixes-2022-05-05' of
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
  Merge tag 'drm-msm-fixes-2022-04-30' of
https://gitlab.freedesktop.org/drm/msm into drm-fixes

Fabien Parent (1):
  drm/bridge: ite-it6505: add missing Kconfig option select

Harry Wentland (1):
  drm/amd/display: Avoid reading audio pattern past AUDIO_CHANNELS_COUNT

Javier Martinez Canillas (1):
  fbdev: Make fb_release() return -ENODEV if fbdev was unregistered

Kuogee Hsieh (1):
  drm/msm/dp: remove fail safe mode related code

Marek Marczykowski-Górecki (1):
  drm/amdgpu: do not use passthrough mode in Xen dom0

 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c |  4 +++-
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c |  2 +-
 drivers/gpu/drm/bridge/Kconfig   |  1 +
 drivers/gpu/drm/msm/dp/dp_display.c  |  6 --
 drivers/gpu/drm/msm/dp/dp_panel.c| 11 ---
 drivers/gpu/drm/msm/dp/dp_panel.h|  1 -
 drivers/video/fbdev/core/fbmem.c |  5 -
 7 files changed, 9 insertions(+), 21 deletions(-)


[PATCH] drm/rockchip: Remove unneeded semicolon

2022-05-05 Thread Haowen Bai
Fixes coccicheck warning:

drivers/gpu/drm/rockchip/rockchip_drm_vop2.c:1476:2-3: Unneeded semicolon

Signed-off-by: Haowen Bai 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0b49fed16535..7f9d88634a77 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1473,7 +1473,7 @@ static void rk3568_set_intf_mux(struct vop2_video_port 
*vp, int id,
default:
drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, 
vp->id);
return;
-   };
+   }
 
dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
 
-- 
2.7.4



[PATCH] drm/amdkfd: Return true/false (not 1/0) from bool functions

2022-05-05 Thread Haowen Bai
Return boolean values ("true" or "false") instead of 1 or 0 from bool
functions.

Signed-off-by: Haowen Bai 
---
 drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c
index c3919aaa76e6..1431f0961769 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c
@@ -241,14 +241,14 @@ static bool event_interrupt_isr_v11(struct kfd_dev *dev,
if (/*!KFD_IRQ_IS_FENCE(client_id, source_id) &&*/
(vmid < dev->vm_info.first_vmid_kfd ||
vmid > dev->vm_info.last_vmid_kfd))
-   return 0;
+   return false;
 
pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry);
context_id0 = SOC15_CONTEXT_ID0_FROM_IH_ENTRY(ih_ring_entry);
 
if ((source_id == SOC15_INTSRC_CP_END_OF_PIPE) &&
(context_id0 & AMDGPU_FENCE_MES_QUEUE_FLAG))
-   return 0;
+   return false;
 
pr_debug("client id 0x%x, source id %d, vmid %d, pasid 0x%x. raw 
data:\n",
 client_id, source_id, vmid, pasid);
@@ -258,7 +258,7 @@ static bool event_interrupt_isr_v11(struct kfd_dev *dev,
 
/* If there is no valid PASID, it's likely a bug */
if (WARN_ONCE(pasid == 0, "Bug: No PASID in KFD interrupt"))
-   return 0;
+   return false;
 
/* Interrupt types we care about: various signals and faults.
 * They will be forwarded to a work queue (see below).
-- 
2.7.4



Re: [PATCH RFC v6 00/21] DEPT(Dependency Tracker)

2022-05-05 Thread Byungchul Park
Linus wrote:
>
> On Wed, May 4, 2022 at 1:19 AM Byungchul Park  wrote:
> >
> > Hi Linus and folks,
> >
> > I've been developing a tool for detecting deadlock possibilities by
> > tracking wait/event rather than lock(?) acquisition order to try to
> > cover all synchonization machanisms.
> 
> So what is the actual status of reports these days?
> 
> Last time I looked at some reports, it gave a lot of false positives
> due to mis-understanding prepare_to_sleep().

Yes, it was. I handled the case in the following way:

1. Stage the wait at prepare_to_sleep(), which might be used at commit.
   Which has yet to be an actual wait that Dept considers.
2. If the condition for sleep is true, the wait will be committed at
   __schedule(). The wait becomes an actual one that Dept considers.
3. If the condition is false and the task gets back to TASK_RUNNING,
   clean(=reset) the staged wait.

That way, Dept only works with what actually hits to __schedule() for
the waits through sleep.

> For this all to make sense, it would need to not have false positives
> (or at least a very small number of them together with a way to sanely

Yes. I agree with you. I got rid of them that way I described above.

> get rid of them), and also have a track record of finding things that
> lockdep doesn't.

I have some reports that wait_for_completion or waitqueue is involved.
It's worth noting those are not tracked by Lockdep. I'm checking if
those are true positive or not. I will share those reports once I get
more convinced for that.

> Maybe such reports have been sent out with the current situation, and
> I haven't seen them.

Dept reports usually have been sent to me privately, not in LKML. As I
told you, I'm planning to share them.

Byungchul

> 
>  Linus
> 


Re: [PATCH v3 00/21] xen: simplify frontend side ring setup

2022-05-05 Thread Boris Ostrovsky



On 5/5/22 4:16 AM, Juergen Gross wrote:

Many Xen PV frontends share similar code for setting up a ring page
(allocating and granting access for the backend) and for tearing it
down.

Create new service functions doing all needed steps in one go.

This requires all frontends to use a common value for an invalid
grant reference in order to make the functions idempotent.

Changes in V3:
- new patches 1 and 2, comments addressed

Changes in V2:
- new patch 9 and related changes in patches 10-18



For the patches that I was explicitly copied on:


Reviewed-by: Boris Ostrovsky 



Re: [PATCH v4 11/15] drm/shmem-helper: Add generic memory shrinker

2022-05-05 Thread Dmitry Osipenko
On 5/5/22 11:34, Thomas Zimmermann wrote:
> Hi
> 
> Am 18.04.22 um 00:37 schrieb Dmitry Osipenko:
>> Introduce a common DRM SHMEM shrinker. It allows to reduce code
>> duplication among DRM drivers that implement theirs own shrinkers.
>> This is initial version of the shrinker that covers basic needs of
>> GPU drivers, both purging and eviction of shmem objects are supported.
>>
>> This patch is based on a couple ideas borrowed from Rob's Clark MSM
>> shrinker and Thomas' Zimmermann variant of SHMEM shrinker.
>>
>> In order to start using DRM SHMEM shrinker drivers should:
>>
>> 1. Implement new purge(), evict() + swap_in() GEM callbacks.
>> 2. Register shrinker using drm_gem_shmem_shrinker_register(drm_device).
>> 3. Use drm_gem_shmem_set_purgeable_and_evictable(shmem) and alike API
>>     functions to activate shrinking of GEMs.
> 
> Honestly speaking, after reading the patch and the discussion here I
> really don't like where all tis is going. The interfaces and
> implementation are overengineered.  Descisions about evicting and
> purging should be done by the memory manager. For the most part, it's
> none of the driver's business.

Daniel mostly suggesting to make interface more flexible for future
drivers, so we won't need to re-do it later on. My version of the
interface is based on what drivers need today.

Why do you think it's a problem to turn shmem helper into the simple
generic memory manager? I don't see how it's better to have drivers
duplicating the exactly same efforts and making different mistakes.

The shmem shrinker implementation is mostly based on the freedreno's
shrinker and it's very easy to enable generic shrinker for VirtIO and
Panfrost drivers. I think in the future freedreno and other drivers
could switch to use drm shmem instead of open coding the memory management.

> I'd like to ask you to reduce the scope of the patchset and build the
> shrinker only for virtio-gpu. I know that I first suggested to build
> upon shmem helpers, but it seems that it's easier to do that in a later
> patchset.

The first version of the VirtIO shrinker didn't support memory eviction.
Memory eviction support requires page fault handler to be aware of the
evicted pages, what should we do about it? The page fault handling is a
part of memory management, hence to me drm-shmem is already kinda a MM.


[PATCH v4 0/7] Make the rest of the VFIO driver interface use vfio_device

2022-05-05 Thread Jason Gunthorpe
Prior series have transformed other parts of VFIO from working on struct
device or struct vfio_group into working directly on struct
vfio_device. Based on that work we now have vfio_device's readily
available in all the drivers.

Update the rest of the driver facing API to use vfio_device as an input.

The following are switched from struct device to struct vfio_device:
  vfio_register_notifier()
  vfio_unregister_notifier()
  vfio_pin_pages()
  vfio_unpin_pages()
  vfio_dma_rw()

The following group APIs are obsoleted and removed by just using struct
vfio_device with the above:
  vfio_group_pin_pages()
  vfio_group_unpin_pages()
  vfio_group_iommu_domain()
  vfio_group_get_external_user_from_dev()

To retain the performance of the new device APIs relative to their group
versions optimize how vfio_group_add_container_user() is used to avoid
calling it when the driver must already guarantee the device is open and
the container_users incrd.

The remaining exported VFIO group interfaces are only used by kvm, and are
addressed by a parallel series.

This series is based on Christoph's gvt rework here:

 https://lore.kernel.org/all/5a8b9f48-2c32-8177-1c18-e3bd7bfde...@intel.com/

and so will need the PR merged first.

I have a followup series that needs this.

This is also part of the iommufd work - moving the driver facing interface
to vfio_device provides a much cleaner path to integrate with iommufd.

v4:
 - Use 'device' as the argument name for a struct vfio_device in vfio.c
v3: 
https://lore.kernel.org/r/0-v3-e131a9b6b467+14b6-vfio_mdev_no_group_...@nvidia.com
 - Based on VFIO's gvt/iommu merge
 - Remove mention of mdev_legacy_get_vfio_device() from commit message
 - Clarify commit message for vfio_dma_rw() conversion
 - Talk about the open_count change in the commit message
 - No code change
v2: 
https://lore.kernel.org/r/0-v2-6011bde8e0a1+5f-vfio_mdev_no_group_...@nvidia.com
 - Based on Christoph's series so mdev_legacy_get_vfio_device() is removed
 - Reflow indenting
 - Use vfio_assert_device_open() and WARN_ON_ONCE instead of open coding
   the assertion
v1: 
https://lore.kernel.org/r/0-v1-a8faf768d202+125dd-vfio_mdev_no_group_...@nvidia.com

Jason Gunthorpe (7):
  vfio: Make vfio_(un)register_notifier accept a vfio_device
  vfio/ccw: Remove mdev from struct channel_program
  vfio/mdev: Pass in a struct vfio_device * to vfio_pin/unpin_pages()
  vfio/mdev: Pass in a struct vfio_device * to vfio_dma_rw()
  drm/i915/gvt: Change from vfio_group_(un)pin_pages to
vfio_(un)pin_pages
  vfio: Remove dead code
  vfio: Remove calls to vfio_group_add_container_user()

 .../driver-api/vfio-mediated-device.rst   |   4 +-
 drivers/gpu/drm/i915/gvt/gvt.h|   5 +-
 drivers/gpu/drm/i915/gvt/kvmgt.c  |  51 ++-
 drivers/s390/cio/vfio_ccw_cp.c|  47 +--
 drivers/s390/cio/vfio_ccw_cp.h|   4 +-
 drivers/s390/cio/vfio_ccw_fsm.c   |   3 +-
 drivers/s390/cio/vfio_ccw_ops.c   |   7 +-
 drivers/s390/crypto/vfio_ap_ops.c |  23 +-
 drivers/vfio/vfio.c   | 299 +++---
 include/linux/vfio.h  |  21 +-
 10 files changed, 109 insertions(+), 355 deletions(-)


base-commit: 676d7cda1a3c19872428a9bc818577a1aafafdd5
-- 
2.36.0



[PATCH v4 4/7] vfio/mdev: Pass in a struct vfio_device * to vfio_dma_rw()

2022-05-05 Thread Jason Gunthorpe
Every caller has a readily available vfio_device pointer, use that instead
of passing in a generic struct device. Change vfio_dma_rw() to take in the
struct vfio_device and move the container users that would have been held
by vfio_group_get_external_user_from_dev() to vfio_dma_rw() directly, like
vfio_pin/unpin_pages().

Reviewed-by: Christoph Hellwig 
Reviewed-by: Kevin Tian 
Signed-off-by: Jason Gunthorpe 
---
 drivers/gpu/drm/i915/gvt/gvt.h |  4 ++--
 drivers/vfio/vfio.c| 24 +++-
 include/linux/vfio.h   |  2 +-
 3 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 03ecffc2ba56a9..5a28ee965b7f3e 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -732,7 +732,7 @@ static inline int intel_gvt_read_gpa(struct intel_vgpu 
*vgpu, unsigned long gpa,
 {
if (!vgpu->attached)
return -ESRCH;
-   return vfio_dma_rw(vgpu->vfio_group, gpa, buf, len, false);
+   return vfio_dma_rw(>vfio_device, gpa, buf, len, false);
 }
 
 /**
@@ -750,7 +750,7 @@ static inline int intel_gvt_write_gpa(struct intel_vgpu 
*vgpu,
 {
if (!vgpu->attached)
return -ESRCH;
-   return vfio_dma_rw(vgpu->vfio_group, gpa, buf, len, true);
+   return vfio_dma_rw(>vfio_device, gpa, buf, len, true);
 }
 
 void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu);
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 93caab1f29dbd7..85e1304099b8a5 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -2108,32 +2108,28 @@ EXPORT_SYMBOL(vfio_group_unpin_pages);
  * As the read/write of user space memory is conducted via the CPUs and is
  * not a real device DMA, it is not necessary to pin the user space memory.
  *
- * The caller needs to call vfio_group_get_external_user() or
- * vfio_group_get_external_user_from_dev() prior to calling this interface,
- * so as to prevent the VFIO group from disposal in the middle of the call.
- * But it can keep the reference to the VFIO group for several calls into
- * this interface.
- * After finishing using of the VFIO group, the caller needs to release the
- * VFIO group by calling vfio_group_put_external_user().
- *
- * @group [in] : VFIO group
+ * @device [in]: VFIO device
  * @user_iova [in] : base IOVA of a user space buffer
  * @data [in]  : pointer to kernel buffer
  * @len [in]   : kernel buffer length
  * @write  : indicate read or write
  * Return error code on failure or 0 on success.
  */
-int vfio_dma_rw(struct vfio_group *group, dma_addr_t user_iova,
-   void *data, size_t len, bool write)
+int vfio_dma_rw(struct vfio_device *device, dma_addr_t user_iova, void *data,
+   size_t len, bool write)
 {
struct vfio_container *container;
struct vfio_iommu_driver *driver;
int ret = 0;
 
-   if (!group || !data || len <= 0)
+   if (!data || len <= 0)
return -EINVAL;
 
-   container = group->container;
+   ret = vfio_group_add_container_user(device->group);
+   if (ret)
+   return ret;
+
+   container = device->group->container;
driver = container->iommu_driver;
 
if (likely(driver && driver->ops->dma_rw))
@@ -2142,6 +2138,8 @@ int vfio_dma_rw(struct vfio_group *group, dma_addr_t 
user_iova,
else
ret = -ENOTTY;
 
+   vfio_group_try_dissolve_container(device->group);
+
return ret;
 }
 EXPORT_SYMBOL(vfio_dma_rw);
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index bddc70f88899c3..8a151025871776 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -161,7 +161,7 @@ extern int vfio_group_pin_pages(struct vfio_group *group,
 extern int vfio_group_unpin_pages(struct vfio_group *group,
  unsigned long *user_iova_pfn, int npage);
 
-extern int vfio_dma_rw(struct vfio_group *group, dma_addr_t user_iova,
+extern int vfio_dma_rw(struct vfio_device *device, dma_addr_t user_iova,
   void *data, size_t len, bool write);
 
 extern struct iommu_domain *vfio_group_iommu_domain(struct vfio_group *group);
-- 
2.36.0



[PATCH v4 6/7] vfio: Remove dead code

2022-05-05 Thread Jason Gunthorpe
Now that callers have been updated to use the vfio_device APIs the driver
facing group interface is no longer used, delete it:

- vfio_group_get_external_user_from_dev()
- vfio_group_pin_pages()
- vfio_group_unpin_pages()
- vfio_group_iommu_domain()

Reviewed-by: Christoph Hellwig 
Reviewed-by: Kevin Tian 
Signed-off-by: Jason Gunthorpe 
--
FIXME: vfio_group_put_external_user() is removable too when combined with the 
KVM series
---
 drivers/vfio/vfio.c  | 151 ---
 include/linux/vfio.h |  11 
 2 files changed, 162 deletions(-)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 85e1304099b8a5..c651c4805acd59 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1732,44 +1732,6 @@ struct vfio_group *vfio_group_get_external_user(struct 
file *filep)
 }
 EXPORT_SYMBOL_GPL(vfio_group_get_external_user);
 
-/*
- * External user API, exported by symbols to be linked dynamically.
- * The external user passes in a device pointer
- * to verify that:
- * - A VFIO group is assiciated with the device;
- * - IOMMU is set for the group.
- * If both checks passed, vfio_group_get_external_user_from_dev()
- * increments the container user counter to prevent the VFIO group
- * from disposal before external user exits and returns the pointer
- * to the VFIO group.
- *
- * When the external user finishes using the VFIO group, it calls
- * vfio_group_put_external_user() to release the VFIO group and
- * decrement the container user counter.
- *
- * @dev [in]   : device
- * Return error PTR or pointer to VFIO group.
- */
-
-struct vfio_group *vfio_group_get_external_user_from_dev(struct device *dev)
-{
-   struct vfio_group *group;
-   int ret;
-
-   group = vfio_group_get_from_dev(dev);
-   if (!group)
-   return ERR_PTR(-ENODEV);
-
-   ret = vfio_group_add_container_user(group);
-   if (ret) {
-   vfio_group_put(group);
-   return ERR_PTR(ret);
-   }
-
-   return group;
-}
-EXPORT_SYMBOL_GPL(vfio_group_get_external_user_from_dev);
-
 void vfio_group_put_external_user(struct vfio_group *group)
 {
vfio_group_try_dissolve_container(group);
@@ -2003,101 +1965,6 @@ int vfio_unpin_pages(struct vfio_device *device, 
unsigned long *user_pfn,
 }
 EXPORT_SYMBOL(vfio_unpin_pages);
 
-/*
- * Pin a set of guest IOVA PFNs and return their associated host PFNs for a
- * VFIO group.
- *
- * The caller needs to call vfio_group_get_external_user() or
- * vfio_group_get_external_user_from_dev() prior to calling this interface,
- * so as to prevent the VFIO group from disposal in the middle of the call.
- * But it can keep the reference to the VFIO group for several calls into
- * this interface.
- * After finishing using of the VFIO group, the caller needs to release the
- * VFIO group by calling vfio_group_put_external_user().
- *
- * @group [in] : VFIO group
- * @user_iova_pfn [in] : array of user/guest IOVA PFNs to be pinned.
- * @npage [in] : count of elements in user_iova_pfn array.
- *   This count should not be greater
- *   VFIO_PIN_PAGES_MAX_ENTRIES.
- * @prot [in]  : protection flags
- * @phys_pfn [out] : array of host PFNs
- * Return error or number of pages pinned.
- */
-int vfio_group_pin_pages(struct vfio_group *group,
-unsigned long *user_iova_pfn, int npage,
-int prot, unsigned long *phys_pfn)
-{
-   struct vfio_container *container;
-   struct vfio_iommu_driver *driver;
-   int ret;
-
-   if (!group || !user_iova_pfn || !phys_pfn || !npage)
-   return -EINVAL;
-
-   if (group->dev_counter > 1)
-   return -EINVAL;
-
-   if (npage > VFIO_PIN_PAGES_MAX_ENTRIES)
-   return -E2BIG;
-
-   container = group->container;
-   driver = container->iommu_driver;
-   if (likely(driver && driver->ops->pin_pages))
-   ret = driver->ops->pin_pages(container->iommu_data,
-group->iommu_group, user_iova_pfn,
-npage, prot, phys_pfn);
-   else
-   ret = -ENOTTY;
-
-   return ret;
-}
-EXPORT_SYMBOL(vfio_group_pin_pages);
-
-/*
- * Unpin a set of guest IOVA PFNs for a VFIO group.
- *
- * The caller needs to call vfio_group_get_external_user() or
- * vfio_group_get_external_user_from_dev() prior to calling this interface,
- * so as to prevent the VFIO group from disposal in the middle of the call.
- * But it can keep the reference to the VFIO group for several calls into
- * this interface.
- * After finishing using of the VFIO group, the caller needs to release the
- * VFIO group by calling vfio_group_put_external_user().
- *
- * @group [in] : vfio group
- * @user_iova_pfn [in] : array of user/guest IOVA PFNs to be unpinned.
- * @npage [in] : count of elements in user_iova_pfn array.
- *  

[PATCH v4 2/7] vfio/ccw: Remove mdev from struct channel_program

2022-05-05 Thread Jason Gunthorpe
The next patch wants the vfio_device instead. There is no reason to store
a pointer here since we can container_of back to the vfio_device.

Reviewed-by: Eric Farman 
Signed-off-by: Jason Gunthorpe 
---
 drivers/s390/cio/vfio_ccw_cp.c  | 47 -
 drivers/s390/cio/vfio_ccw_cp.h  |  4 +--
 drivers/s390/cio/vfio_ccw_fsm.c |  3 +--
 3 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c
index 8d1b2771c1aa02..7a1cf3091cd647 100644
--- a/drivers/s390/cio/vfio_ccw_cp.c
+++ b/drivers/s390/cio/vfio_ccw_cp.c
@@ -16,6 +16,7 @@
 #include 
 
 #include "vfio_ccw_cp.h"
+#include "vfio_ccw_private.h"
 
 struct pfn_array {
/* Starting guest physical I/O address. */
@@ -98,17 +99,17 @@ static int pfn_array_alloc(struct pfn_array *pa, u64 iova, 
unsigned int len)
  * If the pin request partially succeeds, or fails completely,
  * all pages are left unpinned and a negative error value is returned.
  */
-static int pfn_array_pin(struct pfn_array *pa, struct device *mdev)
+static int pfn_array_pin(struct pfn_array *pa, struct vfio_device *vdev)
 {
int ret = 0;
 
-   ret = vfio_pin_pages(mdev, pa->pa_iova_pfn, pa->pa_nr,
+   ret = vfio_pin_pages(vdev->dev, pa->pa_iova_pfn, pa->pa_nr,
 IOMMU_READ | IOMMU_WRITE, pa->pa_pfn);
 
if (ret < 0) {
goto err_out;
} else if (ret > 0 && ret != pa->pa_nr) {
-   vfio_unpin_pages(mdev, pa->pa_iova_pfn, ret);
+   vfio_unpin_pages(vdev->dev, pa->pa_iova_pfn, ret);
ret = -EINVAL;
goto err_out;
}
@@ -122,11 +123,11 @@ static int pfn_array_pin(struct pfn_array *pa, struct 
device *mdev)
 }
 
 /* Unpin the pages before releasing the memory. */
-static void pfn_array_unpin_free(struct pfn_array *pa, struct device *mdev)
+static void pfn_array_unpin_free(struct pfn_array *pa, struct vfio_device 
*vdev)
 {
/* Only unpin if any pages were pinned to begin with */
if (pa->pa_nr)
-   vfio_unpin_pages(mdev, pa->pa_iova_pfn, pa->pa_nr);
+   vfio_unpin_pages(vdev->dev, pa->pa_iova_pfn, pa->pa_nr);
pa->pa_nr = 0;
kfree(pa->pa_iova_pfn);
 }
@@ -190,8 +191,7 @@ static void convert_ccw0_to_ccw1(struct ccw1 *source, 
unsigned long len)
  * Within the domain (@mdev), copy @n bytes from a guest physical
  * address (@iova) to a host physical address (@to).
  */
-static long copy_from_iova(struct device *mdev,
-  void *to, u64 iova,
+static long copy_from_iova(struct vfio_device *vdev, void *to, u64 iova,
   unsigned long n)
 {
struct pfn_array pa = {0};
@@ -203,9 +203,9 @@ static long copy_from_iova(struct device *mdev,
if (ret < 0)
return ret;
 
-   ret = pfn_array_pin(, mdev);
+   ret = pfn_array_pin(, vdev);
if (ret < 0) {
-   pfn_array_unpin_free(, mdev);
+   pfn_array_unpin_free(, vdev);
return ret;
}
 
@@ -226,7 +226,7 @@ static long copy_from_iova(struct device *mdev,
break;
}
 
-   pfn_array_unpin_free(, mdev);
+   pfn_array_unpin_free(, vdev);
 
return l;
 }
@@ -423,11 +423,13 @@ static int ccwchain_loop_tic(struct ccwchain *chain,
 
 static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
 {
+   struct vfio_device *vdev =
+   _of(cp, struct vfio_ccw_private, cp)->vdev;
struct ccwchain *chain;
int len, ret;
 
/* Copy 2K (the most we support today) of possible CCWs */
-   len = copy_from_iova(cp->mdev, cp->guest_cp, cda,
+   len = copy_from_iova(vdev, cp->guest_cp, cda,
 CCWCHAIN_LEN_MAX * sizeof(struct ccw1));
if (len)
return len;
@@ -508,6 +510,8 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
 int idx,
 struct channel_program *cp)
 {
+   struct vfio_device *vdev =
+   _of(cp, struct vfio_ccw_private, cp)->vdev;
struct ccw1 *ccw;
struct pfn_array *pa;
u64 iova;
@@ -526,7 +530,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
if (ccw_is_idal(ccw)) {
/* Read first IDAW to see if it's 4K-aligned or not. */
/* All subsequent IDAws will be 4K-aligned. */
-   ret = copy_from_iova(cp->mdev, , ccw->cda, sizeof(iova));
+   ret = copy_from_iova(vdev, , ccw->cda, sizeof(iova));
if (ret)
return ret;
} else {
@@ -555,7 +559,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
 
if (ccw_is_idal(ccw)) {
/* Copy guest IDAL into host IDAL */
-   ret = copy_from_iova(cp->mdev, idaws, ccw->cda, idal_len);
+   ret = 

[PATCH v4 7/7] vfio: Remove calls to vfio_group_add_container_user()

2022-05-05 Thread Jason Gunthorpe
When the open_device() op is called the container_users is incremented and
held incremented until close_device(). Thus, so long as drivers call
functions within their open_device()/close_device() region they do not
need to worry about the container_users.

These functions can all only be called between open_device() and
close_device():

  vfio_pin_pages()
  vfio_unpin_pages()
  vfio_dma_rw()
  vfio_register_notifier()
  vfio_unregister_notifier()

Eliminate the calls to vfio_group_add_container_user() and add
vfio_assert_device_open() to detect driver mis-use. This causes the
close_device() op to check device->open_count so always leave it elevated
while calling the op.

Reviewed-by: Christoph Hellwig 
Reviewed-by: Kevin Tian 
Signed-off-by: Jason Gunthorpe 
---
 drivers/vfio/vfio.c | 80 ++---
 1 file changed, 17 insertions(+), 63 deletions(-)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index c651c4805acd59..8bb38941c1dfd8 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1115,6 +1115,12 @@ static int vfio_group_add_container_user(struct 
vfio_group *group)
 
 static const struct file_operations vfio_device_fops;
 
+/* true if the vfio_device has open_device() called but not close_device() */
+static bool vfio_assert_device_open(struct vfio_device *device)
+{
+   return !WARN_ON_ONCE(!READ_ONCE(device->open_count));
+}
+
 static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
 {
struct vfio_device *device;
@@ -1329,8 +1335,10 @@ static int vfio_device_fops_release(struct inode *inode, 
struct file *filep)
struct vfio_device *device = filep->private_data;
 
mutex_lock(>dev_set->lock);
-   if (!--device->open_count && device->ops->close_device)
+   vfio_assert_device_open(device);
+   if (device->open_count == 1 && device->ops->close_device)
device->ops->close_device(device);
+   device->open_count--;
mutex_unlock(>dev_set->lock);
 
module_put(device->dev->driver->owner);
@@ -1897,7 +1905,8 @@ int vfio_pin_pages(struct vfio_device *device, unsigned 
long *user_pfn,
struct vfio_iommu_driver *driver;
int ret;
 
-   if (!user_pfn || !phys_pfn || !npage)
+   if (!user_pfn || !phys_pfn || !npage ||
+   !vfio_assert_device_open(device))
return -EINVAL;
 
if (npage > VFIO_PIN_PAGES_MAX_ENTRIES)
@@ -1906,10 +1915,6 @@ int vfio_pin_pages(struct vfio_device *device, unsigned 
long *user_pfn,
if (group->dev_counter > 1)
return -EINVAL;
 
-   ret = vfio_group_add_container_user(group);
-   if (ret)
-   return ret;
-
container = group->container;
driver = container->iommu_driver;
if (likely(driver && driver->ops->pin_pages))
@@ -1919,8 +1924,6 @@ int vfio_pin_pages(struct vfio_device *device, unsigned 
long *user_pfn,
else
ret = -ENOTTY;
 
-   vfio_group_try_dissolve_container(group);
-
return ret;
 }
 EXPORT_SYMBOL(vfio_pin_pages);
@@ -1941,16 +1944,12 @@ int vfio_unpin_pages(struct vfio_device *device, 
unsigned long *user_pfn,
struct vfio_iommu_driver *driver;
int ret;
 
-   if (!user_pfn || !npage)
+   if (!user_pfn || !npage || !vfio_assert_device_open(device))
return -EINVAL;
 
if (npage > VFIO_PIN_PAGES_MAX_ENTRIES)
return -E2BIG;
 
-   ret = vfio_group_add_container_user(device->group);
-   if (ret)
-   return ret;
-
container = device->group->container;
driver = container->iommu_driver;
if (likely(driver && driver->ops->unpin_pages))
@@ -1959,8 +1958,6 @@ int vfio_unpin_pages(struct vfio_device *device, unsigned 
long *user_pfn,
else
ret = -ENOTTY;
 
-   vfio_group_try_dissolve_container(device->group);
-
return ret;
 }
 EXPORT_SYMBOL(vfio_unpin_pages);
@@ -1989,13 +1986,9 @@ int vfio_dma_rw(struct vfio_device *device, dma_addr_t 
user_iova, void *data,
struct vfio_iommu_driver *driver;
int ret = 0;
 
-   if (!data || len <= 0)
+   if (!data || len <= 0 || !vfio_assert_device_open(device))
return -EINVAL;
 
-   ret = vfio_group_add_container_user(device->group);
-   if (ret)
-   return ret;
-
container = device->group->container;
driver = container->iommu_driver;
 
@@ -2004,9 +1997,6 @@ int vfio_dma_rw(struct vfio_device *device, dma_addr_t 
user_iova, void *data,
  user_iova, data, len, write);
else
ret = -ENOTTY;
-
-   vfio_group_try_dissolve_container(device->group);
-
return ret;
 }
 EXPORT_SYMBOL(vfio_dma_rw);
@@ -2019,10 +2009,6 @@ static int vfio_register_iommu_notifier(struct 
vfio_group *group,
struct vfio_iommu_driver *driver;
int ret;
 
-   ret = 

[PATCH v4 1/7] vfio: Make vfio_(un)register_notifier accept a vfio_device

2022-05-05 Thread Jason Gunthorpe
All callers have a struct vfio_device trivially available, pass it in
directly and avoid calling the expensive vfio_group_get_from_dev().

Acked-by: Eric Farman 
Reviewed-by: Jason J. Herne 
Reviewed-by: Tony Krowiak 
Reviewed-by: Kevin Tian 
Reviewed-by: Christoph Hellwig 
Signed-off-by: Jason Gunthorpe 
---
 drivers/gpu/drm/i915/gvt/kvmgt.c  | 24 
 drivers/s390/cio/vfio_ccw_ops.c   |  7 +++
 drivers/s390/crypto/vfio_ap_ops.c | 14 +++---
 drivers/vfio/vfio.c   | 28 +---
 include/linux/vfio.h  |  4 ++--
 5 files changed, 33 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 0787ba5c301f5e..1cec4f1fdfaced 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -810,8 +810,8 @@ static int intel_vgpu_open_device(struct vfio_device 
*vfio_dev)
vgpu->group_notifier.notifier_call = intel_vgpu_group_notifier;
 
events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
-   ret = vfio_register_notifier(vfio_dev->dev, VFIO_IOMMU_NOTIFY, ,
-   >iommu_notifier);
+   ret = vfio_register_notifier(vfio_dev, VFIO_IOMMU_NOTIFY, ,
+>iommu_notifier);
if (ret != 0) {
gvt_vgpu_err("vfio_register_notifier for iommu failed: %d\n",
ret);
@@ -819,8 +819,8 @@ static int intel_vgpu_open_device(struct vfio_device 
*vfio_dev)
}
 
events = VFIO_GROUP_NOTIFY_SET_KVM;
-   ret = vfio_register_notifier(vfio_dev->dev, VFIO_GROUP_NOTIFY, ,
-   >group_notifier);
+   ret = vfio_register_notifier(vfio_dev, VFIO_GROUP_NOTIFY, ,
+>group_notifier);
if (ret != 0) {
gvt_vgpu_err("vfio_register_notifier for group failed: %d\n",
ret);
@@ -873,12 +873,12 @@ static int intel_vgpu_open_device(struct vfio_device 
*vfio_dev)
vgpu->vfio_group = NULL;
 
 undo_register:
-   vfio_unregister_notifier(vfio_dev->dev, VFIO_GROUP_NOTIFY,
-   >group_notifier);
+   vfio_unregister_notifier(vfio_dev, VFIO_GROUP_NOTIFY,
+>group_notifier);
 
 undo_iommu:
-   vfio_unregister_notifier(vfio_dev->dev, VFIO_IOMMU_NOTIFY,
-   >iommu_notifier);
+   vfio_unregister_notifier(vfio_dev, VFIO_IOMMU_NOTIFY,
+>iommu_notifier);
 out:
return ret;
 }
@@ -907,13 +907,13 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
 
intel_gvt_release_vgpu(vgpu);
 
-   ret = vfio_unregister_notifier(vgpu->vfio_device.dev, VFIO_IOMMU_NOTIFY,
-   >iommu_notifier);
+   ret = vfio_unregister_notifier(>vfio_device, VFIO_IOMMU_NOTIFY,
+  >iommu_notifier);
drm_WARN(>drm, ret,
 "vfio_unregister_notifier for iommu failed: %d\n", ret);
 
-   ret = vfio_unregister_notifier(vgpu->vfio_device.dev, VFIO_GROUP_NOTIFY,
-   >group_notifier);
+   ret = vfio_unregister_notifier(>vfio_device, VFIO_GROUP_NOTIFY,
+  >group_notifier);
drm_WARN(>drm, ret,
 "vfio_unregister_notifier for group failed: %d\n", ret);
 
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index c4d60cdbf247bf..b49e2e9db2dc6f 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -183,7 +183,7 @@ static int vfio_ccw_mdev_open_device(struct vfio_device 
*vdev)
 
private->nb.notifier_call = vfio_ccw_mdev_notifier;
 
-   ret = vfio_register_notifier(vdev->dev, VFIO_IOMMU_NOTIFY,
+   ret = vfio_register_notifier(vdev, VFIO_IOMMU_NOTIFY,
 , >nb);
if (ret)
return ret;
@@ -204,8 +204,7 @@ static int vfio_ccw_mdev_open_device(struct vfio_device 
*vdev)
 
 out_unregister:
vfio_ccw_unregister_dev_regions(private);
-   vfio_unregister_notifier(vdev->dev, VFIO_IOMMU_NOTIFY,
->nb);
+   vfio_unregister_notifier(vdev, VFIO_IOMMU_NOTIFY, >nb);
return ret;
 }
 
@@ -223,7 +222,7 @@ static void vfio_ccw_mdev_close_device(struct vfio_device 
*vdev)
 
cp_free(>cp);
vfio_ccw_unregister_dev_regions(private);
-   vfio_unregister_notifier(vdev->dev, VFIO_IOMMU_NOTIFY, >nb);
+   vfio_unregister_notifier(vdev, VFIO_IOMMU_NOTIFY, >nb);
 }
 
 static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private,
diff --git a/drivers/s390/crypto/vfio_ap_ops.c 
b/drivers/s390/crypto/vfio_ap_ops.c
index ee0a3bf8f476ca..bfa7ee6ef532d9 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -1406,21 +1406,21 @@ 

[PATCH v4 5/7] drm/i915/gvt: Change from vfio_group_(un)pin_pages to vfio_(un)pin_pages

2022-05-05 Thread Jason Gunthorpe
Use the existing vfio_device versions of vfio_(un)pin_pages(). There is no
reason to use a group interface here, kvmgt has easy access to a
vfio_device.

Delete kvmgt_vdev::vfio_group since these calls were the last users.

Reviewed-by: Kevin Tian 
Reviewed-by: Christoph Hellwig 
Signed-off-by: Jason Gunthorpe 
---
 drivers/gpu/drm/i915/gvt/gvt.h   |  1 -
 drivers/gpu/drm/i915/gvt/kvmgt.c | 27 ++-
 2 files changed, 6 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 5a28ee965b7f3e..2af4c83e733c6c 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -231,7 +231,6 @@ struct intel_vgpu {
struct kvm *kvm;
struct work_struct release_work;
atomic_t released;
-   struct vfio_group *vfio_group;
 
struct kvm_page_track_notifier_node track_node;
 #define NR_BKT (1 << 18)
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1cec4f1fdfaced..7655ffa97d5116 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -243,7 +243,7 @@ static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, 
unsigned long gfn,
for (npage = 0; npage < total_pages; npage++) {
unsigned long cur_gfn = gfn + npage;
 
-   ret = vfio_group_unpin_pages(vgpu->vfio_group, _gfn, 1);
+   ret = vfio_unpin_pages(>vfio_device, _gfn, 1);
drm_WARN_ON(>drm, ret != 1);
}
 }
@@ -266,8 +266,8 @@ static int gvt_pin_guest_page(struct intel_vgpu *vgpu, 
unsigned long gfn,
unsigned long cur_gfn = gfn + npage;
unsigned long pfn;
 
-   ret = vfio_group_pin_pages(vgpu->vfio_group, _gfn, 1,
-  IOMMU_READ | IOMMU_WRITE, );
+   ret = vfio_pin_pages(>vfio_device, _gfn, 1,
+IOMMU_READ | IOMMU_WRITE, );
if (ret != 1) {
gvt_vgpu_err("vfio_pin_pages failed for gfn 0x%lx, ret 
%d\n",
 cur_gfn, ret);
@@ -804,7 +804,6 @@ static int intel_vgpu_open_device(struct vfio_device 
*vfio_dev)
struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
unsigned long events;
int ret;
-   struct vfio_group *vfio_group;
 
vgpu->iommu_notifier.notifier_call = intel_vgpu_iommu_notifier;
vgpu->group_notifier.notifier_call = intel_vgpu_group_notifier;
@@ -827,28 +826,19 @@ static int intel_vgpu_open_device(struct vfio_device 
*vfio_dev)
goto undo_iommu;
}
 
-   vfio_group =
-   vfio_group_get_external_user_from_dev(vgpu->vfio_device.dev);
-   if (IS_ERR_OR_NULL(vfio_group)) {
-   ret = !vfio_group ? -EFAULT : PTR_ERR(vfio_group);
-   gvt_vgpu_err("vfio_group_get_external_user_from_dev failed\n");
-   goto undo_register;
-   }
-   vgpu->vfio_group = vfio_group;
-
ret = -EEXIST;
if (vgpu->attached)
-   goto undo_group;
+   goto undo_register;
 
ret = -ESRCH;
if (!vgpu->kvm || vgpu->kvm->mm != current->mm) {
gvt_vgpu_err("KVM is required to use Intel vGPU\n");
-   goto undo_group;
+   goto undo_register;
}
 
ret = -EEXIST;
if (__kvmgt_vgpu_exist(vgpu))
-   goto undo_group;
+   goto undo_register;
 
vgpu->attached = true;
kvm_get_kvm(vgpu->kvm);
@@ -868,10 +858,6 @@ static int intel_vgpu_open_device(struct vfio_device 
*vfio_dev)
atomic_set(>released, 0);
return 0;
 
-undo_group:
-   vfio_group_put_external_user(vgpu->vfio_group);
-   vgpu->vfio_group = NULL;
-
 undo_register:
vfio_unregister_notifier(vfio_dev, VFIO_GROUP_NOTIFY,
 >group_notifier);
@@ -925,7 +911,6 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
gvt_cache_destroy(vgpu);
 
intel_vgpu_release_msi_eventfd_ctx(vgpu);
-   vfio_group_put_external_user(vgpu->vfio_group);
 
vgpu->kvm = NULL;
vgpu->attached = false;
-- 
2.36.0



[PATCH v4 3/7] vfio/mdev: Pass in a struct vfio_device * to vfio_pin/unpin_pages()

2022-05-05 Thread Jason Gunthorpe
Every caller has a readily available vfio_device pointer, use that instead
of passing in a generic struct device. The struct vfio_device already
contains the group we need so this avoids complexity, extra refcountings,
and a confusing lifecycle model.

Reviewed-by: Christoph Hellwig 
Acked-by: Eric Farman 
Reviewed-by: Jason J. Herne 
Reviewed-by: Tony Krowiak 
Reviewed-by: Kevin Tian 
Signed-off-by: Jason Gunthorpe 
---
 .../driver-api/vfio-mediated-device.rst   |  4 +-
 drivers/s390/cio/vfio_ccw_cp.c|  6 +--
 drivers/s390/crypto/vfio_ap_ops.c |  9 ++--
 drivers/vfio/vfio.c   | 46 +++
 include/linux/vfio.h  |  4 +-
 5 files changed, 27 insertions(+), 42 deletions(-)

diff --git a/Documentation/driver-api/vfio-mediated-device.rst 
b/Documentation/driver-api/vfio-mediated-device.rst
index 784bbeb22adcf5..eded8719180fba 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -262,10 +262,10 @@ Translation APIs for Mediated Devices
 The following APIs are provided for translating user pfn to host pfn in a VFIO
 driver::
 
-   extern int vfio_pin_pages(struct device *dev, unsigned long *user_pfn,
+   int vfio_pin_pages(struct vfio_device *device, unsigned long *user_pfn,
  int npage, int prot, unsigned long *phys_pfn);
 
-   extern int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn,
+   int vfio_unpin_pages(struct vfio_device *device, unsigned long 
*user_pfn,
int npage);
 
 These functions call back into the back-end IOMMU module by using the pin_pages
diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c
index 7a1cf3091cd647..0c2be9421ab78f 100644
--- a/drivers/s390/cio/vfio_ccw_cp.c
+++ b/drivers/s390/cio/vfio_ccw_cp.c
@@ -103,13 +103,13 @@ static int pfn_array_pin(struct pfn_array *pa, struct 
vfio_device *vdev)
 {
int ret = 0;
 
-   ret = vfio_pin_pages(vdev->dev, pa->pa_iova_pfn, pa->pa_nr,
+   ret = vfio_pin_pages(vdev, pa->pa_iova_pfn, pa->pa_nr,
 IOMMU_READ | IOMMU_WRITE, pa->pa_pfn);
 
if (ret < 0) {
goto err_out;
} else if (ret > 0 && ret != pa->pa_nr) {
-   vfio_unpin_pages(vdev->dev, pa->pa_iova_pfn, ret);
+   vfio_unpin_pages(vdev, pa->pa_iova_pfn, ret);
ret = -EINVAL;
goto err_out;
}
@@ -127,7 +127,7 @@ static void pfn_array_unpin_free(struct pfn_array *pa, 
struct vfio_device *vdev)
 {
/* Only unpin if any pages were pinned to begin with */
if (pa->pa_nr)
-   vfio_unpin_pages(vdev->dev, pa->pa_iova_pfn, pa->pa_nr);
+   vfio_unpin_pages(vdev, pa->pa_iova_pfn, pa->pa_nr);
pa->pa_nr = 0;
kfree(pa->pa_iova_pfn);
 }
diff --git a/drivers/s390/crypto/vfio_ap_ops.c 
b/drivers/s390/crypto/vfio_ap_ops.c
index bfa7ee6ef532d9..e8914024f5b1af 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -124,8 +124,7 @@ static void vfio_ap_free_aqic_resources(struct 
vfio_ap_queue *q)
q->saved_isc = VFIO_AP_ISC_INVALID;
}
if (q->saved_pfn && !WARN_ON(!q->matrix_mdev)) {
-   vfio_unpin_pages(mdev_dev(q->matrix_mdev->mdev),
->saved_pfn, 1);
+   vfio_unpin_pages(>matrix_mdev->vdev, >saved_pfn, 1);
q->saved_pfn = 0;
}
 }
@@ -258,7 +257,7 @@ static struct ap_queue_status vfio_ap_irq_enable(struct 
vfio_ap_queue *q,
return status;
}
 
-   ret = vfio_pin_pages(mdev_dev(q->matrix_mdev->mdev), _pfn, 1,
+   ret = vfio_pin_pages(>matrix_mdev->vdev, _pfn, 1,
 IOMMU_READ | IOMMU_WRITE, _pfn);
switch (ret) {
case 1:
@@ -301,7 +300,7 @@ static struct ap_queue_status vfio_ap_irq_enable(struct 
vfio_ap_queue *q,
break;
case AP_RESPONSE_OTHERWISE_CHANGED:
/* We could not modify IRQ setings: clear new configuration */
-   vfio_unpin_pages(mdev_dev(q->matrix_mdev->mdev), _pfn, 1);
+   vfio_unpin_pages(>matrix_mdev->vdev, _pfn, 1);
kvm_s390_gisc_unregister(kvm, isc);
break;
default:
@@ -1250,7 +1249,7 @@ static int vfio_ap_mdev_iommu_notifier(struct 
notifier_block *nb,
struct vfio_iommu_type1_dma_unmap *unmap = data;
unsigned long g_pfn = unmap->iova >> PAGE_SHIFT;
 
-   vfio_unpin_pages(mdev_dev(matrix_mdev->mdev), _pfn, 1);
+   vfio_unpin_pages(_mdev->vdev, _pfn, 1);
return NOTIFY_OK;
}
 
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index d70890ab9cea92..93caab1f29dbd7 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1919,7 +1919,7 @@ 

Re: (subset) [PATCH 1/2] [RFC] regmap: Add bulk read/write callbacks into regmap_config

2022-05-05 Thread Marek Vasut

On 5/5/22 23:08, Mark Brown wrote:

On Thu, May 05, 2022 at 07:32:23PM +0200, Marek Vasut wrote:

On 5/5/22 17:12, Mark Brown wrote:

On Sat, 30 Apr 2022 04:51:44 +0200, Marek Vasut wrote:



Currently the regmap_config structure only allows the user to implement
single element register read/write using .reg_read/.reg_write callbacks.



[1/2] regmap: Add bulk read/write callbacks into regmap_config
commit: d77e745613680c54708470402e2b623dcd769681



I was really hoping this would get a lot more review / comments before this
is applied.


I can easily punt for this release, though TBH I'm not anticipating huge
numbers of comments on a regmap patch unless it breaks things for
people, they tend to be very quiet.


In that case, let's wait and see ...


I did go through it and didn't spot
any issues so it seemed like the testing coverage would be useful here.
Are there specific things you're worried about that you'd like feedback
on?


Plumbing on core code is worrying.


[PATCH -next 2/2] drm/amdkfd: Return true/false (not 1/0) from bool functions

2022-05-05 Thread Yang Li
Return boolean values ("true" or "false") instead of 1 or 0 from bool
functions. This fixes the following warnings from coccicheck:

./drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c:244:9-10: WARNING:
return of 0/1 in function 'event_interrupt_isr_v11' with return type
bool

Reported-by: Abaci Robot 
Signed-off-by: Yang Li 
---
 drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c
index c3919aaa76e6..1431f0961769 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c
@@ -241,14 +241,14 @@ static bool event_interrupt_isr_v11(struct kfd_dev *dev,
if (/*!KFD_IRQ_IS_FENCE(client_id, source_id) &&*/
(vmid < dev->vm_info.first_vmid_kfd ||
vmid > dev->vm_info.last_vmid_kfd))
-   return 0;
+   return false;
 
pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry);
context_id0 = SOC15_CONTEXT_ID0_FROM_IH_ENTRY(ih_ring_entry);
 
if ((source_id == SOC15_INTSRC_CP_END_OF_PIPE) &&
(context_id0 & AMDGPU_FENCE_MES_QUEUE_FLAG))
-   return 0;
+   return false;
 
pr_debug("client id 0x%x, source id %d, vmid %d, pasid 0x%x. raw 
data:\n",
 client_id, source_id, vmid, pasid);
@@ -258,7 +258,7 @@ static bool event_interrupt_isr_v11(struct kfd_dev *dev,
 
/* If there is no valid PASID, it's likely a bug */
if (WARN_ONCE(pasid == 0, "Bug: No PASID in KFD interrupt"))
-   return 0;
+   return false;
 
/* Interrupt types we care about: various signals and faults.
 * They will be forwarded to a work queue (see below).
-- 
2.20.1.7.g153144c



[PATCH -next] drm/rockchip: remove unneeded semicolon

2022-05-05 Thread Yang Li
Eliminate the following coccicheck warning:
./drivers/gpu/drm/rockchip/rockchip_drm_vop2.c:1476:2-3: Unneeded
semicolon

Reported-by: Abaci Robot 
Signed-off-by: Yang Li 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0b49fed16535..7f9d88634a77 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1473,7 +1473,7 @@ static void rk3568_set_intf_mux(struct vop2_video_port 
*vp, int id,
default:
drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, 
vp->id);
return;
-   };
+   }
 
dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
 
-- 
2.20.1.7.g153144c



[PATCH -next 1/2] drm/amdgpu/gfx11: remove unneeded semicolon

2022-05-05 Thread Yang Li
Eliminate the following coccicheck warning:
./drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:1222:2-3: Unneeded semicolon

Reported-by: Abaci Robot 
Signed-off-by: Yang Li 
---
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 184bf554acca..d2ab325e40b4 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -1219,7 +1219,7 @@ static void gfx_v11_0_parse_rlc_toc(struct amdgpu_device 
*adev, void *rlc_toc)
rlc_autoload_info[ucode->id].size = ucode->size * 4;
 
ucode++;
-   };
+   }
 }
 
 static uint32_t gfx_v11_0_calc_toc_total_size(struct amdgpu_device *adev)
-- 
2.20.1.7.g153144c



Re: [PATCH v1 04/15] mm: add device coherent checker to remove migration pte

2022-05-05 Thread Alistair Popple
"Sierra Guiza, Alejandro (Alex)"  writes:

> @apop...@nvidia.com Could you please check this patch? It's somehow related to
> migrate_device_page() for long term device coherent pages.

Sure thing. This whole series is in my queue of things to review once I make it 
home from LSF/MM.

- Alistair

> Regards,
> Alex Sierra
>> -Original Message-
>> From: amd-gfx  On Behalf Of Alex
>> Sierra
>> Sent: Thursday, May 5, 2022 4:34 PM
>> To: j...@nvidia.com
>> Cc: rcampb...@nvidia.com; wi...@infradead.org; da...@redhat.com;
>> Kuehling, Felix ; apop...@nvidia.com; amd-
>> g...@lists.freedesktop.org; linux-...@vger.kernel.org; linux...@kvack.org;
>> jgli...@redhat.com; dri-devel@lists.freedesktop.org; akpm@linux-
>> foundation.org; linux-e...@vger.kernel.org; h...@lst.de
>> Subject: [PATCH v1 04/15] mm: add device coherent checker to remove
>> migration pte
>>
>> During remove_migration_pte(), entries for device coherent type pages that
>> were not created through special migration ptes, ignore _PAGE_RW flag. This
>> path can be found at migrate_device_page(), where valid vma is not
>> required. In this case, migrate_vma_collect_pmd() is not called and special
>> migration ptes are not set.
>>
>> Signed-off-by: Alex Sierra 
>> ---
>>  mm/migrate.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/mm/migrate.c b/mm/migrate.c index
>> 6c31ee1e1c9b..e18ddee56f37 100644
>> --- a/mm/migrate.c
>> +++ b/mm/migrate.c
>> @@ -206,7 +206,8 @@ static bool remove_migration_pte(struct folio *folio,
>>   * Recheck VMA as permissions can change since migration
>> started
>>   */
>>  entry = pte_to_swp_entry(*pvmw.pte);
>> -if (is_writable_migration_entry(entry))
>> +if (is_writable_migration_entry(entry) ||
>> +is_device_coherent_page(pfn_to_page(pvmw.pfn)))
>>  pte = maybe_mkwrite(pte, vma);
>>  else if (pte_swp_uffd_wp(*pvmw.pte))
>>  pte = pte_mkuffd_wp(pte);
>> --
>> 2.32.0


Re: [PATCH v4 10/15] drm/shmem-helper: Take reservation lock instead of drm_gem_shmem locks

2022-05-05 Thread Dmitry Osipenko
On 5/5/22 11:12, Daniel Vetter wrote:
> On Wed, May 04, 2022 at 06:56:09PM +0300, Dmitry Osipenko wrote:
>> On 5/4/22 11:21, Daniel Vetter wrote:
>> ...
> - Maybe also do what you suggest and keep a separate lock for this, but
>   the fundamental issue is that this doesn't really work - if you share
>   buffers both ways with two drivers using shmem helpers, then the
>   ordering of this vmap_count_mutex vs dma_resv_lock is inconsistent and
>   you can get some nice deadlocks. So not a great approach (and also the
>   reason why we really need to get everyone to move towards dma_resv_lock
>   as _the_ buffer object lock, since otherwise we'll never get a
>   consistent lock nesting hierarchy).

 The separate locks should work okay because it will be always the
 exporter that takes the dma_resv_lock. But I agree that it's less ideal
 than defining the new rules for dma-bufs since sometime you will take
 the resv lock and sometime not, potentially hiding bugs related to 
 lockings.
>>>
>>> That's the issue, some importers need to take the dma_resv_lock for
>>> dma_buf_vmap too (e.g. to first nail the buffer in place when it's a
>>> dynamic memory manager). In practice it'll work as well as what we have
>>> currently, which is similarly inconsistent, except with per-driver locks
>>> instead of shared locks from shmem helpers or dma-buf, so less obvious
>>> that things are inconsistent.
>>>
>>> So yeah if it's too messy maybe the approach is to have a separate lock
>>> for vmap for now, land things, and then fix up dma_buf_vmap in a follow up
>>> series.
>>
>> The amdgpu driver was the fist who introduced the concept of movable
>> memory for dma-bufs. Now we want to support it for DRM SHMEM too. For
>> both amdgpu ttm and shmem drivers we will want to hold the reservation
>> lock when we're touching moveable buffers. The current way of denoting
>> that dma-buf is movable is to implement the pin/unpin callbacks of the
>> dma-buf ops, should be doable for shmem.
> 
> Hm that sounds like a bridge too far? I don't think we want to start
> adding moveable dma-bufs for shmem, thus far at least no one asked for
> that. Goal here is just to streamline the locking a bit and align across
> all the different ways of doing buffers in drm.
> 
> Or do you mean something else and I'm just completely lost?

I'm talking about aligning DRM locks with the dma-buf locks. The problem
is that the convention of dma-bufs isn't specified yet. In particular
there is no convention for the mapping operations.

If we want to switch vmapping of shmem to use reservation lock, then
somebody will have to hold this lock for dma_buf_vmap() and the locking
convention needs to be specified firmly.

In case of dynamic buffers, we will also need to specify whether
dma_buf_vmap() should imply the implicit pinning by exporter or the
buffer must be pinned explicitly by importer before dma_buf_vmap() is
invoked.

Perhaps I indeed shouldn't care about this for this patchset. The
complete locking model of dma-bufs must be specified first.

>> A day ago I found that mapping of imported dma-bufs is broken at least
>> for the Tegra DRM driver (and likely for others too) because driver
>> doesn't assume that anyone will try to mmap imported buffer and just
>> doesn't handle this case at all, so we're getting a hard lockup on
>> touching mapped memory because we're mapping something else than the
>> dma-buf.
> 
> Huh that sounds bad, how does this happen? Pretty much all pieces of
> dma-buf (cpu vmap, userspace mmap, heck even dma_buf_attach) are optional
> or at least can fail for various reasons. So exporters not providing mmap
> support is fine, but importers then dying is not.

Those drivers that die don't have userspace that uses dma-bufs
extensively. I noticed it only because was looking at this code too much
for the last days.

Drivers that don't die either map imported BOs properly or don't allow
mapping at all.

>> My plan is to move the dma-buf management code to the level of DRM core
>> and make it aware of the reservation locks for the dynamic dma-bufs.
>> This way we will get the proper locking for dma-bufs and fix mapping of
>> imported dma-bufs for Tegra and other drivers.
> 
> So maybe we're completely talking past each another, or coffee is not
> working here on my end, but I've no idea what you mean.
> 
> We do have some helpers for taking care of the dma_resv_lock dance, and
> Christian König has an rfc patch set to maybe unify this further. But that
> should be fairly orthogonal to reworking shmem (it might help a bit with
> reworking shmem though).

The reservation lock itself doesn't help much shmem, IMO. It should help
only in the context of dynamic dma-bufs and today we don't have a need
in the dynamic shmem dma-bufs.

You were talking about making DRM locks consistent with dma-buf locks,
so I thought that yours main point of making use of reservation locks
for shmem is to 

Re: [PATCH] drm: Document that power requirements for DP AUX transfers

2022-05-05 Thread Doug Anderson
Hi,

On Thu, May 5, 2022 at 3:15 PM Dmitry Baryshkov
 wrote:
>
> On 06/05/2022 00:24, Doug Anderson wrote:
> > Hi,
> >
> > On Thu, May 5, 2022 at 1:56 PM Dmitry Baryshkov
> >  wrote:
> >>
> >> On Thu, 5 May 2022 at 23:21, Doug Anderson  wrote:
> >>>
> >>> Hi,
> >>>
> >>> On Thu, May 5, 2022 at 1:10 PM Dmitry Baryshkov
> >>>  wrote:
> 
>  On Thu, 5 May 2022 at 18:53, Doug Anderson  wrote:
> >
> > Hi,
> >
> > On Thu, May 5, 2022 at 8:29 AM Ville Syrjälä
> >  wrote:
> >>
> >> On Thu, May 05, 2022 at 08:00:20AM -0700, Doug Anderson wrote:
> >>> Hi,
> >>>
> >>> On Thu, May 5, 2022 at 7:46 AM Ville Syrjälä
> >>>  wrote:
> 
>  On Wed, May 04, 2022 at 02:10:08PM -0400, Lyude Paul wrote:
> > On Wed, 2022-05-04 at 09:04 -0700, Doug Anderson wrote:
> >> Hi,
> >>
> >> On Wed, May 4, 2022 at 5:21 AM Ville Syrjälä
> >>  wrote:
> >>>
> >>> On Tue, May 03, 2022 at 04:21:08PM -0700, Douglas Anderson wrote:
>  When doing DP AUX transfers there are two actors that need to be
>  powered in order for the DP AUX transfer to work: the DP source 
>  and
>  the DP sync. Commit bacbab58f09d ("drm: Mention the power state
>  requirement on side-channel operations") added some documentation
>  saying that the DP source is required to power itself up (if 
>  needed)
>  to do AUX transfers. However, that commit doesn't talk anything 
>  about
>  the DP sink.
> 
>  For full fledged DP the sink isn't really a problem. It's 
>  expected
>  that if an external DP monitor isn't plugged in that attempting 
>  to do
>  AUX transfers won't work. It's also expected that if a DP 
>  monitor is
>  plugged in (and thus asserting HPD) that it AUX transfers will 
>  work.
> 
>  When we're looking at eDP, however, things are less obvious. 
>  Let's add
>  some documentation about expectations. Here's what we'll say:
> 
>  1. We don't expect the DP AUX transfer function to power on an 
>  eDP
>  panel. If an eDP panel is physically connected but powered off 
>  then it
>  makes sense for the transfer to fail.
> >>>
> >>> I don't agree with this. I think the panel should just get powred 
> >>> up
> >>> for AUX transfers.
> >>
> >> That's definitely a fair thing to think about and I have at times
> >> thought about trying to make it work that way. It always ends up
> >> hitting a roadblock.
> 
>  How do you even probe the panel initially if you can't power it on
>  without doing some kind of full modeset/etc.?
> >>>
> >>> It's not that we can't power it on without a full modeset. It' that at
> >>> panel probe time all the DRM components haven't been hooked together
> >>> yet, so the bridge chain isn't available yet. The panel can power
> >>> itself on, though. This is why the documentation I added says: "if a
> >>> panel driver is initiating a DP AUX transfer it may power itself up
> >>> however it wants"
> >>>
> >>>
> >> The biggest roadblock that I recall is that to make this work then
> >> you'd have to somehow ensure that the bridge chain's pre_enable() 
> >> call
> >> was made as part of the AUX transfer, right? Since the transfer
> >> function can be called in any context at all, we have to coordinate
> >> this with DRM. If, for instance, DRM is mid way through powering 
> >> the
> >> panel down then we need to wait for DRM to fully finish powering 
> >> down,
> >> then we need to power the panel back up. I don't believe that we 
> >> can
> >> just force the panel to stay on if DRM is turning it off because of
> >> panel power sequencing requirements. At least I know it would have 
> >> the
> >> potential to break "samsung-atna33xc20.c" which absolutely needs to
> >> see the panel power off after it's been disabled.
> >>
> >> We also, I believe, need to handle the fact that the bridge chain 
> >> may
> >> not have even been created yet. We do AUX transfers to read the 
> >> EDID
> >> and also to setup the backlight in the probe function of 
> >> panel-edp. At
> >> that point the panel hasn't been linked into the chain. We had 
> >> _long_
> >> discussions [1] about moving these out of probe and decided that we
> >> could move the EDID read to be later but that it was going to 
> >> really
> >> ugly to move the AUX backlight later. The 

Re: [PATCH v10, 16/17] media: mediatek: vcodec: support stateless VP9 decoding

2022-05-05 Thread Nícolas F . R . A . Prado
On Tue, Apr 26, 2022 at 06:08:27PM +0800, Yunfei Dong wrote:
> Add support for VP9 decoding using the stateless API,
> as supported by MT8192. And the drivers is lat and core architecture.
> 
> Signed-off-by: Yunfei Dong 
> Signed-off-by: George Sun 
> Reviewed-by: AngeloGioacchino Del Regno 
> 
> ---
>  .../media/platform/mediatek/vcodec/Makefile   |1 +
>  .../vcodec/mtk_vcodec_dec_stateless.c |   26 +-
>  .../platform/mediatek/vcodec/mtk_vcodec_drv.h |1 +
>  .../vcodec/vdec/vdec_vp9_req_lat_if.c | 2031 +
>  .../platform/mediatek/vcodec/vdec_drv_if.c|4 +
>  .../platform/mediatek/vcodec/vdec_drv_if.h|1 +
>  6 files changed, 2061 insertions(+), 3 deletions(-)
>  create mode 100644 
> drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c
> 

...

> + use_128 = !frame_is_intra && !vsi->frame.uh.last_frame_type;
> + v4l2_vp9_adapt_coef_probs(pre_frame_ctx_helper,
> +   counts_helper,
> +   use_128,
> +   frame_is_intra);

Hi Yunfei,

I'm getting

ERROR: modpost: "v4l2_vp9_adapt_noncoef_probs" 
[drivers/media/platform/mediatek/vcodec/mtk-vcodec-dec.ko] undefined!
ERROR: modpost: "v4l2_vp9_adapt_coef_probs" 
[drivers/media/platform/mediatek/vcodec/mtk-vcodec-dec.ko] undefined!

when building this series.

Adding
select V4L2_VP9
to
config VIDEO_MEDIATEK_VCODEC
solved the issue.

Thanks,
Nícolas


Re: [PATCH] drm: Document that power requirements for DP AUX transfers

2022-05-05 Thread Dmitry Baryshkov

On 06/05/2022 00:24, Doug Anderson wrote:

Hi,

On Thu, May 5, 2022 at 1:56 PM Dmitry Baryshkov
 wrote:


On Thu, 5 May 2022 at 23:21, Doug Anderson  wrote:


Hi,

On Thu, May 5, 2022 at 1:10 PM Dmitry Baryshkov
 wrote:


On Thu, 5 May 2022 at 18:53, Doug Anderson  wrote:


Hi,

On Thu, May 5, 2022 at 8:29 AM Ville Syrjälä
 wrote:


On Thu, May 05, 2022 at 08:00:20AM -0700, Doug Anderson wrote:

Hi,

On Thu, May 5, 2022 at 7:46 AM Ville Syrjälä
 wrote:


On Wed, May 04, 2022 at 02:10:08PM -0400, Lyude Paul wrote:

On Wed, 2022-05-04 at 09:04 -0700, Doug Anderson wrote:

Hi,

On Wed, May 4, 2022 at 5:21 AM Ville Syrjälä
 wrote:


On Tue, May 03, 2022 at 04:21:08PM -0700, Douglas Anderson wrote:

When doing DP AUX transfers there are two actors that need to be
powered in order for the DP AUX transfer to work: the DP source and
the DP sync. Commit bacbab58f09d ("drm: Mention the power state
requirement on side-channel operations") added some documentation
saying that the DP source is required to power itself up (if needed)
to do AUX transfers. However, that commit doesn't talk anything about
the DP sink.

For full fledged DP the sink isn't really a problem. It's expected
that if an external DP monitor isn't plugged in that attempting to do
AUX transfers won't work. It's also expected that if a DP monitor is
plugged in (and thus asserting HPD) that it AUX transfers will work.

When we're looking at eDP, however, things are less obvious. Let's add
some documentation about expectations. Here's what we'll say:

1. We don't expect the DP AUX transfer function to power on an eDP
panel. If an eDP panel is physically connected but powered off then it
makes sense for the transfer to fail.


I don't agree with this. I think the panel should just get powred up
for AUX transfers.


That's definitely a fair thing to think about and I have at times
thought about trying to make it work that way. It always ends up
hitting a roadblock.


How do you even probe the panel initially if you can't power it on
without doing some kind of full modeset/etc.?


It's not that we can't power it on without a full modeset. It' that at
panel probe time all the DRM components haven't been hooked together
yet, so the bridge chain isn't available yet. The panel can power
itself on, though. This is why the documentation I added says: "if a
panel driver is initiating a DP AUX transfer it may power itself up
however it wants"



The biggest roadblock that I recall is that to make this work then
you'd have to somehow ensure that the bridge chain's pre_enable() call
was made as part of the AUX transfer, right? Since the transfer
function can be called in any context at all, we have to coordinate
this with DRM. If, for instance, DRM is mid way through powering the
panel down then we need to wait for DRM to fully finish powering down,
then we need to power the panel back up. I don't believe that we can
just force the panel to stay on if DRM is turning it off because of
panel power sequencing requirements. At least I know it would have the
potential to break "samsung-atna33xc20.c" which absolutely needs to
see the panel power off after it's been disabled.

We also, I believe, need to handle the fact that the bridge chain may
not have even been created yet. We do AUX transfers to read the EDID
and also to setup the backlight in the probe function of panel-edp. At
that point the panel hasn't been linked into the chain. We had _long_
discussions [1] about moving these out of probe and decided that we
could move the EDID read to be later but that it was going to really
ugly to move the AUX backlight later. The backlight would end up
popping up at some point in time later (the first call to panel
prepare() or maybe get_modes()) and that seemed weird.

[1]
https://lore.kernel.org/lkml/CAD=FV=u5-stdlydkejwlaog-0wgxr49vxtwuyuo7z2puibl...@mail.gmail.com/



Otherwise you can't trust that eg. the /dev/aux
stuff is actually usable.


Yeah, it's been on my mind to talk more about /dev/aux. I think
/dev/aux has some problems, at least with eDP. Specifically:

1. Even if we somehow figure out how to power the panel on as part of
the aux transfer, we actually _still_ not guaranteed to be able to
talk to it as far as I understand. My colleague reported to me that on
a system he was working with that had PSR (panel self refresh) that
when the panel was powered on but in PSR mode that it wouldn't talk
over AUX. Assuming that this is correct then I guess we'd also have to
do even more coordination with DRM to exit PSR and block future
transitions of PSR. (NOTE: it's always possible that my colleague ran
into some other bug and that panels are _supposed_ to be able to talk
in PSR. If you think this is the case, I can always try to dig more).


TBH - the coordination with drm I don't think would be the difficult part, as
we'd just need to add some sort of property (ideally invisible to userspace)
that can be used in an atomic commit to disable PSR - similar to how we 

Re: AMD display drivers handling DRM CRTC color mgmt props

2022-05-05 Thread Melissa Wen
On 04/22, Harry Wentland wrote:
> 
> 
> On 2022-04-22 10:28, Melissa Wen wrote:
> > On 04/21, Harry Wentland wrote:
> > > 
> > > 
> > > On 2022-04-21 15:20, Melissa Wen wrote:
> > > > On 04/21, Harry Wentland wrote:
> > > > > 
> > > > > 
> > > > > On 2022-04-21 10:37, Melissa Wen wrote:
> > > > > > Hi all,
> > > > > > 
> > > > > > I'm examining how DRM color management properties (degamma, ctm, 
> > > > > > gamma)
> > > > > > are applied to AMD display drivers. As far I could understand thanks
> > > > > > Nicholas documentation on amdgpu_dm/amdgpu_dm_color, DC drivers have
> > > > > > per-plane color correction features:
> > > > > > 
> > > > Hi Harry,
> > > > 
> > > > Wow, thanks so much for all details!
> > > > > 
> > > > > DC programs some of the color correction features pre-blending but
> > > > > DRM/KMS has not per-plane color correction properties.
> > > > > 
> > > > > See this series from Uma Shankar for an RFC on how to introduce those
> > > > > properties for 1D LUTs and CSC matrix:
> > > > > https://patchwork.freedesktop.org/series/90826/
> > > > > 
> > > > > Bhanuprakash has a series of IGT tests for these properties:
> > > > > https://patchwork.freedesktop.org/series/96895/
> > > > > 
> > > > > I've rebased these on amd-staging-drm-next and maintain a kernel and 
> > > > > IGT
> > > > > branch with these patches:
> > > > > https://gitlab.freedesktop.org/hwentland/linux/-/tree/color-and-hdr
> > > > > https://gitlab.freedesktop.org/hwentland/igt-gpu-tools/-/tree/color-and-hdr
> > > > > 
> > > > > We've had many discussions with Weston guys on this. In order to 
> > > > > merge the
> > > > > kernel properties we need a canonical userspace implementation that 
> > > > > are
> > > > > using it. Weston guys are working towards that but if you want to 
> > > > > suggest a
> > > > > different userspace to serve as that vehicle I'd be all ears. :)
> > > > > 
> > > > > Note that in order to show this all working we also need a Wayland 
> > > > > Protocol
> > > > > update.
> > > > > 
> > > > > See
> > > > > https://gitlab.freedesktop.org/pq/color-and-hdr
> > > > > https://gitlab.freedesktop.org/swick/wayland-protocols
> > > > > https://gitlab.freedesktop.org/wayland/weston/-/issues/467
> > > > 
> > > > So, I've followed these discussions (until the issue on naming) because
> > > > initially I considered it addresses our current goals for color
> > > > correction. But after some discussions, what we are targeting is a 3D
> > > > LUT after blending (per-CRTC). I found past proposals on dri-devel
> > > > [1][2] to extend the DRM CRTC color management properties, but they
> > > > didn't move forward and were never applied.
> > > > 
> > > 
> > > They're stuck in limbo until we have an upstream userspace
> > > implementation that's making use of them.
> > 
> > Yes... afaiu, the basic requirements for all of these changes are IGT
> > tests + open userspace usage, right?
> > 
> 
> Correct. See [1] and [2].
> 
> [1] https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#requirements
> [2] 
> https://www.kernel.org/doc/html/latest/gpu/drm-uapi.html#open-source-userspace-requirements
> 
> > > 
> > > > > 
> > > > > > * - Input gamma LUT (de-normalized)
> > > > > > * - Input CSC (normalized)
> > > > > > * - Surface degamma LUT (normalized)
> > > > > > * - Surface CSC (normalized)
> > > > > > * - Surface regamma LUT (normalized)
> > > > > > * - Output CSC (normalized)
> > > > > > so DM is "adapting" those DRM per-CRTC properties to fit into three 
> > > > > > of
> > > > > > these color correction stages, which I guess are the surface stages:
> > > > > > 
> > > > > > * - Surface degamma LUT (normalized)
> > > > > > * - Surface CSC (normalized)
> > > > > > * - Surface regamma LUT (normalized)
> > > > > > 
> > > > > > I'm trying to understand what this mapping is doing. A comment 
> > > > > > mentions
> > > > > > that is not possible to do these color corrections after blending, 
> > > > > > so,
> > > > > > the same color correction pipe is performed on every plane before
> > > > > > blending?  (is the surface the plane?) Does this adaptation affect 
> > > > > > the
> > > > > > expected output?  Moreover, is there something that I 
> > > > > > misunderstood? :)
> > > > > > 
> > > > > 
> > > > > What's possible to do before and after blending has changed quite a 
> > > > > bit
> > > > > between DCN generations. We program the CRTC Gamma and CTM after 
> > > > > blending.
> > > > > See attached picture for a view relating the color bits between the 
> > > > > DRM
> > > > > interface, DC interface and DCN 3.0 HW blocks.
> > > > 
> > > > This picture is really enlightening, thanks!
> > > > You said it changes between generations, therefore, I can't consider the
> > > > DCN 2.x family follow the same mapping, right? If so, can you share the
> > > > main differences for a DCN 2.x regarding per-CRTC properties?
> > > > 
> > > 
> > > See attached diagram for DCN 2.0.
> > 
> > Thanks again!
> > 
> > > 
> > > > > 
> > > > > > 

[PATCH v3 4/4] fbdev: vesafb: Cleanup fb_info in .fb_destroy rather than .remove

2022-05-05 Thread Javier Martinez Canillas
The driver is calling framebuffer_release() in its .remove callback, but
this will cause the struct fb_info to be freed too early. Since it could
be that a reference is still hold to it if user-space opened the fbdev.

This would lead to a use-after-free error if the framebuffer device was
unregistered but later a user-space process tries to close the fbdev fd.

To prevent this, move the framebuffer_release() call to fb_ops.fb_destroy
instead of doing it in the driver's .remove callback.

Strictly speaking, the code flow in the driver is still wrong because all
the hardware cleanupd (i.e: iounmap) should be done in .remove while the
software cleanup (i.e: releasing the framebuffer) should be done in the
.fb_destroy handler. But this at least makes to match the behavior before
commit 27599aacbaef ("fbdev: Hot-unplug firmware fb devices on forced removal").

Fixes: 27599aacbaef ("fbdev: Hot-unplug firmware fb devices on forced removal")
Suggested-by: Daniel Vetter 
Signed-off-by: Javier Martinez Canillas 
Reviewed-by: Thomas Zimmermann 
Reviewed-by: Daniel Vetter 
---

Changes in v3:
- Only move framebuffer_release() and don't do any other change
  (Daniel Vetter).

Changes in v2:
- Also do the change for vesafb (Thomas Zimmermann).

 drivers/video/fbdev/vesafb.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c
index df6de5a9dd4c..e25e8de5ff67 100644
--- a/drivers/video/fbdev/vesafb.c
+++ b/drivers/video/fbdev/vesafb.c
@@ -179,6 +179,10 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, 
unsigned green,
return err;
 }
 
+/*
+ * fb_ops.fb_destroy is called by the last put_fb_info() call at the end
+ * of unregister_framebuffer() or fb_release(). Do any cleanup here.
+ */
 static void vesafb_destroy(struct fb_info *info)
 {
struct vesafb_par *par = info->par;
@@ -188,6 +192,8 @@ static void vesafb_destroy(struct fb_info *info)
if (info->screen_base)
iounmap(info->screen_base);
release_mem_region(info->apertures->ranges[0].base, 
info->apertures->ranges[0].size);
+
+   framebuffer_release(info);
 }
 
 static struct fb_ops vesafb_ops = {
@@ -484,10 +490,10 @@ static int vesafb_remove(struct platform_device *pdev)
 {
struct fb_info *info = platform_get_drvdata(pdev);
 
+   /* vesafb_destroy takes care of info cleanup */
unregister_framebuffer(info);
if (((struct vesafb_par *)(info->par))->region)
release_region(0x3c0, 32);
-   framebuffer_release(info);
 
return 0;
 }
-- 
2.35.1



[PATCH v3 3/4] fbdev: efifb: Cleanup fb_info in .fb_destroy rather than .remove

2022-05-05 Thread Javier Martinez Canillas
The driver is calling framebuffer_release() in its .remove callback, but
this will cause the struct fb_info to be freed too early. Since it could
be that a reference is still hold to it if user-space opened the fbdev.

This would lead to a use-after-free error if the framebuffer device was
unregistered but later a user-space process tries to close the fbdev fd.

To prevent this, move the framebuffer_release() call to fb_ops.fb_destroy
instead of doing it in the driver's .remove callback.

Strictly speaking, the code flow in the driver is still wrong because all
the hardware cleanupd (i.e: iounmap) should be done in .remove while the
software cleanup (i.e: releasing the framebuffer) should be done in the
.fb_destroy handler. But this at least makes to match the behavior before
commit 27599aacbaef ("fbdev: Hot-unplug firmware fb devices on forced removal").

Fixes: 27599aacbaef ("fbdev: Hot-unplug firmware fb devices on forced removal")
Suggested-by: Daniel Vetter 
Signed-off-by: Javier Martinez Canillas 
Reviewed-by: Thomas Zimmermann 
Reviewed-by: Daniel Vetter 
---

(no changes since v1)

 drivers/video/fbdev/efifb.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index ea42ba6445b2..cfa3dc0b4eee 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -243,6 +243,10 @@ static void efifb_show_boot_graphics(struct fb_info *info)
 static inline void efifb_show_boot_graphics(struct fb_info *info) {}
 #endif
 
+/*
+ * fb_ops.fb_destroy is called by the last put_fb_info() call at the end
+ * of unregister_framebuffer() or fb_release(). Do any cleanup here.
+ */
 static void efifb_destroy(struct fb_info *info)
 {
if (efifb_pci_dev)
@@ -254,6 +258,9 @@ static void efifb_destroy(struct fb_info *info)
else
memunmap(info->screen_base);
}
+
+   framebuffer_release(info);
+
if (request_mem_succeeded)
release_mem_region(info->apertures->ranges[0].base,
   info->apertures->ranges[0].size);
@@ -620,9 +627,9 @@ static int efifb_remove(struct platform_device *pdev)
 {
struct fb_info *info = platform_get_drvdata(pdev);
 
+   /* efifb_destroy takes care of info cleanup */
unregister_framebuffer(info);
sysfs_remove_groups(>dev.kobj, efifb_groups);
-   framebuffer_release(info);
 
return 0;
 }
-- 
2.35.1



[PATCH v3 2/4] fbdev: simplefb: Cleanup fb_info in .fb_destroy rather than .remove

2022-05-05 Thread Javier Martinez Canillas
The driver is calling framebuffer_release() in its .remove callback, but
this will cause the struct fb_info to be freed too early. Since it could
be that a reference is still hold to it if user-space opened the fbdev.

This would lead to a use-after-free error if the framebuffer device was
unregistered but later a user-space process tries to close the fbdev fd.

To prevent this, move the framebuffer_release() call to fb_ops.fb_destroy
instead of doing it in the driver's .remove callback.

Strictly speaking, the code flow in the driver is still wrong because all
the hardware cleanupd (i.e: iounmap) should be done in .remove while the
software cleanup (i.e: releasing the framebuffer) should be done in the
.fb_destroy handler. But this at least makes to match the behavior before
commit 27599aacbaef ("fbdev: Hot-unplug firmware fb devices on forced removal").

Fixes: 27599aacbaef ("fbdev: Hot-unplug firmware fb devices on forced removal")
Suggested-by: Daniel Vetter 
Signed-off-by: Javier Martinez Canillas 
Reviewed-by: Thomas Zimmermann 
Reviewed-by: Daniel Vetter 
---

(no changes since v1)

 drivers/video/fbdev/simplefb.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index 94fc9c6d0411..2c198561c338 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -84,6 +84,10 @@ struct simplefb_par {
 static void simplefb_clocks_destroy(struct simplefb_par *par);
 static void simplefb_regulators_destroy(struct simplefb_par *par);
 
+/*
+ * fb_ops.fb_destroy is called by the last put_fb_info() call at the end
+ * of unregister_framebuffer() or fb_release(). Do any cleanup here.
+ */
 static void simplefb_destroy(struct fb_info *info)
 {
struct simplefb_par *par = info->par;
@@ -94,6 +98,8 @@ static void simplefb_destroy(struct fb_info *info)
if (info->screen_base)
iounmap(info->screen_base);
 
+   framebuffer_release(info);
+
if (mem)
release_mem_region(mem->start, resource_size(mem));
 }
@@ -545,8 +551,8 @@ static int simplefb_remove(struct platform_device *pdev)
 {
struct fb_info *info = platform_get_drvdata(pdev);
 
+   /* simplefb_destroy takes care of info cleanup */
unregister_framebuffer(info);
-   framebuffer_release(info);
 
return 0;
 }
-- 
2.35.1



[PATCH v3 1/4] fbdev: Prevent possible use-after-free in fb_release()

2022-05-05 Thread Javier Martinez Canillas
From: Daniel Vetter 

Most fbdev drivers have issues with the fb_info lifetime, because call to
framebuffer_release() from their driver's .remove callback, rather than
doing from fbops.fb_destroy callback.

Doing that will destroy the fb_info too early, while references to it may
still exist, leading to a use-after-free error.

To prevent this, check the fb_info reference counter when attempting to
kfree the data structure in framebuffer_release(). That will leak it but
at least will prevent the mentioned error.

Signed-off-by: Daniel Vetter 
Signed-off-by: Javier Martinez Canillas 
Reviewed-by: Thomas Zimmermann 
---

(no changes since v1)

 drivers/video/fbdev/core/fbsysfs.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/video/fbdev/core/fbsysfs.c 
b/drivers/video/fbdev/core/fbsysfs.c
index 8c1ee9ecec3d..c2a60b187467 100644
--- a/drivers/video/fbdev/core/fbsysfs.c
+++ b/drivers/video/fbdev/core/fbsysfs.c
@@ -80,6 +80,10 @@ void framebuffer_release(struct fb_info *info)
 {
if (!info)
return;
+
+   if (WARN_ON(refcount_read(>count)))
+   return;
+
kfree(info->apertures);
kfree(info);
 }
-- 
2.35.1



Re: [PATCH v3 2/2] drm/msm/mdp5: Return error code in mdp5_mixer_release when deadlock is detected

2022-05-05 Thread Rob Clark
On Thu, May 5, 2022 at 2:41 PM Jessica Zhang  wrote:
>
> There is a possibility for mdp5_get_global_state to return
> -EDEADLK when acquiring the modeset lock, but currently global_state in
> mdp5_mixer_release doesn't check for if an error is returned.
>
> To avoid a NULL dereference error, let's have mdp5_mixer_release
> check if an error is returned and propagate that error.
>
> Reported-by: Tomeu Vizoso 
> Signed-off-by: Jessica Zhang 

Fixes: 7907a0d77cb4 ("drm/msm/mdp5: Use the new private_obj state")
Reviewed-by: Rob Clark 

> ---
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c  | 10 --
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c | 15 +++
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h |  4 ++--
>  3 files changed, 21 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c 
> b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
> index b966cd69f99d..fe2922c8d21b 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
> @@ -612,9 +612,15 @@ static int mdp5_crtc_setup_pipeline(struct drm_crtc 
> *crtc,
> if (ret)
> return ret;
>
> -   mdp5_mixer_release(new_crtc_state->state, old_mixer);
> +   ret = mdp5_mixer_release(new_crtc_state->state, old_mixer);
> +   if (ret)
> +   return ret;
> +
> if (old_r_mixer) {
> -   mdp5_mixer_release(new_crtc_state->state, 
> old_r_mixer);
> +   ret = mdp5_mixer_release(new_crtc_state->state, 
> old_r_mixer);
> +   if (ret)
> +   return ret;
> +
> if (!need_right_mixer)
> pipeline->r_mixer = NULL;
> }
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c 
> b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c
> index 954db683ae44..2536def2a000 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c
> @@ -116,21 +116,28 @@ int mdp5_mixer_assign(struct drm_atomic_state *s, 
> struct drm_crtc *crtc,
> return 0;
>  }
>
> -void mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer 
> *mixer)
> +int mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer 
> *mixer)
>  {
> struct mdp5_global_state *global_state = mdp5_get_global_state(s);
> -   struct mdp5_hw_mixer_state *new_state = _state->hwmixer;
> +   struct mdp5_hw_mixer_state *new_state;
>
> if (!mixer)
> -   return;
> +   return 0;
> +
> +   if (IS_ERR(global_state))
> +   return PTR_ERR(global_state);
> +
> +   new_state = _state->hwmixer;
>
> if (WARN_ON(!new_state->hwmixer_to_crtc[mixer->idx]))
> -   return;
> +   return -EINVAL;
>
> DBG("%s: release from crtc %s", mixer->name,
> new_state->hwmixer_to_crtc[mixer->idx]->name);
>
> new_state->hwmixer_to_crtc[mixer->idx] = NULL;
> +
> +   return 0;
>  }
>
>  void mdp5_mixer_destroy(struct mdp5_hw_mixer *mixer)
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h 
> b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h
> index 43c9ba43ce18..545ee223b9d7 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h
> @@ -30,7 +30,7 @@ void mdp5_mixer_destroy(struct mdp5_hw_mixer *lm);
>  int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc,
>   uint32_t caps, struct mdp5_hw_mixer **mixer,
>   struct mdp5_hw_mixer **r_mixer);
> -void mdp5_mixer_release(struct drm_atomic_state *s,
> -   struct mdp5_hw_mixer *mixer);
> +int mdp5_mixer_release(struct drm_atomic_state *s,
> +  struct mdp5_hw_mixer *mixer);
>
>  #endif /* __MDP5_LM_H__ */
> --
> 2.35.1
>


Re: [PATCH v3 1/2] drm/msm/mdp5: Return error code in mdp5_pipe_release when deadlock is detected

2022-05-05 Thread Rob Clark
On Thu, May 5, 2022 at 2:41 PM Jessica Zhang  wrote:
>
> mdp5_get_global_state runs the risk of hitting a -EDEADLK when acquiring
> the modeset lock, but currently mdp5_pipe_release doesn't check for if
> an error is returned. Because of this, there is a possibility of
> mdp5_pipe_release hitting a NULL dereference error.
>
> To avoid this, let's have mdp5_pipe_release check if
> mdp5_get_global_state returns an error and propogate that error.
>
> Changes since v1:
> - Separated declaration and initialization of *new_state to avoid
>   compiler warning
> - Fixed some spelling mistakes in commit message
>
> Changes since v2:
> - Return 0 in case where hwpipe is NULL as this is considered normal
>   behavior
> - Added 2nd patch in series to fix a similar NULL dereference issue in
>   mdp5_mixer_release
>
> Reported-by: Tomeu Vizoso 
> Signed-off-by: Jessica Zhang 

Fixes: 7907a0d77cb4 ("drm/msm/mdp5: Use the new private_obj state")
Reviewed-by: Rob Clark 

> ---
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c  | 15 +++
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h  |  2 +-
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 20 
>  3 files changed, 28 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c 
> b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
> index ba6695963aa6..a4f5cb90f3e8 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
> @@ -119,18 +119,23 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct 
> drm_plane *plane,
> return 0;
>  }
>
> -void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe 
> *hwpipe)
> +int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe 
> *hwpipe)
>  {
> struct msm_drm_private *priv = s->dev->dev_private;
> struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
> struct mdp5_global_state *state = mdp5_get_global_state(s);
> -   struct mdp5_hw_pipe_state *new_state = >hwpipe;
> +   struct mdp5_hw_pipe_state *new_state;
>
> if (!hwpipe)
> -   return;
> +   return 0;
> +
> +   if (IS_ERR(state))
> +   return PTR_ERR(state);
> +
> +   new_state = >hwpipe;
>
> if (WARN_ON(!new_state->hwpipe_to_plane[hwpipe->idx]))
> -   return;
> +   return -EINVAL;
>
> DBG("%s: release from plane %s", hwpipe->name,
> new_state->hwpipe_to_plane[hwpipe->idx]->name);
> @@ -141,6 +146,8 @@ void mdp5_pipe_release(struct drm_atomic_state *s, struct 
> mdp5_hw_pipe *hwpipe)
> }
>
> new_state->hwpipe_to_plane[hwpipe->idx] = NULL;
> +
> +   return 0;
>  }
>
>  void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe)
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h 
> b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h
> index 9b26d0761bd4..cca67938cab2 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h
> @@ -37,7 +37,7 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct 
> drm_plane *plane,
>  uint32_t caps, uint32_t blkcfg,
>  struct mdp5_hw_pipe **hwpipe,
>  struct mdp5_hw_pipe **r_hwpipe);
> -void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe 
> *hwpipe);
> +int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe 
> *hwpipe);
>
>  struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe,
> uint32_t reg_offset, uint32_t caps);
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c 
> b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
> index 228b22830970..979458482841 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
> @@ -311,12 +311,24 @@ static int mdp5_plane_atomic_check_with_state(struct 
> drm_crtc_state *crtc_state,
> mdp5_state->r_hwpipe = NULL;
>
>
> -   mdp5_pipe_release(state->state, old_hwpipe);
> -   mdp5_pipe_release(state->state, old_right_hwpipe);
> +   ret = mdp5_pipe_release(state->state, old_hwpipe);
> +   if (ret)
> +   return ret;
> +
> +   ret = mdp5_pipe_release(state->state, 
> old_right_hwpipe);
> +   if (ret)
> +   return ret;
> +
> }
> } else {
> -   mdp5_pipe_release(state->state, mdp5_state->hwpipe);
> -   mdp5_pipe_release(state->state, mdp5_state->r_hwpipe);
> +   ret = mdp5_pipe_release(state->state, mdp5_state->hwpipe);
> +   if (ret)
> +   return ret;
> +
> +   ret = mdp5_pipe_release(state->state, mdp5_state->r_hwpipe);
> +   if (ret)
> +   return ret;
> +
> 

[PATCH v3 0/4] fbdev: Fix use-after-free caused by wrong fb_info cleanup in drivers

2022-05-05 Thread Javier Martinez Canillas
Hello,

This series contains patches suggested by Daniel Vetter to fix a use-after-free
error in the fb_release() function, due a fb_info associated with a fbdev being
freed too early while a user-space process still has the fbdev dev node opened.

That is caused by a wrong management of the struct fb_info lifetime in drivers,
but the fbdev core can also be made more resilient about it an leak

This can easily be reproduced with the simplefb driver doing the following:

$ cat < /dev/fb0 &
$ echo simple-framebuffer.0 > 
/sys/bus/platform/drivers/simple-framebuffer/unbind
$ kill %1

[  257.490471] [ cut here ]
...
[  257.495125] refcount_t: underflow; use-after-free.
[  257.495222] WARNING: CPU: 0 PID: 975 at lib/refcount.c:28 
refcount_warn_saturate+0xf4/0x144
...
[  257.637482] pstate: 8045 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  257.61] pc : refcount_warn_saturate+0xf4/0x144
[  257.649226] lr : refcount_warn_saturate+0xf4/0x144
[  257.654009] sp : 8a06bbf0
[  257.657315] x29: 8a06bbf0 x28: 000a x27: 000a
[  257.664448] x26:  x25: 470b88c6a180 x24: 000a
[  257.671581] x23: 470b81706480 x22: 470b808c2160 x21: 470b8922ba20
[  257.678713] x20: 470b891f5810 x19: 470b891f5800 x18: 
[  257.685846] x17: 3a725f7463656a62 x16: bb18c6465fd4 x15: 0720072007200720
[  257.692978] x14: 0720072d072d072d x13: 0a2e656572662d72 x12: 657466612d657375
[  257.700110] x11: 203b776f6c667265 x10: 646e75203a745f74 x9 : bb18c58f6c90
[  257.707242] x8 : 75203b776f6c6672 x7 : 65646e75203a745f x6 : 0001
[  257.714373] x5 : 470bff8ec418 x4 :  x3 : 0027
[  257.721506] x2 :  x1 : 0027 x0 : 0026
[  257.728638] Call trace:
[  257.731075]  refcount_warn_saturate+0xf4/0x144
[  257.735513]  put_fb_info+0x70/0x7c
[  257.738916]  fb_release+0x60/0x74
[  257.742225]  __fput+0x88/0x240
[  257.745276]  fput+0x1c/0x30
[  257.748410]  task_work_run+0xc4/0x21c
[  257.752066]  do_exit+0x170/0x370
[  257.755288]  do_group_exit+0x40/0xb4
[  257.758858]  get_signal+0x8e0/0x90c
[  257.762339]  do_signal+0x1a0/0x280
[  257.765733]  do_notify_resume+0xc8/0x390
[  257.769650]  el0_da+0xe8/0xf0
[  257.772613]  el0t_64_sync_handler+0xe8/0x130
[  257.776877]  el0t_64_sync+0x190/0x194
[  257.780534] ---[ end trace  ]---

Patch #1 adds a WARN_ON() to framebuffer_release() to prevent the use-after-free
to happen.

Patch #2, #3 and #4 fix the simplefb, efifb and vesafb drivers respectively, to
free the resources at the correct place.

Changes in v3:
- Add Fixes: tag (Daniel Vetter).
- Include in commit message a note that drivers are still broken
  but at least reverts to the previous behavior (Daniel Vetter).
- Only move framebuffer_release() and don't do any other change
  (Daniel Vetter).

Changes in v2:
- Also do the change for vesafb (Thomas Zimmermann).

Daniel Vetter (1):
  fbdev: Prevent possible use-after-free in fb_release()

Javier Martinez Canillas (3):
  fbdev: simplefb: Cleanup fb_info in .fb_destroy rather than .remove
  fbdev: efifb: Cleanup fb_info in .fb_destroy rather than .remove
  fbdev: vesafb: Cleanup fb_info in .fb_destroy rather than .remove

 drivers/video/fbdev/core/fbsysfs.c | 4 
 drivers/video/fbdev/efifb.c| 9 -
 drivers/video/fbdev/simplefb.c | 8 +++-
 drivers/video/fbdev/vesafb.c   | 8 +++-
 4 files changed, 26 insertions(+), 3 deletions(-)

-- 
2.35.1



[PATCH] drm/tve200: Fix smatch warning

2022-05-05 Thread Linus Walleij
The "ret" variable is ambiguously returning something that
could be zero in the tve200_modeset_init() function, assign
it an explicit error return code to make this unambiguous.

Reported-by: Dan Carpenter 
Signed-off-by: Linus Walleij 
---
 drivers/gpu/drm/tve200/tve200_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tve200/tve200_drv.c 
b/drivers/gpu/drm/tve200/tve200_drv.c
index 6d9d2921abf4..3f4fef574706 100644
--- a/drivers/gpu/drm/tve200/tve200_drv.c
+++ b/drivers/gpu/drm/tve200/tve200_drv.c
@@ -65,7 +65,7 @@ static int tve200_modeset_init(struct drm_device *dev)
struct tve200_drm_dev_private *priv = dev->dev_private;
struct drm_panel *panel;
struct drm_bridge *bridge;
-   int ret = 0;
+   int ret;
 
drm_mode_config_init(dev);
mode_config = >mode_config;
@@ -93,6 +93,7 @@ static int tve200_modeset_init(struct drm_device *dev)
 * method to get the connector out of the bridge.
 */
dev_err(dev->dev, "the bridge is not a panel\n");
+   ret = -EINVAL;
goto out_bridge;
}
 
-- 
2.35.1



[PATCH v3 2/2] drm/msm/mdp5: Return error code in mdp5_mixer_release when deadlock is detected

2022-05-05 Thread Jessica Zhang
There is a possibility for mdp5_get_global_state to return
-EDEADLK when acquiring the modeset lock, but currently global_state in
mdp5_mixer_release doesn't check for if an error is returned.

To avoid a NULL dereference error, let's have mdp5_mixer_release
check if an error is returned and propagate that error.

Reported-by: Tomeu Vizoso 
Signed-off-by: Jessica Zhang 
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c  | 10 --
 drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c | 15 +++
 drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h |  4 ++--
 3 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index b966cd69f99d..fe2922c8d21b 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -612,9 +612,15 @@ static int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc,
if (ret)
return ret;
 
-   mdp5_mixer_release(new_crtc_state->state, old_mixer);
+   ret = mdp5_mixer_release(new_crtc_state->state, old_mixer);
+   if (ret)
+   return ret;
+
if (old_r_mixer) {
-   mdp5_mixer_release(new_crtc_state->state, old_r_mixer);
+   ret = mdp5_mixer_release(new_crtc_state->state, 
old_r_mixer);
+   if (ret)
+   return ret;
+
if (!need_right_mixer)
pipeline->r_mixer = NULL;
}
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c
index 954db683ae44..2536def2a000 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c
@@ -116,21 +116,28 @@ int mdp5_mixer_assign(struct drm_atomic_state *s, struct 
drm_crtc *crtc,
return 0;
 }
 
-void mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer 
*mixer)
+int mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer)
 {
struct mdp5_global_state *global_state = mdp5_get_global_state(s);
-   struct mdp5_hw_mixer_state *new_state = _state->hwmixer;
+   struct mdp5_hw_mixer_state *new_state;
 
if (!mixer)
-   return;
+   return 0;
+
+   if (IS_ERR(global_state))
+   return PTR_ERR(global_state);
+
+   new_state = _state->hwmixer;
 
if (WARN_ON(!new_state->hwmixer_to_crtc[mixer->idx]))
-   return;
+   return -EINVAL;
 
DBG("%s: release from crtc %s", mixer->name,
new_state->hwmixer_to_crtc[mixer->idx]->name);
 
new_state->hwmixer_to_crtc[mixer->idx] = NULL;
+
+   return 0;
 }
 
 void mdp5_mixer_destroy(struct mdp5_hw_mixer *mixer)
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h
index 43c9ba43ce18..545ee223b9d7 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h
@@ -30,7 +30,7 @@ void mdp5_mixer_destroy(struct mdp5_hw_mixer *lm);
 int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc,
  uint32_t caps, struct mdp5_hw_mixer **mixer,
  struct mdp5_hw_mixer **r_mixer);
-void mdp5_mixer_release(struct drm_atomic_state *s,
-   struct mdp5_hw_mixer *mixer);
+int mdp5_mixer_release(struct drm_atomic_state *s,
+  struct mdp5_hw_mixer *mixer);
 
 #endif /* __MDP5_LM_H__ */
-- 
2.35.1



[PATCH v3 1/2] drm/msm/mdp5: Return error code in mdp5_pipe_release when deadlock is detected

2022-05-05 Thread Jessica Zhang
mdp5_get_global_state runs the risk of hitting a -EDEADLK when acquiring
the modeset lock, but currently mdp5_pipe_release doesn't check for if
an error is returned. Because of this, there is a possibility of
mdp5_pipe_release hitting a NULL dereference error.

To avoid this, let's have mdp5_pipe_release check if
mdp5_get_global_state returns an error and propogate that error.

Changes since v1:
- Separated declaration and initialization of *new_state to avoid
  compiler warning
- Fixed some spelling mistakes in commit message

Changes since v2:
- Return 0 in case where hwpipe is NULL as this is considered normal
  behavior
- Added 2nd patch in series to fix a similar NULL dereference issue in
  mdp5_mixer_release

Reported-by: Tomeu Vizoso 
Signed-off-by: Jessica Zhang 
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c  | 15 +++
 drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h  |  2 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 20 
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
index ba6695963aa6..a4f5cb90f3e8 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
@@ -119,18 +119,23 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct 
drm_plane *plane,
return 0;
 }
 
-void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe)
+int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe)
 {
struct msm_drm_private *priv = s->dev->dev_private;
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
struct mdp5_global_state *state = mdp5_get_global_state(s);
-   struct mdp5_hw_pipe_state *new_state = >hwpipe;
+   struct mdp5_hw_pipe_state *new_state;
 
if (!hwpipe)
-   return;
+   return 0;
+
+   if (IS_ERR(state))
+   return PTR_ERR(state);
+
+   new_state = >hwpipe;
 
if (WARN_ON(!new_state->hwpipe_to_plane[hwpipe->idx]))
-   return;
+   return -EINVAL;
 
DBG("%s: release from plane %s", hwpipe->name,
new_state->hwpipe_to_plane[hwpipe->idx]->name);
@@ -141,6 +146,8 @@ void mdp5_pipe_release(struct drm_atomic_state *s, struct 
mdp5_hw_pipe *hwpipe)
}
 
new_state->hwpipe_to_plane[hwpipe->idx] = NULL;
+
+   return 0;
 }
 
 void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe)
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h
index 9b26d0761bd4..cca67938cab2 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h
@@ -37,7 +37,7 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct 
drm_plane *plane,
 uint32_t caps, uint32_t blkcfg,
 struct mdp5_hw_pipe **hwpipe,
 struct mdp5_hw_pipe **r_hwpipe);
-void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe 
*hwpipe);
+int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe);
 
 struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe,
uint32_t reg_offset, uint32_t caps);
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index 228b22830970..979458482841 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -311,12 +311,24 @@ static int mdp5_plane_atomic_check_with_state(struct 
drm_crtc_state *crtc_state,
mdp5_state->r_hwpipe = NULL;
 
 
-   mdp5_pipe_release(state->state, old_hwpipe);
-   mdp5_pipe_release(state->state, old_right_hwpipe);
+   ret = mdp5_pipe_release(state->state, old_hwpipe);
+   if (ret)
+   return ret;
+
+   ret = mdp5_pipe_release(state->state, old_right_hwpipe);
+   if (ret)
+   return ret;
+
}
} else {
-   mdp5_pipe_release(state->state, mdp5_state->hwpipe);
-   mdp5_pipe_release(state->state, mdp5_state->r_hwpipe);
+   ret = mdp5_pipe_release(state->state, mdp5_state->hwpipe);
+   if (ret)
+   return ret;
+
+   ret = mdp5_pipe_release(state->state, mdp5_state->r_hwpipe);
+   if (ret)
+   return ret;
+
mdp5_state->hwpipe = mdp5_state->r_hwpipe = NULL;
}
 
-- 
2.35.1



[PATCH v2 06/12] drm/i915/pvc: Reduce stack usage in reset selftest with extra blitter engine

2022-05-05 Thread Matt Roper
From: John Harrison 

PVC adds extra blitter engines (in the following patch). The reset
selftest has a local array on the stack which is sized by the number
of engines. The increase pushes the size of this array to the point
where it trips the 'stack too large' compile warning. This patch takes
the allocation of the stack and makes it dynamic instead.

v2 (MattR):
 - Minor cosmetic changes:  re-sort definition and allocate using
   kmalloc_array().  (Tvrtko)

Cc: Tvrtko Ursulin 
Signed-off-by: John Harrison 
Signed-off-by: Matt Roper 
Reviewed-by: José Roberto de Souza 
---
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c 
b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
index 83ff4c2e57c5..6493265d5f64 100644
--- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
@@ -976,6 +976,7 @@ static int __igt_reset_engines(struct intel_gt *gt,
 {
struct i915_gpu_error *global = >i915->gpu_error;
struct intel_engine_cs *engine, *other;
+   struct active_engine *threads;
enum intel_engine_id id, tmp;
struct hang h;
int err = 0;
@@ -996,8 +997,11 @@ static int __igt_reset_engines(struct intel_gt *gt,
h.ctx->sched.priority = 1024;
}
 
+   threads = kmalloc_array(I915_NUM_ENGINES, sizeof(*threads), GFP_KERNEL);
+   if (!threads)
+   return -ENOMEM;
+
for_each_engine(engine, gt, id) {
-   struct active_engine threads[I915_NUM_ENGINES] = {};
unsigned long device = i915_reset_count(global);
unsigned long count = 0, reported;
bool using_guc = intel_engine_uses_guc(engine);
@@ -1016,7 +1020,7 @@ static int __igt_reset_engines(struct intel_gt *gt,
break;
}
 
-   memset(threads, 0, sizeof(threads));
+   memset(threads, 0, sizeof(*threads) * I915_NUM_ENGINES);
for_each_engine(other, gt, tmp) {
struct task_struct *tsk;
 
@@ -1236,6 +1240,7 @@ static int __igt_reset_engines(struct intel_gt *gt,
break;
}
}
+   kfree(threads);
 
if (intel_gt_is_wedged(gt))
err = -EIO;
-- 
2.35.1



[PATCH v2 01/12] drm/i915/uncore: Reorganize and document shadow and forcewake tables

2022-05-05 Thread Matt Roper
Let's reorganize some of the forcewake/shadow handling in intel_uncore.c
and consolidate the cargo-cult comments on each table into more general
comments that apply to all tables.

We'll probably move forcewake handling to its own dedicated file in the
near future and further enhance this with true kerneldoc.  But this is a
good intermediate step to help clarify the behavior a bit.

Cc: Stuart Summers 
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/intel_uncore.c | 125 ++--
 1 file changed, 80 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index 83517a703eb6..095e071e4053 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -938,36 +938,32 @@ find_fw_domain(struct intel_uncore *uncore, u32 offset)
return entry->domains;
 }
 
-#define GEN_FW_RANGE(s, e, d) \
-   { .start = (s), .end = (e), .domains = (d) }
-
-/* *Must* be sorted by offset ranges! See intel_fw_table_check(). */
-static const struct intel_forcewake_range __vlv_fw_ranges[] = {
-   GEN_FW_RANGE(0x2000, 0x3fff, FORCEWAKE_RENDER),
-   GEN_FW_RANGE(0x5000, 0x7fff, FORCEWAKE_RENDER),
-   GEN_FW_RANGE(0xb000, 0x11fff, FORCEWAKE_RENDER),
-   GEN_FW_RANGE(0x12000, 0x13fff, FORCEWAKE_MEDIA),
-   GEN_FW_RANGE(0x22000, 0x23fff, FORCEWAKE_MEDIA),
-   GEN_FW_RANGE(0x2e000, 0x2, FORCEWAKE_RENDER),
-   GEN_FW_RANGE(0x3, 0x3, FORCEWAKE_MEDIA),
-};
-
-#define __fwtable_reg_read_fw_domains(uncore, offset) \
-({ \
-   enum forcewake_domains __fwd = 0; \
-   if (NEEDS_FORCE_WAKE((offset))) \
-   __fwd = find_fw_domain(uncore, offset); \
-   __fwd; \
-})
+/*
+ * Shadowed register tables describe special register ranges that i915 is
+ * allowed to write to without acquiring forcewake.  If these registers' power
+ * wells are down, the hardware will save values written by i915 to a shadow
+ * copy and automatically transfer them into the real register the next time
+ * the power well is woken up.  Shadowing only applies to writes; forcewake
+ * must still be acquired when reading from registers in these ranges.
+ *
+ * The documentation for shadowed registers is somewhat spotty on older
+ * platforms.  However missing registers from these lists is non-fatal; it just
+ * means we'll wake up the hardware for some register accesses where we didn't
+ * really need to.
+ *
+ * The ranges listed in these tables must be sorted by offset.
+ *
+ * When adding new tables here, please also add them to
+ * intel_shadow_table_check() in selftests/intel_uncore.c so that they will be
+ * scanned for obvious mistakes or typos by the selftests.
+ */
 
-/* *Must* be sorted by offset! See intel_shadow_table_check(). */
 static const struct i915_range gen8_shadowed_regs[] = {
{ .start =  0x2030, .end =  0x2030 },
{ .start =  0xA008, .end =  0xA00C },
{ .start = 0x12030, .end = 0x12030 },
{ .start = 0x1a030, .end = 0x1a030 },
{ .start = 0x22030, .end = 0x22030 },
-   /* TODO: Other registers are not yet used */
 };
 
 static const struct i915_range gen11_shadowed_regs[] = {
@@ -1107,11 +1103,71 @@ gen6_reg_write_fw_domains(struct intel_uncore *uncore, 
i915_reg_t reg)
return FORCEWAKE_RENDER;
 }
 
+#define __fwtable_reg_read_fw_domains(uncore, offset) \
+({ \
+   enum forcewake_domains __fwd = 0; \
+   if (NEEDS_FORCE_WAKE((offset))) \
+   __fwd = find_fw_domain(uncore, offset); \
+   __fwd; \
+})
+
+#define __fwtable_reg_write_fw_domains(uncore, offset) \
+({ \
+   enum forcewake_domains __fwd = 0; \
+   const u32 __offset = (offset); \
+   if (NEEDS_FORCE_WAKE((__offset)) && !is_shadowed(uncore, __offset)) \
+   __fwd = find_fw_domain(uncore, __offset); \
+   __fwd; \
+})
+
+#define GEN_FW_RANGE(s, e, d) \
+   { .start = (s), .end = (e), .domains = (d) }
+
+/*
+ * All platforms' forcewake tables below must be sorted by offset ranges.
+ * Furthermore, new forcewake tables added should be "watertight" and have
+ * no gaps between ranges.
+ *
+ * When there are multiple consecutive ranges listed in the bspec with
+ * the same forcewake domain, it is customary to combine them into a single
+ * row in the tables below to keep the tables small and lookups fast.
+ * Likewise, reserved/unused ranges may be combined with the preceding and/or
+ * following ranges since the driver will never be making MMIO accesses in
+ * those ranges.
+ *
+ * For example, if the bspec were to list:
+ *
+ *...
+ *0x1000 - 0x1fff:  GT
+ *0x2000 - 0x2cff:  GT
+ *0x2d00 - 0x2fff:  unused/reserved
+ *0x3000 - 0x:  GT
+ *...
+ *
+ * these could all be represented by a single line in the code:
+ *
+ *   GEN_FW_RANGE(0x1000, 0x, FORCEWAKE_GT)
+ *
+ * When adding new forcewake tables here, please also add them to
+ * intel_uncore_mock_selftests in 

[PATCH v2 00/12] i915: Introduce Ponte Vecchio

2022-05-05 Thread Matt Roper
Ponte Vecchio (PVC) is a new GPU based on the Xe_HPC architecture.  As a
compute-focused platform, PVC has compute engines and enhanced copy
engines, but no render engine (there is no geometry pipeline) and no
display.

This is just a handful of early enablement patches, including some
initial support for the new copy engines (although we're not yet adding
those to the platform's engine list or exposing them to userspace just
yet).

v2:
 - Drop replicated comment from forcewake patch completely and add an
   additional commit to provide better documentation for forcewake and
   shadowed register tables in a way that's clear for all platforms.
 - Move gvt build fix to its own patch.
 - Address various minor review feedback from Lucas, Tvrtko, and
   Prathap.


Ayaz A Siddiqui (1):
  drm/i915/pvc: Define MOCS table for PVC

John Harrison (1):
  drm/i915/pvc: Reduce stack usage in reset selftest with extra blitter
engine

Lucas De Marchi (2):
  drm/i915/pvc: skip all copy engines from aux table invalidate
  drm/i915/pvc: read fuses for link copy engines

Matt Roper (7):
  drm/i915/uncore: Reorganize and document shadow and forcewake tables
  drm/i915/pvc: Add forcewake support
  drm/i915/pvc: Read correct RP_STATE_CAP register
  drm/i915/gvt: Use intel_engine_mask_t for ring mask
  drm/i915/pvc: Engine definitions for new copy engines
  drm/i915/pvc: Interrupt support for new copy engines
  drm/i915/pvc: Reset support for new copy engines

Stuart Summers (1):
  drm/i915/pvc: Remove additional 3D flags from PIPE_CONTROL

 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  |  21 +-
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |  93 ++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  12 +-
 drivers/gpu/drm/i915/gt/intel_gpu_commands.h  |  12 +-
 drivers/gpu/drm/i915/gt/intel_gt_irq.c|  16 ++
 drivers/gpu/drm/i915/gt/intel_gt_regs.h   |  56 ++--
 drivers/gpu/drm/i915/gt/intel_gt_types.h  |   1 +
 drivers/gpu/drm/i915/gt/intel_mocs.c  |  24 +-
 drivers/gpu/drm/i915/gt/intel_rps.c   |   4 +-
 drivers/gpu/drm/i915/gt/intel_workarounds.c   |  30 +-
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c  |   9 +-
 drivers/gpu/drm/i915/gvt/cmd_parser.c |   2 +-
 drivers/gpu/drm/i915/i915_drv.h   |   4 +
 drivers/gpu/drm/i915/i915_pci.c   |   4 +-
 drivers/gpu/drm/i915/i915_reg.h   |   9 +
 drivers/gpu/drm/i915/intel_device_info.h  |   4 +-
 drivers/gpu/drm/i915/intel_uncore.c   | 267 +++---
 drivers/gpu/drm/i915/selftests/intel_uncore.c |   2 +
 18 files changed, 483 insertions(+), 87 deletions(-)

-- 
2.35.1



[PATCH v2 09/12] drm/i915/pvc: Interrupt support for new copy engines

2022-05-05 Thread Matt Roper
Add the interrupt handler support for new copy engines.

Bspec: 54030
Original-author: CQ Tang
Signed-off-by: Matt Roper 
Reviewed-by: Stuart Summers 
---
 drivers/gpu/drm/i915/gt/intel_gt_irq.c  | 16 
 drivers/gpu/drm/i915/gt/intel_gt_regs.h |  4 
 2 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c 
b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index 88b4becfcb17..3a72d4fd0214 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -193,6 +193,14 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
/* Restore masks irqs on RCS, BCS, VCS and VECS engines. */
intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK,   ~0);
intel_uncore_write(uncore, GEN11_BCS_RSVD_INTR_MASK,~0);
+   if (HAS_ENGINE(gt, BCS1) || HAS_ENGINE(gt, BCS2))
+   intel_uncore_write(uncore, XEHPC_BCS1_BCS2_INTR_MASK, ~0);
+   if (HAS_ENGINE(gt, BCS3) || HAS_ENGINE(gt, BCS4))
+   intel_uncore_write(uncore, XEHPC_BCS3_BCS4_INTR_MASK, ~0);
+   if (HAS_ENGINE(gt, BCS5) || HAS_ENGINE(gt, BCS6))
+   intel_uncore_write(uncore, XEHPC_BCS5_BCS6_INTR_MASK, ~0);
+   if (HAS_ENGINE(gt, BCS7) || HAS_ENGINE(gt, BCS8))
+   intel_uncore_write(uncore, XEHPC_BCS7_BCS8_INTR_MASK, ~0);
intel_uncore_write(uncore, GEN11_VCS0_VCS1_INTR_MASK,   ~0);
intel_uncore_write(uncore, GEN11_VCS2_VCS3_INTR_MASK,   ~0);
if (HAS_ENGINE(gt, VCS4) || HAS_ENGINE(gt, VCS5))
@@ -248,6 +256,14 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
/* Unmask irqs on RCS, BCS, VCS and VECS engines. */
intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK, ~smask);
intel_uncore_write(uncore, GEN11_BCS_RSVD_INTR_MASK, ~smask);
+   if (HAS_ENGINE(gt, BCS1) || HAS_ENGINE(gt, BCS2))
+   intel_uncore_write(uncore, XEHPC_BCS1_BCS2_INTR_MASK, ~dmask);
+   if (HAS_ENGINE(gt, BCS3) || HAS_ENGINE(gt, BCS4))
+   intel_uncore_write(uncore, XEHPC_BCS3_BCS4_INTR_MASK, ~dmask);
+   if (HAS_ENGINE(gt, BCS5) || HAS_ENGINE(gt, BCS6))
+   intel_uncore_write(uncore, XEHPC_BCS5_BCS6_INTR_MASK, ~dmask);
+   if (HAS_ENGINE(gt, BCS7) || HAS_ENGINE(gt, BCS8))
+   intel_uncore_write(uncore, XEHPC_BCS7_BCS8_INTR_MASK, ~dmask);
intel_uncore_write(uncore, GEN11_VCS0_VCS1_INTR_MASK, ~dmask);
intel_uncore_write(uncore, GEN11_VCS2_VCS3_INTR_MASK, ~dmask);
if (HAS_ENGINE(gt, VCS4) || HAS_ENGINE(gt, VCS5))
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index aa2c0974b02c..fe09288a3145 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1529,6 +1529,10 @@
 #define GEN11_GUNIT_CSME_INTR_MASK _MMIO(0x1900f4)
 #define GEN12_CCS0_CCS1_INTR_MASK  _MMIO(0x190100)
 #define GEN12_CCS2_CCS3_INTR_MASK  _MMIO(0x190104)
+#define XEHPC_BCS1_BCS2_INTR_MASK  _MMIO(0x190110)
+#define XEHPC_BCS3_BCS4_INTR_MASK  _MMIO(0x190114)
+#define XEHPC_BCS5_BCS6_INTR_MASK  _MMIO(0x190118)
+#define XEHPC_BCS7_BCS8_INTR_MASK  _MMIO(0x19011c)
 
 #define GEN12_SFC_DONE(n)  _MMIO(0x1cc000 + (n) * 0x1000)
 
-- 
2.35.1



[PATCH v2 12/12] drm/i915/pvc: read fuses for link copy engines

2022-05-05 Thread Matt Roper
From: Lucas De Marchi 

The new Link Copy engines in PVC may be fused off according to the
mslice_mask. Each bit of the MEML3_EN_MASK we read from the
GEN10_MIRROR_FUSE3 register disables a pair of link copy engines.

v2 (Tvrtko):
 - Minor cosmetic changes: s/u8/unsigned long/, use instance local
   variable.  (Tvrtko)

Bspec: 44483
Cc: Matt Roper 
Cc: Tvrtko Ursulin 
Signed-off-by: Lucas De Marchi 
Signed-off-by: Matt Roper 
Reviewed-by: José Roberto de Souza 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c | 29 +++
 1 file changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index c6e93db134b1..1adbf34c3632 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -686,6 +686,34 @@ static void engine_mask_apply_compute_fuses(struct 
intel_gt *gt)
}
 }
 
+static void engine_mask_apply_copy_fuses(struct intel_gt *gt)
+{
+   struct drm_i915_private *i915 = gt->i915;
+   struct intel_gt_info *info = >info;
+   unsigned long meml3_mask;
+   unsigned long quad;
+
+   meml3_mask = intel_uncore_read(gt->uncore, GEN10_MIRROR_FUSE3);
+   meml3_mask = REG_FIELD_GET(GEN12_MEML3_EN_MASK, meml3_mask);
+
+   /*
+* Link Copy engines may be fused off according to meml3_mask. Each
+* bit is a quad that houses 2 Link Copy and two Sub Copy engines.
+*/
+   for_each_clear_bit(quad, _mask, GEN12_MAX_MSLICES) {
+   unsigned int instance = quad * 2 + 1;
+   intel_engine_mask_t mask = GENMASK(_BCS(instance + 1),
+  _BCS(instance));
+
+   if (mask & info->engine_mask) {
+   drm_dbg(>drm, "bcs%u fused off\n", instance);
+   drm_dbg(>drm, "bcs%u fused off\n", instance + 1);
+
+   info->engine_mask &= ~mask;
+   }
+   }
+}
+
 /*
  * Determine which engines are fused off in our particular hardware.
  * Note that we have a catch-22 situation where we need to be able to access
@@ -768,6 +796,7 @@ static intel_engine_mask_t init_engine_mask(struct intel_gt 
*gt)
GEM_BUG_ON(vebox_mask != VEBOX_MASK(gt));
 
engine_mask_apply_compute_fuses(gt);
+   engine_mask_apply_copy_fuses(gt);
 
return info->engine_mask;
 }
-- 
2.35.1



[PATCH v2 10/12] drm/i915/pvc: Reset support for new copy engines

2022-05-05 Thread Matt Roper
Add the reset support for new copy engines in PVC.

Bspec: 52549
Original-author: CQ Tang
Signed-off-by: Matt Roper 
Reviewed-by: José Roberto de Souza 
Reviewed-by: Stuart Summers 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |  8 +
 drivers/gpu/drm/i915/gt/intel_gt_regs.h   | 44 +--
 2 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 4532c3ea9ace..c6e93db134b1 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -390,6 +390,14 @@ static u32 get_reset_domain(u8 ver, enum intel_engine_id 
id)
static const u32 engine_reset_domains[] = {
[RCS0]  = GEN11_GRDOM_RENDER,
[BCS0]  = GEN11_GRDOM_BLT,
+   [BCS1]  = XEHPC_GRDOM_BLT1,
+   [BCS2]  = XEHPC_GRDOM_BLT2,
+   [BCS3]  = XEHPC_GRDOM_BLT3,
+   [BCS4]  = XEHPC_GRDOM_BLT4,
+   [BCS5]  = XEHPC_GRDOM_BLT5,
+   [BCS6]  = XEHPC_GRDOM_BLT6,
+   [BCS7]  = XEHPC_GRDOM_BLT7,
+   [BCS8]  = XEHPC_GRDOM_BLT8,
[VCS0]  = GEN11_GRDOM_MEDIA,
[VCS1]  = GEN11_GRDOM_MEDIA2,
[VCS2]  = GEN11_GRDOM_MEDIA3,
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index fe09288a3145..98ede9c93f00 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -597,24 +597,32 @@
 /* GEN11 changed all bit defs except for FULL & RENDER */
 #define   GEN11_GRDOM_FULL GEN6_GRDOM_FULL
 #define   GEN11_GRDOM_RENDER   GEN6_GRDOM_RENDER
-#define   GEN11_GRDOM_BLT  (1 << 2)
-#define   GEN11_GRDOM_GUC  (1 << 3)
-#define   GEN11_GRDOM_MEDIA(1 << 5)
-#define   GEN11_GRDOM_MEDIA2   (1 << 6)
-#define   GEN11_GRDOM_MEDIA3   (1 << 7)
-#define   GEN11_GRDOM_MEDIA4   (1 << 8)
-#define   GEN11_GRDOM_MEDIA5   (1 << 9)
-#define   GEN11_GRDOM_MEDIA6   (1 << 10)
-#define   GEN11_GRDOM_MEDIA7   (1 << 11)
-#define   GEN11_GRDOM_MEDIA8   (1 << 12)
-#define   GEN11_GRDOM_VECS (1 << 13)
-#define   GEN11_GRDOM_VECS2(1 << 14)
-#define   GEN11_GRDOM_VECS3(1 << 15)
-#define   GEN11_GRDOM_VECS4(1 << 16)
-#define   GEN11_GRDOM_SFC0 (1 << 17)
-#define   GEN11_GRDOM_SFC1 (1 << 18)
-#define   GEN11_GRDOM_SFC2 (1 << 19)
-#define   GEN11_GRDOM_SFC3 (1 << 20)
+#define   XEHPC_GRDOM_BLT8 REG_BIT(31)
+#define   XEHPC_GRDOM_BLT7 REG_BIT(30)
+#define   XEHPC_GRDOM_BLT6 REG_BIT(29)
+#define   XEHPC_GRDOM_BLT5 REG_BIT(28)
+#define   XEHPC_GRDOM_BLT4 REG_BIT(27)
+#define   XEHPC_GRDOM_BLT3 REG_BIT(26)
+#define   XEHPC_GRDOM_BLT2 REG_BIT(25)
+#define   XEHPC_GRDOM_BLT1 REG_BIT(24)
+#define   GEN11_GRDOM_SFC3 REG_BIT(20)
+#define   GEN11_GRDOM_SFC2 REG_BIT(19)
+#define   GEN11_GRDOM_SFC1 REG_BIT(18)
+#define   GEN11_GRDOM_SFC0 REG_BIT(17)
+#define   GEN11_GRDOM_VECS4REG_BIT(16)
+#define   GEN11_GRDOM_VECS3REG_BIT(15)
+#define   GEN11_GRDOM_VECS2REG_BIT(14)
+#define   GEN11_GRDOM_VECS REG_BIT(13)
+#define   GEN11_GRDOM_MEDIA8   REG_BIT(12)
+#define   GEN11_GRDOM_MEDIA7   REG_BIT(11)
+#define   GEN11_GRDOM_MEDIA6   REG_BIT(10)
+#define   GEN11_GRDOM_MEDIA5   REG_BIT(9)
+#define   GEN11_GRDOM_MEDIA4   REG_BIT(8)
+#define   GEN11_GRDOM_MEDIA3   REG_BIT(7)
+#define   GEN11_GRDOM_MEDIA2   REG_BIT(6)
+#define   GEN11_GRDOM_MEDIAREG_BIT(5)
+#define   GEN11_GRDOM_GUC  REG_BIT(3)
+#define   GEN11_GRDOM_BLT  REG_BIT(2)
 #define   GEN11_VCS_SFC_RESET_BIT(instance)(GEN11_GRDOM_SFC0 << 
((instance) >> 1))
 #define   GEN11_VECS_SFC_RESET_BIT(instance)   (GEN11_GRDOM_SFC0 << (instance))
 
-- 
2.35.1



[PATCH v2 11/12] drm/i915/pvc: skip all copy engines from aux table invalidate

2022-05-05 Thread Matt Roper
From: Lucas De Marchi 

As we have more copy engines now, mask all of them from aux table
invalidate.

v2 (MattR):
 - Use I915_MAX_BCS to determine mask rather than hardcoding BCS8.
   (Prathap)

Cc: Prathap Kumar Valsan 
Signed-off-by: Lucas De Marchi 
Signed-off-by: Matt Roper 
Reviewed-by: José Roberto de Souza 
Reviewed-by: Prathap Kumar Valsan 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index 11c72792573d..0f5ab2c99ffc 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -276,7 +276,8 @@ int gen12_emit_flush_xcs(struct i915_request *rq, u32 mode)
if (!HAS_FLAT_CCS(rq->engine->i915) &&
(rq->engine->class == VIDEO_DECODE_CLASS ||
 rq->engine->class == VIDEO_ENHANCEMENT_CLASS)) {
-   aux_inv = rq->engine->mask & ~BIT(BCS0);
+   aux_inv = rq->engine->mask &
+   ~GENMASK(_BCS(I915_MAX_BCS - 1), BCS0);
if (aux_inv)
cmd += 4;
}
-- 
2.35.1



[PATCH v2 08/12] drm/i915/pvc: Engine definitions for new copy engines

2022-05-05 Thread Matt Roper
This patch adds the basic definitions needed to support
new copy engines. Also updating the cmd_info to accommodate
new engines, as the engine id's of legacy engines have been
changed.

v2:
 - Add _BCS(n) definition, similar to other engines.  (Tvrtko)
 - Add I915_MAX_BCS definition, similar to other engnes.  (Prathap)
 - Move GVT change to avoid u16 overflow to its own patch.  (Tvrtko)

Original-author: CQ Tang
Cc: Tvrtko Ursulin 
Cc: Prathap Kumar Valsan 
Signed-off-by: Matt Roper 
Reviewed-by: José Roberto de Souza 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c| 56 
 drivers/gpu/drm/i915/gt/intel_engine_types.h | 12 -
 drivers/gpu/drm/i915/gt/intel_gt_regs.h  |  8 +++
 drivers/gpu/drm/i915/i915_reg.h  |  8 +++
 4 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 14c6ddbbfde8..4532c3ea9ace 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -71,6 +71,62 @@ static const struct engine_info intel_engines[] = {
{ .graphics_ver = 6, .base = BLT_RING_BASE }
},
},
+   [BCS1] = {
+   .class = COPY_ENGINE_CLASS,
+   .instance = 1,
+   .mmio_bases = {
+   { .graphics_ver = 12, .base = XEHPC_BCS1_RING_BASE }
+   },
+   },
+   [BCS2] = {
+   .class = COPY_ENGINE_CLASS,
+   .instance = 2,
+   .mmio_bases = {
+   { .graphics_ver = 12, .base = XEHPC_BCS2_RING_BASE }
+   },
+   },
+   [BCS3] = {
+   .class = COPY_ENGINE_CLASS,
+   .instance = 3,
+   .mmio_bases = {
+   { .graphics_ver = 12, .base = XEHPC_BCS3_RING_BASE }
+   },
+   },
+   [BCS4] = {
+   .class = COPY_ENGINE_CLASS,
+   .instance = 4,
+   .mmio_bases = {
+   { .graphics_ver = 12, .base = XEHPC_BCS4_RING_BASE }
+   },
+   },
+   [BCS5] = {
+   .class = COPY_ENGINE_CLASS,
+   .instance = 5,
+   .mmio_bases = {
+   { .graphics_ver = 12, .base = XEHPC_BCS5_RING_BASE }
+   },
+   },
+   [BCS6] = {
+   .class = COPY_ENGINE_CLASS,
+   .instance = 6,
+   .mmio_bases = {
+   { .graphics_ver = 12, .base = XEHPC_BCS6_RING_BASE }
+   },
+   },
+   [BCS7] = {
+   .class = COPY_ENGINE_CLASS,
+   .instance = 7,
+   .mmio_bases = {
+   { .graphics_ver = 12, .base = XEHPC_BCS7_RING_BASE }
+   },
+   },
+   [BCS8] = {
+   .class = COPY_ENGINE_CLASS,
+   .instance = 8,
+   .mmio_bases = {
+   { .graphics_ver = 12, .base = XEHPC_BCS8_RING_BASE }
+   },
+   },
[VCS0] = {
.class = VIDEO_DECODE_CLASS,
.instance = 0,
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 298f2cc7a879..2286f96f5f87 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -35,7 +35,7 @@
 #define OTHER_CLASS4
 #define COMPUTE_CLASS  5
 #define MAX_ENGINE_CLASS   5
-#define MAX_ENGINE_INSTANCE7
+#define MAX_ENGINE_INSTANCE8
 
 #define I915_MAX_SLICES3
 #define I915_MAX_SUBSLICES 8
@@ -99,6 +99,7 @@ struct i915_ctx_workarounds {
 #define I915_MAX_SFC   (I915_MAX_VCS / 2)
 #define I915_MAX_CCS   4
 #define I915_MAX_RCS   1
+#define I915_MAX_BCS   9
 
 /*
  * Engine IDs definitions.
@@ -107,6 +108,15 @@ struct i915_ctx_workarounds {
 enum intel_engine_id {
RCS0 = 0,
BCS0,
+   BCS1,
+   BCS2,
+   BCS3,
+   BCS4,
+   BCS5,
+   BCS6,
+   BCS7,
+   BCS8,
+#define _BCS(n) (BCS0 + (n))
VCS0,
VCS1,
VCS2,
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index a0a49c16babd..aa2c0974b02c 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1476,6 +1476,14 @@
 #define   GEN11_KCR(19)
 #define   GEN11_GTPM   (16)
 #define   GEN11_BCS(15)
+#define   XEHPC_BCS1   (14)
+#define   XEHPC_BCS2   (13)
+#define   XEHPC_BCS3   (12)
+#define   XEHPC_BCS4   (11)
+#define   XEHPC_BCS5   (10)
+#define   XEHPC_BCS6   (9)
+#define   XEHPC_BCS7   (8)
+#define   XEHPC_BCS8   

[PATCH v2 05/12] drm/i915/pvc: Remove additional 3D flags from PIPE_CONTROL

2022-05-05 Thread Matt Roper
From: Stuart Summers 

Although we already strip 3D-specific flags from PIPE_CONTROL
instructions when submitting to a compute engine, there are some
additional flags that need to be removed when the platform as a whole
lacks a 3D pipeline.  Add those restrictions here.

Bspec: 47112
Signed-off-by: Stuart Summers 
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c | 18 --
 drivers/gpu/drm/i915/gt/intel_gpu_commands.h | 12 ++--
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 drivers/gpu/drm/i915/i915_pci.c  |  3 ++-
 drivers/gpu/drm/i915/intel_device_info.h |  3 ++-
 5 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index 3e13960615bd..11c72792573d 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -197,8 +197,10 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode)
 
flags |= PIPE_CONTROL_CS_STALL;
 
-   if (engine->class == COMPUTE_CLASS)
-   flags &= ~PIPE_CONTROL_3D_FLAGS;
+   if (LACKS_3D_PIPELINE(engine->i915))
+   flags &= ~PIPE_CONTROL_3D_ARCH_FLAGS;
+   else if (engine->class == COMPUTE_CLASS)
+   flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS;
 
cs = intel_ring_begin(rq, 6);
if (IS_ERR(cs))
@@ -227,8 +229,10 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode)
 
flags |= PIPE_CONTROL_CS_STALL;
 
-   if (engine->class == COMPUTE_CLASS)
-   flags &= ~PIPE_CONTROL_3D_FLAGS;
+   if (LACKS_3D_PIPELINE(engine->i915))
+   flags &= ~PIPE_CONTROL_3D_ARCH_FLAGS;
+   else if (engine->class == COMPUTE_CLASS)
+   flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS;
 
if (!HAS_FLAT_CCS(rq->engine->i915))
count = 8 + 4;
@@ -716,8 +720,10 @@ u32 *gen12_emit_fini_breadcrumb_rcs(struct i915_request 
*rq, u32 *cs)
/* Wa_1409600907 */
flags |= PIPE_CONTROL_DEPTH_STALL;
 
-   if (rq->engine->class == COMPUTE_CLASS)
-   flags &= ~PIPE_CONTROL_3D_FLAGS;
+   if (LACKS_3D_PIPELINE(rq->engine->i915))
+   flags &= ~PIPE_CONTROL_3D_ARCH_FLAGS;
+   else if (rq->engine->class == COMPUTE_CLASS)
+   flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS;
 
cs = gen12_emit_ggtt_write_rcs(cs,
   rq->fence.seqno,
diff --git a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h 
b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
index 556bca3be804..900755f4b787 100644
--- a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
+++ b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
@@ -288,8 +288,8 @@
 #define   PIPE_CONTROL_DEPTH_CACHE_FLUSH   (1<<0)
 #define   PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
 
-/* 3D-related flags can't be set on compute engine */
-#define PIPE_CONTROL_3D_FLAGS (\
+/* 3D-related flags that can't be set on _engines_ that lack a 3D pipeline */
+#define PIPE_CONTROL_3D_ENGINE_FLAGS (\
PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH | \
PIPE_CONTROL_DEPTH_CACHE_FLUSH | \
PIPE_CONTROL_TILE_CACHE_FLUSH | \
@@ -300,6 +300,14 @@
PIPE_CONTROL_VF_CACHE_INVALIDATE | \
PIPE_CONTROL_GLOBAL_SNAPSHOT_RESET)
 
+/* 3D-related flags that can't be set on _platforms_ that lack a 3D pipeline */
+#define PIPE_CONTROL_3D_ARCH_FLAGS ( \
+   PIPE_CONTROL_3D_ENGINE_FLAGS | \
+   PIPE_CONTROL_INDIRECT_STATE_DISABLE | \
+   PIPE_CONTROL_FLUSH_ENABLE | \
+   PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | \
+   PIPE_CONTROL_DC_FLUSH_ENABLE)
+
 #define MI_MATH(x) MI_INSTR(0x1a, (x) - 1)
 #define MI_MATH_INSTR(opcode, op1, op2) ((opcode) << 20 | (op1) << 10 | (op2))
 /* Opcodes for MI_MATH_INSTR */
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b389674b5210..1e153cefc92e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1403,6 +1403,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 
 #define HAS_MBUS_JOINING(i915) (IS_ALDERLAKE_P(i915))
 
+#define LACKS_3D_PIPELINE(i915)(INTEL_INFO(i915)->lacks_3d_pipeline)
+
 /* i915_gem.c */
 void i915_gem_init_early(struct drm_i915_private *dev_priv);
 void i915_gem_cleanup_early(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 07722cdf63ac..14e0e8225324 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -1077,7 +1077,8 @@ static const struct intel_device_info ats_m_info = {
 #define XE_HPC_FEATURES \
XE_HP_FEATURES, \
.dma_mask_size = 

[PATCH v2 07/12] drm/i915/gvt: Use intel_engine_mask_t for ring mask

2022-05-05 Thread Matt Roper
When i915 adds additional PVC blitter instances (in an upcoming patch),
the definition of VECS0 will change from bit(10) to bit(18), causing
GVT's R_ALL mask to overflow the u16 storage that's currently used.
Let's replace the u16 with an intel_engine_mask_t to ensure we avoid
this.

Cc: Tvrtko Ursulin 
Cc: Zhi Wang 
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/gvt/cmd_parser.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c 
b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index b9eb75a2b400..0ba2a3455d99 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -428,7 +428,7 @@ struct cmd_info {
 #define R_VECS BIT(VECS0)
 #define R_ALL (R_RCS | R_VCS | R_BCS | R_VECS)
/* rings that support this cmd: BLT/RCS/VCS/VECS */
-   u16 rings;
+   intel_engine_mask_t rings;
 
/* devices that support this cmd: SNB/IVB/HSW/... */
u16 devices;
-- 
2.35.1



[PATCH v2 03/12] drm/i915/pvc: Define MOCS table for PVC

2022-05-05 Thread Matt Roper
From: Ayaz A Siddiqui 

v2 (MattR):
 - Clarify comment above RING_CMD_CCTL programming.
 - Remove bspec reference from field definition.  (Lucas)
 - Add WARN if we try to use a (presumably uninitialized) wb_index of 0.
   On most platforms 0 is an invalid MOCS entry and even on the ones
   where it isn't, it isn't the right setting for wb_index.  (Lucas)

Bspec: 45101, 72161
Cc: Lucas De Marchi 
Signed-off-by: Ayaz A Siddiqui 
Signed-off-by: Fei Yang 
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/gt/intel_gt_types.h|  1 +
 drivers/gpu/drm/i915/gt/intel_mocs.c| 24 -
 drivers/gpu/drm/i915/gt/intel_workarounds.c | 30 -
 drivers/gpu/drm/i915/i915_drv.h |  2 ++
 drivers/gpu/drm/i915/i915_pci.c |  3 ++-
 drivers/gpu/drm/i915/intel_device_info.h|  1 +
 6 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h 
b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index b06611c1d4ad..7853ea194ea6 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -221,6 +221,7 @@ struct intel_gt {
 
struct {
u8 uc_index;
+   u8 wb_index; /* Only for platforms listed in Bspec: 72161 */
} mocs;
 
struct intel_pxp pxp;
diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.c 
b/drivers/gpu/drm/i915/gt/intel_mocs.c
index c4c37585ae8c..c6ebe2781076 100644
--- a/drivers/gpu/drm/i915/gt/intel_mocs.c
+++ b/drivers/gpu/drm/i915/gt/intel_mocs.c
@@ -23,6 +23,7 @@ struct drm_i915_mocs_table {
unsigned int n_entries;
const struct drm_i915_mocs_entry *table;
u8 uc_index;
+   u8 wb_index; /* Only used on HAS_L3_CCS_READ() platforms */
u8 unused_entries_index;
 };
 
@@ -47,6 +48,7 @@ struct drm_i915_mocs_table {
 
 /* Helper defines */
 #define GEN9_NUM_MOCS_ENTRIES  64  /* 63-64 are reserved, but configured. */
+#define PVC_NUM_MOCS_ENTRIES   3
 
 /* (e)LLC caching options */
 /*
@@ -394,6 +396,17 @@ static const struct drm_i915_mocs_entry 
dg2_mocs_table_g10_ax[] = {
MOCS_ENTRY(3, 0, L3_3_WB | L3_LKUP(1)),
 };
 
+static const struct drm_i915_mocs_entry pvc_mocs_table[] = {
+   /* Error */
+   MOCS_ENTRY(0, 0, L3_3_WB),
+
+   /* UC */
+   MOCS_ENTRY(1, 0, L3_1_UC),
+
+   /* WB */
+   MOCS_ENTRY(2, 0, L3_3_WB),
+};
+
 enum {
HAS_GLOBAL_MOCS = BIT(0),
HAS_ENGINE_MOCS = BIT(1),
@@ -423,7 +436,14 @@ static unsigned int get_mocs_settings(const struct 
drm_i915_private *i915,
memset(table, 0, sizeof(struct drm_i915_mocs_table));
 
table->unused_entries_index = I915_MOCS_PTE;
-   if (IS_DG2(i915)) {
+   if (IS_PONTEVECCHIO(i915)) {
+   table->size = ARRAY_SIZE(pvc_mocs_table);
+   table->table = pvc_mocs_table;
+   table->n_entries = PVC_NUM_MOCS_ENTRIES;
+   table->uc_index = 1;
+   table->wb_index = 2;
+   table->unused_entries_index = 2;
+   } else if (IS_DG2(i915)) {
if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0)) {
table->size = ARRAY_SIZE(dg2_mocs_table_g10_ax);
table->table = dg2_mocs_table_g10_ax;
@@ -622,6 +642,8 @@ void intel_set_mocs_index(struct intel_gt *gt)
 
get_mocs_settings(gt->i915, );
gt->mocs.uc_index = table.uc_index;
+   if (HAS_L3_CCS_READ(gt->i915))
+   gt->mocs.wb_index = table.wb_index;
 }
 
 void intel_mocs_init(struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c 
b/drivers/gpu/drm/i915/gt/intel_workarounds.c
index a05c4b99b3fb..756807c4b405 100644
--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
@@ -1994,19 +1994,37 @@ void intel_engine_apply_whitelist(struct 
intel_engine_cs *engine)
 static void
 engine_fake_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
 {
-   u8 mocs;
+   u8 mocs_w, mocs_r;
 
/*
-* RING_CMD_CCTL are need to be programed to un-cached
-* for memory writes and reads outputted by Command
-* Streamers on Gen12 onward platforms.
+* RING_CMD_CCTL specifies the default MOCS entry that will be used
+* by the command streamer when executing commands that don't have
+* a way to explicitly specify a MOCS setting.  The default should
+* usually reference whichever MOCS entry corresponds to uncached
+* behavior, although use of a WB cached entry is recommended by the
+* spec in certain circumstances on specific platforms.
 */
if (GRAPHICS_VER(engine->i915) >= 12) {
-   mocs = engine->gt->mocs.uc_index;
+   mocs_r = engine->gt->mocs.uc_index;
+   mocs_w = engine->gt->mocs.uc_index;
+
+   if (HAS_L3_CCS_READ(engine->i915) &&
+   engine->class == COMPUTE_CLASS) {
+   

[PATCH v2 04/12] drm/i915/pvc: Read correct RP_STATE_CAP register

2022-05-05 Thread Matt Roper
The SoC registers, including RP_STATE_CAP, have moved to a new location
in GTTMMADR on Ponte Vecchio.  We need to update the register offset
accordingly.

Cc: Rodrigo Vivi 
Signed-off-by: Matt Roper 
Reviewed-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/gt/intel_rps.c | 4 +++-
 drivers/gpu/drm/i915/i915_reg.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c 
b/drivers/gpu/drm/i915/gt/intel_rps.c
index 3476a11f294c..3bd8415a0f1b 100644
--- a/drivers/gpu/drm/i915/gt/intel_rps.c
+++ b/drivers/gpu/drm/i915/gt/intel_rps.c
@@ -1075,7 +1075,9 @@ static u32 intel_rps_read_state_cap(struct intel_rps *rps)
struct drm_i915_private *i915 = rps_to_i915(rps);
struct intel_uncore *uncore = rps_to_uncore(rps);
 
-   if (IS_XEHPSDV(i915))
+   if (IS_PONTEVECCHIO(i915))
+   return intel_uncore_read(uncore, PVC_RP_STATE_CAP);
+   else if (IS_XEHPSDV(i915))
return intel_uncore_read(uncore, XEHPSDV_RP_STATE_CAP);
else if (IS_GEN9_LP(i915))
return intel_uncore_read(uncore, BXT_RP_STATE_CAP);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9ccb67eec1bd..4a3d7b96ef43 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1846,6 +1846,7 @@
 #define BXT_RP_STATE_CAP_MMIO(0x138170)
 #define GEN9_RP_STATE_LIMITS   _MMIO(0x138148)
 #define XEHPSDV_RP_STATE_CAP   _MMIO(0x250014)
+#define PVC_RP_STATE_CAP   _MMIO(0x281014)
 
 #define GT0_PERF_LIMIT_REASONS _MMIO(0x1381a8)
 #define   GT0_PERF_LIMIT_REASONS_MASK  0xde3
-- 
2.35.1



[PATCH v2 02/12] drm/i915/pvc: Add forcewake support

2022-05-05 Thread Matt Roper
Add PVC's forcewake ranges.

v2:
 - Drop replicated comment completely; move general cleanup of the
   documentation to a separate patch.

Bspec: 67609
Cc: Daniele Ceraolo Spurio 
Cc: Stuart Summers 
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/intel_uncore.c   | 142 +-
 drivers/gpu/drm/i915/selftests/intel_uncore.c |   2 +
 2 files changed, 143 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index 095e071e4053..fac0ff60bfbf 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -1076,6 +1076,45 @@ static const struct i915_range dg2_shadowed_regs[] = {
{ .start = 0x1F8510, .end = 0x1F8550 },
 };
 
+static const struct i915_range pvc_shadowed_regs[] = {
+   { .start =   0x2030, .end =   0x2030 },
+   { .start =   0x2510, .end =   0x2550 },
+   { .start =   0xA008, .end =   0xA00C },
+   { .start =   0xA188, .end =   0xA188 },
+   { .start =   0xA278, .end =   0xA278 },
+   { .start =   0xA540, .end =   0xA56C },
+   { .start =   0xC4C8, .end =   0xC4C8 },
+   { .start =   0xC4E0, .end =   0xC4E0 },
+   { .start =   0xC600, .end =   0xC600 },
+   { .start =   0xC658, .end =   0xC658 },
+   { .start =  0x22030, .end =  0x22030 },
+   { .start =  0x22510, .end =  0x22550 },
+   { .start = 0x1C0030, .end = 0x1C0030 },
+   { .start = 0x1C0510, .end = 0x1C0550 },
+   { .start = 0x1C4030, .end = 0x1C4030 },
+   { .start = 0x1C4510, .end = 0x1C4550 },
+   { .start = 0x1C8030, .end = 0x1C8030 },
+   { .start = 0x1C8510, .end = 0x1C8550 },
+   { .start = 0x1D0030, .end = 0x1D0030 },
+   { .start = 0x1D0510, .end = 0x1D0550 },
+   { .start = 0x1D4030, .end = 0x1D4030 },
+   { .start = 0x1D4510, .end = 0x1D4550 },
+   { .start = 0x1D8030, .end = 0x1D8030 },
+   { .start = 0x1D8510, .end = 0x1D8550 },
+   { .start = 0x1E0030, .end = 0x1E0030 },
+   { .start = 0x1E0510, .end = 0x1E0550 },
+   { .start = 0x1E4030, .end = 0x1E4030 },
+   { .start = 0x1E4510, .end = 0x1E4550 },
+   { .start = 0x1E8030, .end = 0x1E8030 },
+   { .start = 0x1E8510, .end = 0x1E8550 },
+   { .start = 0x1F0030, .end = 0x1F0030 },
+   { .start = 0x1F0510, .end = 0x1F0550 },
+   { .start = 0x1F4030, .end = 0x1F4030 },
+   { .start = 0x1F4510, .end = 0x1F4550 },
+   { .start = 0x1F8030, .end = 0x1F8030 },
+   { .start = 0x1F8510, .end = 0x1F8550 },
+};
+
 static int mmio_range_cmp(u32 key, const struct i915_range *range)
 {
if (key < range->start)
@@ -1525,6 +1564,103 @@ static const struct intel_forcewake_range 
__dg2_fw_ranges[] = {
XEHP_FWRANGES(FORCEWAKE_RENDER)
 };
 
+static const struct intel_forcewake_range __pvc_fw_ranges[] = {
+   GEN_FW_RANGE(0x0, 0xaff, 0),
+   GEN_FW_RANGE(0xb00, 0xbff, FORCEWAKE_GT),
+   GEN_FW_RANGE(0xc00, 0xfff, 0),
+   GEN_FW_RANGE(0x1000, 0x1fff, FORCEWAKE_GT),
+   GEN_FW_RANGE(0x2000, 0x26ff, FORCEWAKE_RENDER),
+   GEN_FW_RANGE(0x2700, 0x2fff, FORCEWAKE_GT),
+   GEN_FW_RANGE(0x3000, 0x3fff, FORCEWAKE_RENDER),
+   GEN_FW_RANGE(0x4000, 0x813f, FORCEWAKE_GT), /*
+   0x4000 - 0x4aff: gt
+   0x4b00 - 0x4fff: reserved
+   0x5000 - 0x51ff: gt
+   0x5200 - 0x52ff: reserved
+   0x5300 - 0x53ff: gt
+   0x5400 - 0x7fff: reserved
+   0x8000 - 0x813f: gt */
+   GEN_FW_RANGE(0x8140, 0x817f, FORCEWAKE_RENDER),
+   GEN_FW_RANGE(0x8180, 0x81ff, 0),
+   GEN_FW_RANGE(0x8200, 0x94cf, FORCEWAKE_GT), /*
+   0x8200 - 0x82ff: gt
+   0x8300 - 0x84ff: reserved
+   0x8500 - 0x887f: gt
+   0x8880 - 0x8a7f: reserved
+   0x8a80 - 0x8aff: gt
+   0x8b00 - 0x8fff: reserved
+   0x9000 - 0x947f: gt
+   0x9480 - 0x94cf: reserved */
+   GEN_FW_RANGE(0x94d0, 0x955f, FORCEWAKE_RENDER),
+   GEN_FW_RANGE(0x9560, 0x967f, 0), /*
+   0x9560 - 0x95ff: always on
+   0x9600 - 0x967f: reserved */
+   GEN_FW_RANGE(0x9680, 0x97ff, FORCEWAKE_RENDER), /*
+   0x9680 - 0x96ff: render
+   0x9700 - 0x97ff: reserved */
+   GEN_FW_RANGE(0x9800, 0xcfff, FORCEWAKE_GT), /*
+   0x9800 - 0xb4ff: gt
+   0xb500 - 0xbfff: reserved
+   0xc000 - 0xcfff: gt */
+   GEN_FW_RANGE(0xd000, 0xd3ff, 0),
+   GEN_FW_RANGE(0xd400, 0xdbff, FORCEWAKE_GT),
+   GEN_FW_RANGE(0xdc00, 0xdcff, FORCEWAKE_RENDER),
+   GEN_FW_RANGE(0xdd00, 0xde7f, FORCEWAKE_GT), /*
+   0xdd00 - 0xddff: gt
+   0xde00 - 0xde7f: reserved */
+   GEN_FW_RANGE(0xde80, 0xe8ff, FORCEWAKE_RENDER), /*
+   0xde80 - 0xdeff: render
+   0xdf00 - 0xe1ff: reserved
+   0xe200 - 0xe7ff: render
+   0xe800 - 0xe8ff: reserved */

RE: [PATCH v1 04/15] mm: add device coherent checker to remove migration pte

2022-05-05 Thread Sierra Guiza, Alejandro (Alex)
@apop...@nvidia.com Could you please check this patch? It's somehow related to 
migrate_device_page() for long term device coherent pages.

Regards,
Alex Sierra
> -Original Message-
> From: amd-gfx  On Behalf Of Alex
> Sierra
> Sent: Thursday, May 5, 2022 4:34 PM
> To: j...@nvidia.com
> Cc: rcampb...@nvidia.com; wi...@infradead.org; da...@redhat.com;
> Kuehling, Felix ; apop...@nvidia.com; amd-
> g...@lists.freedesktop.org; linux-...@vger.kernel.org; linux...@kvack.org;
> jgli...@redhat.com; dri-devel@lists.freedesktop.org; akpm@linux-
> foundation.org; linux-e...@vger.kernel.org; h...@lst.de
> Subject: [PATCH v1 04/15] mm: add device coherent checker to remove
> migration pte
> 
> During remove_migration_pte(), entries for device coherent type pages that
> were not created through special migration ptes, ignore _PAGE_RW flag. This
> path can be found at migrate_device_page(), where valid vma is not
> required. In this case, migrate_vma_collect_pmd() is not called and special
> migration ptes are not set.
> 
> Signed-off-by: Alex Sierra 
> ---
>  mm/migrate.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/mm/migrate.c b/mm/migrate.c index
> 6c31ee1e1c9b..e18ddee56f37 100644
> --- a/mm/migrate.c
> +++ b/mm/migrate.c
> @@ -206,7 +206,8 @@ static bool remove_migration_pte(struct folio *folio,
>* Recheck VMA as permissions can change since migration
> started
>*/
>   entry = pte_to_swp_entry(*pvmw.pte);
> - if (is_writable_migration_entry(entry))
> + if (is_writable_migration_entry(entry) ||
> + is_device_coherent_page(pfn_to_page(pvmw.pfn)))
>   pte = maybe_mkwrite(pte, vma);
>   else if (pte_swp_uffd_wp(*pvmw.pte))
>   pte = pte_mkuffd_wp(pte);
> --
> 2.32.0



Re: [Intel-gfx] [PATCH v5 1/2] module: update dependencies at try_module_get()

2022-05-05 Thread Andi Shyti
Hi Mauro,

[...]

> +static int ref_module_dependency(struct module *mod, struct module *this)
> +{
> + int ret;
> +
> + if (!this || !this->name)
> + return -EINVAL;
> +
> + if (mod == this)
> + return 0;
> +
> + mutex_lock(_mutex);
> +
> + ret = ref_module(this, mod);
> +
> +#ifdef CONFIG_MODULE_UNLOAD
> + if (ret)
> + goto ret;
> +
> + ret = sysfs_create_link(mod->holders_dir,
> + >mkobj.kobj, this->name);
> +#endif
> +
> +ret:
> + mutex_unlock(_mutex);
> + return ret;
> +}
> +
>  /* Clear the unload stuff of the module. */
>  static void module_unload_free(struct module *mod)
>  {
> @@ -841,24 +886,16 @@ void __module_get(struct module *module)
>  }
>  EXPORT_SYMBOL(__module_get);
>  
> -bool try_module_get(struct module *module)
> +bool try_module_get_owner(struct module *module, struct module *this)
>  {
> - bool ret = true;
> + int ret = __try_module_get(module);
>  
> - if (module) {
> - preempt_disable();
> - /* Note: here, we can fail to get a reference */
> - if (likely(module_is_live(module) &&
> -atomic_inc_not_zero(>refcnt) != 0))
> - trace_module_get(module, _RET_IP_);
> - else
> - ret = false;
> + if (ret)
> + ref_module_dependency(module, this);

do we care about the return value here?

Andi

>  
> - preempt_enable();
> - }
>   return ret;
>  }
> -EXPORT_SYMBOL(try_module_get);
> +EXPORT_SYMBOL(try_module_get_owner);
>  
>  void module_put(struct module *module)
>  {
> -- 
> 2.35.1


[PATCH v1 14/15] tools: add hmm gup tests for device coherent type

2022-05-05 Thread Alex Sierra
The intention is to test hmm device coherent type under different get
user pages paths. Also, test gup with FOLL_LONGTERM flag set in
device coherent pages. These pages should get migrated back to system
memory.

Signed-off-by: Alex Sierra 
---
 tools/testing/selftests/vm/hmm-tests.c | 104 +
 1 file changed, 104 insertions(+)

diff --git a/tools/testing/selftests/vm/hmm-tests.c 
b/tools/testing/selftests/vm/hmm-tests.c
index 84ec8c4a1dc7..65e30ab6494c 100644
--- a/tools/testing/selftests/vm/hmm-tests.c
+++ b/tools/testing/selftests/vm/hmm-tests.c
@@ -36,6 +36,7 @@
  * in the usual include/uapi/... directory.
  */
 #include "../../../../lib/test_hmm_uapi.h"
+#include "../../../../mm/gup_test.h"
 
 struct hmm_buffer {
void*ptr;
@@ -60,6 +61,8 @@ enum {
 #define NTIMES 10
 
 #define ALIGN(x, a) (((x) + (a - 1)) & (~((a) - 1)))
+/* Just the flags we need, copied from mm.h: */
+#define FOLL_WRITE 0x01/* check pte is writable */
 
 FIXTURE(hmm)
 {
@@ -1766,4 +1769,105 @@ TEST_F(hmm, exclusive_cow)
hmm_buffer_free(buffer);
 }
 
+static int gup_test_exec(int gup_fd, unsigned long addr,
+int cmd, int npages, int size)
+{
+   struct gup_test gup = {
+   .nr_pages_per_call  = npages,
+   .addr   = addr,
+   .gup_flags  = FOLL_WRITE,
+   .size   = size,
+   };
+
+   if (ioctl(gup_fd, cmd, )) {
+   perror("ioctl on error\n");
+   return errno;
+   }
+
+   return 0;
+}
+
+/*
+ * Test get user device pages through gup_test. Setting PIN_LONGTERM flag.
+ * This should trigger a migration back to system memory for both, private
+ * and coherent type pages.
+ * This test makes use of gup_test module. Make sure GUP_TEST_CONFIG is added
+ * to your configuration before you run it.
+ */
+TEST_F(hmm, hmm_gup_test)
+{
+   struct hmm_buffer *buffer;
+   int gup_fd;
+   unsigned long npages;
+   unsigned long size;
+   unsigned long i;
+   int *ptr;
+   int ret;
+   unsigned char *m;
+
+   gup_fd = open("/sys/kernel/debug/gup_test", O_RDWR);
+   if (gup_fd == -1)
+   SKIP(return, "Skipping test, could not find gup_test driver");
+
+   npages = 3;
+   size = npages << self->page_shift;
+
+   buffer = malloc(sizeof(*buffer));
+   ASSERT_NE(buffer, NULL);
+
+   buffer->fd = -1;
+   buffer->size = size;
+   buffer->mirror = malloc(size);
+   ASSERT_NE(buffer->mirror, NULL);
+
+   buffer->ptr = mmap(NULL, size,
+  PROT_READ | PROT_WRITE,
+  MAP_PRIVATE | MAP_ANONYMOUS,
+  buffer->fd, 0);
+   ASSERT_NE(buffer->ptr, MAP_FAILED);
+
+   /* Initialize buffer in system memory. */
+   for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
+   ptr[i] = i;
+
+   /* Migrate memory to device. */
+   ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
+   ASSERT_EQ(ret, 0);
+   ASSERT_EQ(buffer->cpages, npages);
+   /* Check what the device read. */
+   for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
+   ASSERT_EQ(ptr[i], i);
+
+   ASSERT_EQ(gup_test_exec(gup_fd,
+   (unsigned long)buffer->ptr,
+   GUP_BASIC_TEST, 1, self->page_size), 0);
+   ASSERT_EQ(gup_test_exec(gup_fd,
+   (unsigned long)buffer->ptr + 1 * 
self->page_size,
+   GUP_FAST_BENCHMARK, 1, self->page_size), 0);
+   ASSERT_EQ(gup_test_exec(gup_fd,
+   (unsigned long)buffer->ptr + 2 * 
self->page_size,
+   PIN_LONGTERM_BENCHMARK, 1, self->page_size), 0);
+
+   /* Take snapshot to CPU pagetables */
+   ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
+   ASSERT_EQ(ret, 0);
+   ASSERT_EQ(buffer->cpages, npages);
+   m = buffer->mirror;
+   if (hmm_is_coherent_type(variant->device_number)) {
+   ASSERT_EQ(HMM_DMIRROR_PROT_DEV_COHERENT_LOCAL | 
HMM_DMIRROR_PROT_WRITE, m[0]);
+   ASSERT_EQ(HMM_DMIRROR_PROT_DEV_COHERENT_LOCAL | 
HMM_DMIRROR_PROT_WRITE, m[1]);
+   } else {
+   ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[0]);
+   ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[1]);
+   }
+   ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[2]);
+   /* Check again the content on the pages. Make sure there's no
+* corrupted data.
+*/
+   for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
+   ASSERT_EQ(ptr[i], i);
+
+   close(gup_fd);
+   hmm_buffer_free(buffer);
+}
 TEST_HARNESS_MAIN
-- 
2.32.0



[PATCH v1 13/15] mm: handling Non-LRU pages returned by vm_normal_pages

2022-05-05 Thread Alex Sierra
With DEVICE_COHERENT, we'll soon have vm_normal_pages() return
device-managed anonymous pages that are not LRU pages. Although they
behave like normal pages for purposes of mapping in CPU page, and for
COW. They do not support LRU lists, NUMA migration or THP.

We also introduced a FOLL_LRU flag that adds the same behaviour to
follow_page and related APIs, to allow callers to specify that they
expect to put pages on an LRU list.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
---
 fs/proc/task_mmu.c | 2 +-
 include/linux/mm.h | 3 ++-
 mm/gup.c   | 2 ++
 mm/huge_memory.c   | 2 +-
 mm/khugepaged.c| 9 ++---
 mm/ksm.c   | 6 +++---
 mm/madvise.c   | 4 ++--
 mm/memory.c| 9 -
 mm/mempolicy.c | 2 +-
 mm/migrate.c   | 4 ++--
 mm/mlock.c | 2 +-
 mm/mprotect.c  | 2 +-
 12 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index f46060eb91b5..5d620733f173 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -1785,7 +1785,7 @@ static struct page *can_gather_numa_stats(pte_t pte, 
struct vm_area_struct *vma,
return NULL;
 
page = vm_normal_page(vma, addr, pte);
-   if (!page)
+   if (!page || is_zone_device_page(page))
return NULL;
 
if (PageReserved(page))
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 9f44254af8ce..d7f253a0c41e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -601,7 +601,7 @@ struct vm_operations_struct {
 #endif
/*
 * Called by vm_normal_page() for special PTEs to find the
-* page for @addr.  This is useful if the default behavior
+* page for @addr. This is useful if the default behavior
 * (using pte_page()) would not find the correct page.
 */
struct page *(*find_special_page)(struct vm_area_struct *vma,
@@ -2929,6 +2929,7 @@ struct page *follow_page(struct vm_area_struct *vma, 
unsigned long address,
 #define FOLL_NUMA  0x200   /* force NUMA hinting page fault */
 #define FOLL_MIGRATION 0x400   /* wait for page to replace migration entry */
 #define FOLL_TRIED 0x800   /* a retry, previous pass started an IO */
+#define FOLL_LRU0x1000  /* return only LRU (anon or page cache) */
 #define FOLL_REMOTE0x2000  /* we are working on non-current tsk/mm */
 #define FOLL_COW   0x4000  /* internal GUP flag */
 #define FOLL_ANON  0x8000  /* don't do file mappings */
diff --git a/mm/gup.c b/mm/gup.c
index a214c8df7140..13bf04bce132 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -479,6 +479,8 @@ static struct page *follow_page_pte(struct vm_area_struct 
*vma,
}
 
page = vm_normal_page(vma, address, pte);
+   if ((flags & FOLL_LRU) && page && is_zone_device_page(page))
+   page = NULL;
if (!page && pte_devmap(pte) && (flags & (FOLL_GET | FOLL_PIN))) {
/*
 * Only return device mapping pages in the FOLL_GET or FOLL_PIN
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index c468fee595ff..dc572bc9fa1c 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2851,7 +2851,7 @@ static int split_huge_pages_pid(int pid, unsigned long 
vaddr_start,
}
 
/* FOLL_DUMP to ignore special (like zero) pages */
-   page = follow_page(vma, addr, FOLL_GET | FOLL_DUMP);
+   page = follow_page(vma, addr, FOLL_GET | FOLL_DUMP | FOLL_LRU);
 
if (IS_ERR(page))
continue;
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index a4e5eaf3eb01..eb3cfd679800 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -627,7 +627,7 @@ static int __collapse_huge_page_isolate(struct 
vm_area_struct *vma,
goto out;
}
page = vm_normal_page(vma, address, pteval);
-   if (unlikely(!page)) {
+   if (unlikely(!page) || unlikely(is_zone_device_page(page))) {
result = SCAN_PAGE_NULL;
goto out;
}
@@ -1276,7 +1276,7 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
writable = true;
 
page = vm_normal_page(vma, _address, pteval);
-   if (unlikely(!page)) {
+   if (unlikely(!page) || unlikely(is_zone_device_page(page))) {
result = SCAN_PAGE_NULL;
goto out_unmap;
}
@@ -1484,7 +1484,8 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, 
unsigned long addr)
goto abort;
 
page = vm_normal_page(vma, addr, *pte);
-
+   if (page && is_zone_device_page(page))
+   page = NULL;
/*
 * Note that uprobe, debugger, or MAP_PRIVATE may change the
 * page table, but the new page will not be a subpage of hpage.
@@ -1502,6 +1503,8 @@ void 

[PATCH v1 11/15] tools: update hmm-test to support device coherent type

2022-05-05 Thread Alex Sierra
Test cases such as migrate_fault and migrate_multiple, were modified to
explicit migrate from device to sys memory without the need of page
faults, when using device coherent type.

Snapshot test case updated to read memory device type first and based
on that, get the proper returned results migrate_ping_pong test case
added to test explicit migration from device to sys memory for both
private and coherent zone types.

Helpers to migrate from device to sys memory and vicerversa
were also added.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Popple 
Signed-off-by: Christoph Hellwig 
---
 tools/testing/selftests/vm/hmm-tests.c | 123 -
 1 file changed, 102 insertions(+), 21 deletions(-)

diff --git a/tools/testing/selftests/vm/hmm-tests.c 
b/tools/testing/selftests/vm/hmm-tests.c
index 203323967b50..84ec8c4a1dc7 100644
--- a/tools/testing/selftests/vm/hmm-tests.c
+++ b/tools/testing/selftests/vm/hmm-tests.c
@@ -44,6 +44,14 @@ struct hmm_buffer {
int fd;
uint64_tcpages;
uint64_tfaults;
+   int zone_device_type;
+};
+
+enum {
+   HMM_PRIVATE_DEVICE_ONE,
+   HMM_PRIVATE_DEVICE_TWO,
+   HMM_COHERENCE_DEVICE_ONE,
+   HMM_COHERENCE_DEVICE_TWO,
 };
 
 #define TWOMEG (1 << 21)
@@ -60,6 +68,21 @@ FIXTURE(hmm)
unsigned intpage_shift;
 };
 
+FIXTURE_VARIANT(hmm)
+{
+   int device_number;
+};
+
+FIXTURE_VARIANT_ADD(hmm, hmm_device_private)
+{
+   .device_number = HMM_PRIVATE_DEVICE_ONE,
+};
+
+FIXTURE_VARIANT_ADD(hmm, hmm_device_coherent)
+{
+   .device_number = HMM_COHERENCE_DEVICE_ONE,
+};
+
 FIXTURE(hmm2)
 {
int fd0;
@@ -68,6 +91,24 @@ FIXTURE(hmm2)
unsigned intpage_shift;
 };
 
+FIXTURE_VARIANT(hmm2)
+{
+   int device_number0;
+   int device_number1;
+};
+
+FIXTURE_VARIANT_ADD(hmm2, hmm2_device_private)
+{
+   .device_number0 = HMM_PRIVATE_DEVICE_ONE,
+   .device_number1 = HMM_PRIVATE_DEVICE_TWO,
+};
+
+FIXTURE_VARIANT_ADD(hmm2, hmm2_device_coherent)
+{
+   .device_number0 = HMM_COHERENCE_DEVICE_ONE,
+   .device_number1 = HMM_COHERENCE_DEVICE_TWO,
+};
+
 static int hmm_open(int unit)
 {
char pathname[HMM_PATH_MAX];
@@ -81,12 +122,19 @@ static int hmm_open(int unit)
return fd;
 }
 
+static bool hmm_is_coherent_type(int dev_num)
+{
+   return (dev_num >= HMM_COHERENCE_DEVICE_ONE);
+}
+
 FIXTURE_SETUP(hmm)
 {
self->page_size = sysconf(_SC_PAGE_SIZE);
self->page_shift = ffs(self->page_size) - 1;
 
-   self->fd = hmm_open(0);
+   self->fd = hmm_open(variant->device_number);
+   if (self->fd < 0 && hmm_is_coherent_type(variant->device_number))
+   SKIP(exit(0), "DEVICE_COHERENT not available");
ASSERT_GE(self->fd, 0);
 }
 
@@ -95,9 +143,11 @@ FIXTURE_SETUP(hmm2)
self->page_size = sysconf(_SC_PAGE_SIZE);
self->page_shift = ffs(self->page_size) - 1;
 
-   self->fd0 = hmm_open(0);
+   self->fd0 = hmm_open(variant->device_number0);
+   if (self->fd0 < 0 && hmm_is_coherent_type(variant->device_number0))
+   SKIP(exit(0), "DEVICE_COHERENT not available");
ASSERT_GE(self->fd0, 0);
-   self->fd1 = hmm_open(1);
+   self->fd1 = hmm_open(variant->device_number1);
ASSERT_GE(self->fd1, 0);
 }
 
@@ -144,6 +194,7 @@ static int hmm_dmirror_cmd(int fd,
}
buffer->cpages = cmd.cpages;
buffer->faults = cmd.faults;
+   buffer->zone_device_type = cmd.zone_device_type;
 
return 0;
 }
@@ -211,6 +262,20 @@ static void hmm_nanosleep(unsigned int n)
nanosleep(, NULL);
 }
 
+static int hmm_migrate_sys_to_dev(int fd,
+  struct hmm_buffer *buffer,
+  unsigned long npages)
+{
+   return hmm_dmirror_cmd(fd, HMM_DMIRROR_MIGRATE_TO_DEV, buffer, npages);
+}
+
+static int hmm_migrate_dev_to_sys(int fd,
+  struct hmm_buffer *buffer,
+  unsigned long npages)
+{
+   return hmm_dmirror_cmd(fd, HMM_DMIRROR_MIGRATE_TO_SYS, buffer, npages);
+}
+
 /*
  * Simple NULL test of device open/close.
  */
@@ -875,7 +940,7 @@ TEST_F(hmm, migrate)
ptr[i] = i;
 
/* Migrate memory to device. */
-   ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_MIGRATE, buffer, npages);
+   ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
ASSERT_EQ(ret, 0);
ASSERT_EQ(buffer->cpages, npages);
 
@@ -923,7 +988,7 @@ TEST_F(hmm, migrate_fault)
ptr[i] = i;
 
/* Migrate memory to device. */
-   ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_MIGRATE, buffer, npages);
+   ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
ASSERT_EQ(ret, 0);
ASSERT_EQ(buffer->cpages, npages);
 
@@ -936,7 +1001,7 @@ TEST_F(hmm, migrate_fault)
ASSERT_EQ(ptr[i], i);
 

[PATCH v1 12/15] tools: update test_hmm script to support SP config

2022-05-05 Thread Alex Sierra
Add two more parameters to set spm_addr_dev0 & spm_addr_dev1
addresses. These two parameters configure the start SP
addresses for each device in test_hmm driver.
Consequently, this configures zone device type as coherent.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Popple 
Signed-off-by: Christoph Hellwig 
---
 tools/testing/selftests/vm/test_hmm.sh | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/vm/test_hmm.sh 
b/tools/testing/selftests/vm/test_hmm.sh
index 0647b525a625..539c9371e592 100755
--- a/tools/testing/selftests/vm/test_hmm.sh
+++ b/tools/testing/selftests/vm/test_hmm.sh
@@ -40,11 +40,26 @@ check_test_requirements()
 
 load_driver()
 {
-   modprobe $DRIVER > /dev/null 2>&1
+   if [ $# -eq 0 ]; then
+   modprobe $DRIVER > /dev/null 2>&1
+   else
+   if [ $# -eq 2 ]; then
+   modprobe $DRIVER spm_addr_dev0=$1 spm_addr_dev1=$2
+   > /dev/null 2>&1
+   else
+   echo "Missing module parameters. Make sure pass"\
+   "spm_addr_dev0 and spm_addr_dev1"
+   usage
+   fi
+   fi
if [ $? == 0 ]; then
major=$(awk "\$2==\"HMM_DMIRROR\" {print \$1}" /proc/devices)
mknod /dev/hmm_dmirror0 c $major 0
mknod /dev/hmm_dmirror1 c $major 1
+   if [ $# -eq 2 ]; then
+   mknod /dev/hmm_dmirror2 c $major 2
+   mknod /dev/hmm_dmirror3 c $major 3
+   fi
fi
 }
 
@@ -58,7 +73,7 @@ run_smoke()
 {
echo "Running smoke test. Note, this test provides basic coverage."
 
-   load_driver
+   load_driver $1 $2
$(dirname "${BASH_SOURCE[0]}")/hmm-tests
unload_driver
 }
@@ -75,6 +90,9 @@ usage()
echo "# Smoke testing"
echo "./${TEST_NAME}.sh smoke"
echo
+   echo "# Smoke testing with SPM enabled"
+   echo "./${TEST_NAME}.sh smoke  "
+   echo
exit 0
 }
 
@@ -84,7 +102,7 @@ function run_test()
usage
else
if [ "$1" = "smoke" ]; then
-   run_smoke
+   run_smoke $2 $3
else
usage
fi
-- 
2.32.0



[PATCH v1 15/15] tools: add selftests to hmm for COW in device memory

2022-05-05 Thread Alex Sierra
The objective is to test device migration mechanism in pages marked
as COW, for private and coherent device type. In case of writing to
COW private page(s), a page fault will migrate pages back to system
memory first. Then, these pages will be duplicated. In case of COW
device coherent type, pages are duplicated directly from device
memory.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
---
 tools/testing/selftests/vm/hmm-tests.c | 80 ++
 1 file changed, 80 insertions(+)

diff --git a/tools/testing/selftests/vm/hmm-tests.c 
b/tools/testing/selftests/vm/hmm-tests.c
index 65e30ab6494c..d70b780df877 100644
--- a/tools/testing/selftests/vm/hmm-tests.c
+++ b/tools/testing/selftests/vm/hmm-tests.c
@@ -1870,4 +1870,84 @@ TEST_F(hmm, hmm_gup_test)
close(gup_fd);
hmm_buffer_free(buffer);
 }
+
+/*
+ * Test copy-on-write in device pages.
+ * In case of writing to COW private page(s), a page fault will migrate pages
+ * back to system memory first. Then, these pages will be duplicated. In case
+ * of COW device coherent type, pages are duplicated directly from device
+ * memory.
+ */
+TEST_F(hmm, hmm_cow_in_device)
+{
+   struct hmm_buffer *buffer;
+   unsigned long npages;
+   unsigned long size;
+   unsigned long i;
+   int *ptr;
+   int ret;
+   unsigned char *m;
+   pid_t pid;
+   int status;
+
+   npages = 4;
+   size = npages << self->page_shift;
+
+   buffer = malloc(sizeof(*buffer));
+   ASSERT_NE(buffer, NULL);
+
+   buffer->fd = -1;
+   buffer->size = size;
+   buffer->mirror = malloc(size);
+   ASSERT_NE(buffer->mirror, NULL);
+
+   buffer->ptr = mmap(NULL, size,
+  PROT_READ | PROT_WRITE,
+  MAP_PRIVATE | MAP_ANONYMOUS,
+  buffer->fd, 0);
+   ASSERT_NE(buffer->ptr, MAP_FAILED);
+
+   /* Initialize buffer in system memory. */
+   for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
+   ptr[i] = i;
+
+   /* Migrate memory to device. */
+
+   ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
+   ASSERT_EQ(ret, 0);
+   ASSERT_EQ(buffer->cpages, npages);
+
+   pid = fork();
+   if (pid == -1)
+   ASSERT_EQ(pid, 0);
+   if (!pid) {
+   /* Child process waitd for SIGTERM from the parent. */
+   while (1) {
+   }
+   perror("Should not reach this\n");
+   exit(0);
+   }
+   /* Parent process writes to COW pages(s) and gets a
+* new copy in system. In case of device private pages,
+* this write causes a migration to system mem first.
+*/
+   for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
+   ptr[i] = i;
+
+   /* Terminate child and wait */
+   EXPECT_EQ(0, kill(pid, SIGTERM));
+   EXPECT_EQ(pid, waitpid(pid, , 0));
+   EXPECT_NE(0, WIFSIGNALED(status));
+   EXPECT_EQ(SIGTERM, WTERMSIG(status));
+
+   /* Take snapshot to CPU pagetables */
+   ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
+   ASSERT_EQ(ret, 0);
+   ASSERT_EQ(buffer->cpages, npages);
+   m = buffer->mirror;
+   for (i = 0; i < npages; i++)
+   ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[i]);
+
+   hmm_buffer_free(buffer);
+}
 TEST_HARNESS_MAIN
-- 
2.32.0



[PATCH v1 09/15] lib: test_hmm add module param for zone device type

2022-05-05 Thread Alex Sierra
In order to configure device coherent in test_hmm, two module parameters
should be passed, which correspond to the SP start address of each
device (2) spm_addr_dev0 & spm_addr_dev1. If no parameters are passed,
private device type is configured.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Poppple 
Signed-off-by: Christoph Hellwig 
---
 lib/test_hmm.c  | 73 -
 lib/test_hmm_uapi.h |  1 +
 2 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/lib/test_hmm.c b/lib/test_hmm.c
index 7a27584484ce..15747f70c5bc 100644
--- a/lib/test_hmm.c
+++ b/lib/test_hmm.c
@@ -37,6 +37,16 @@
 #define DEVMEM_CHUNK_SIZE  (256 * 1024 * 1024U)
 #define DEVMEM_CHUNKS_RESERVE  16
 
+static unsigned long spm_addr_dev0;
+module_param(spm_addr_dev0, long, 0644);
+MODULE_PARM_DESC(spm_addr_dev0,
+   "Specify start address for SPM (special purpose memory) used 
for device 0. By setting this Coherent device type will be used. Make sure 
spm_addr_dev1 is set too. Minimum SPM size should be DEVMEM_CHUNK_SIZE.");
+
+static unsigned long spm_addr_dev1;
+module_param(spm_addr_dev1, long, 0644);
+MODULE_PARM_DESC(spm_addr_dev1,
+   "Specify start address for SPM (special purpose memory) used 
for device 1. By setting this Coherent device type will be used. Make sure 
spm_addr_dev0 is set too. Minimum SPM size should be DEVMEM_CHUNK_SIZE.");
+
 static const struct dev_pagemap_ops dmirror_devmem_ops;
 static const struct mmu_interval_notifier_ops dmirror_min_ops;
 static dev_t dmirror_dev;
@@ -455,28 +465,44 @@ static int dmirror_write(struct dmirror *dmirror, struct 
hmm_dmirror_cmd *cmd)
return ret;
 }
 
-static bool dmirror_allocate_chunk(struct dmirror_device *mdevice,
+static int dmirror_allocate_chunk(struct dmirror_device *mdevice,
   struct page **ppage)
 {
struct dmirror_chunk *devmem;
-   struct resource *res;
+   struct resource *res = NULL;
unsigned long pfn;
unsigned long pfn_first;
unsigned long pfn_last;
void *ptr;
+   int ret = -ENOMEM;
 
devmem = kzalloc(sizeof(*devmem), GFP_KERNEL);
if (!devmem)
-   return false;
+   return ret;
 
-   res = request_free_mem_region(_resource, DEVMEM_CHUNK_SIZE,
- "hmm_dmirror");
-   if (IS_ERR(res))
+   switch (mdevice->zone_device_type) {
+   case HMM_DMIRROR_MEMORY_DEVICE_PRIVATE:
+   res = request_free_mem_region(_resource, 
DEVMEM_CHUNK_SIZE,
+ "hmm_dmirror");
+   if (IS_ERR_OR_NULL(res))
+   goto err_devmem;
+   devmem->pagemap.range.start = res->start;
+   devmem->pagemap.range.end = res->end;
+   devmem->pagemap.type = MEMORY_DEVICE_PRIVATE;
+   break;
+   case HMM_DMIRROR_MEMORY_DEVICE_COHERENT:
+   devmem->pagemap.range.start = (MINOR(mdevice->cdevice.dev) - 2) 
?
+   spm_addr_dev0 :
+   spm_addr_dev1;
+   devmem->pagemap.range.end = devmem->pagemap.range.start +
+   DEVMEM_CHUNK_SIZE - 1;
+   devmem->pagemap.type = MEMORY_DEVICE_COHERENT;
+   break;
+   default:
+   ret = -EINVAL;
goto err_devmem;
+   }
 
-   devmem->pagemap.type = MEMORY_DEVICE_PRIVATE;
-   devmem->pagemap.range.start = res->start;
-   devmem->pagemap.range.end = res->end;
devmem->pagemap.nr_range = 1;
devmem->pagemap.ops = _devmem_ops;
devmem->pagemap.owner = mdevice;
@@ -497,10 +523,14 @@ static bool dmirror_allocate_chunk(struct dmirror_device 
*mdevice,
mdevice->devmem_capacity = new_capacity;
mdevice->devmem_chunks = new_chunks;
}
-
ptr = memremap_pages(>pagemap, numa_node_id());
-   if (IS_ERR(ptr))
+   if (IS_ERR_OR_NULL(ptr)) {
+   if (ptr)
+   ret = PTR_ERR(ptr);
+   else
+   ret = -EFAULT;
goto err_release;
+   }
 
devmem->mdevice = mdevice;
pfn_first = devmem->pagemap.range.start >> PAGE_SHIFT;
@@ -529,15 +559,17 @@ static bool dmirror_allocate_chunk(struct dmirror_device 
*mdevice,
}
spin_unlock(>lock);
 
-   return true;
+   return 0;
 
 err_release:
mutex_unlock(>devmem_lock);
-   release_mem_region(devmem->pagemap.range.start, 
range_len(>pagemap.range));
+   if (res && devmem->pagemap.type == MEMORY_DEVICE_PRIVATE)
+   release_mem_region(devmem->pagemap.range.start,
+  range_len(>pagemap.range));
 err_devmem:
kfree(devmem);
 
-   return false;
+  

[PATCH v1 10/15] lib: add support for device coherent type in test_hmm

2022-05-05 Thread Alex Sierra
Device Coherent type uses device memory that is coherently accesible by
the CPU. This could be shown as SP (special purpose) memory range
at the BIOS-e820 memory enumeration. If no SP memory is supported in
system, this could be faked by setting CONFIG_EFI_FAKE_MEMMAP.

Currently, test_hmm only supports two different SP ranges of at least
256MB size. This could be specified in the kernel parameter variable
efi_fake_mem. Ex. Two SP ranges of 1GB starting at 0x1 &
0x14000 physical address. Ex.
efi_fake_mem=1G@0x1:0x4,1G@0x14000:0x4

Private and coherent device mirror instances can be created in the same
probed. This is done by passing the module parameters spm_addr_dev0 &
spm_addr_dev1. In this case, it will create four instances of
device_mirror. The first two correspond to private device type, the
last two to coherent type. Then, they can be easily accessed from user
space through /dev/hmm_mirror. Usually num_device 0 and 1
are for private, and 2 and 3 for coherent types. If no module
parameters are passed, two instances of private type device_mirror will
be created only.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Poppple 
---
 lib/test_hmm.c  | 253 +---
 lib/test_hmm_uapi.h |  15 ++-
 2 files changed, 202 insertions(+), 66 deletions(-)

diff --git a/lib/test_hmm.c b/lib/test_hmm.c
index 15747f70c5bc..361a026c5d21 100644
--- a/lib/test_hmm.c
+++ b/lib/test_hmm.c
@@ -32,11 +32,22 @@
 
 #include "test_hmm_uapi.h"
 
-#define DMIRROR_NDEVICES   2
+#define DMIRROR_NDEVICES   4
 #define DMIRROR_RANGE_FAULT_TIMEOUT1000
 #define DEVMEM_CHUNK_SIZE  (256 * 1024 * 1024U)
 #define DEVMEM_CHUNKS_RESERVE  16
 
+/*
+ * For device_private pages, dpage is just a dummy struct page
+ * representing a piece of device memory. dmirror_devmem_alloc_page
+ * allocates a real system memory page as backing storage to fake a
+ * real device. zone_device_data points to that backing page. But
+ * for device_coherent memory, the struct page represents real
+ * physical CPU-accessible memory that we can use directly.
+ */
+#define BACKING_PAGE(page) (is_device_private_page((page)) ? \
+  (page)->zone_device_data : (page))
+
 static unsigned long spm_addr_dev0;
 module_param(spm_addr_dev0, long, 0644);
 MODULE_PARM_DESC(spm_addr_dev0,
@@ -125,6 +136,21 @@ static int dmirror_bounce_init(struct dmirror_bounce 
*bounce,
return 0;
 }
 
+static bool dmirror_is_private_zone(struct dmirror_device *mdevice)
+{
+   return (mdevice->zone_device_type ==
+   HMM_DMIRROR_MEMORY_DEVICE_PRIVATE) ? true : false;
+}
+
+static enum migrate_vma_direction
+dmirror_select_device(struct dmirror *dmirror)
+{
+   return (dmirror->mdevice->zone_device_type ==
+   HMM_DMIRROR_MEMORY_DEVICE_PRIVATE) ?
+   MIGRATE_VMA_SELECT_DEVICE_PRIVATE :
+   MIGRATE_VMA_SELECT_DEVICE_COHERENT;
+}
+
 static void dmirror_bounce_fini(struct dmirror_bounce *bounce)
 {
vfree(bounce->ptr);
@@ -575,16 +601,19 @@ static int dmirror_allocate_chunk(struct dmirror_device 
*mdevice,
 static struct page *dmirror_devmem_alloc_page(struct dmirror_device *mdevice)
 {
struct page *dpage = NULL;
-   struct page *rpage;
+   struct page *rpage = NULL;
 
/*
-* This is a fake device so we alloc real system memory to store
-* our device memory.
+* For ZONE_DEVICE private type, this is a fake device so we allocate
+* real system memory to store our device memory.
+* For ZONE_DEVICE coherent type we use the actual dpage to store the
+* data and ignore rpage.
 */
-   rpage = alloc_page(GFP_HIGHUSER);
-   if (!rpage)
-   return NULL;
-
+   if (dmirror_is_private_zone(mdevice)) {
+   rpage = alloc_page(GFP_HIGHUSER);
+   if (!rpage)
+   return NULL;
+   }
spin_lock(>lock);
 
if (mdevice->free_pages) {
@@ -603,7 +632,8 @@ static struct page *dmirror_devmem_alloc_page(struct 
dmirror_device *mdevice)
return dpage;
 
 error:
-   __free_page(rpage);
+   if (rpage)
+   __free_page(rpage);
return NULL;
 }
 
@@ -629,12 +659,16 @@ static void dmirror_migrate_alloc_and_copy(struct 
migrate_vma *args,
 * unallocated pte_none() or read-only zero page.
 */
spage = migrate_pfn_to_page(*src);
+   if (WARN(spage && is_zone_device_page(spage),
+"page already in device spage pfn: 0x%lx\n",
+page_to_pfn(spage)))
+   continue;
 
dpage = dmirror_devmem_alloc_page(mdevice);
if (!dpage)
continue;
 
-   rpage = dpage->zone_device_data;
+   rpage = BACKING_PAGE(dpage);
  

[PATCH v1 07/15] drm/amdkfd: coherent type as sys mem on migration to ram

2022-05-05 Thread Alex Sierra
Coherent device type memory on VRAM to RAM migration, has similar access
as System RAM from the CPU. This flag sets the source from the sender.
Which in Coherent type case, should be set as
MIGRATE_VMA_SELECT_DEVICE_COHERENT.

Signed-off-by: Alex Sierra 
Reviewed-by: Felix Kuehling 
Signed-off-by: Christoph Hellwig 
---
 drivers/gpu/drm/amd/amdkfd/kfd_migrate.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
index 52bd3fa6a582..25c9f7a4325d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
@@ -673,9 +673,12 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct 
svm_range *prange,
migrate.vma = vma;
migrate.start = start;
migrate.end = end;
-   migrate.flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE;
migrate.pgmap_owner = SVM_ADEV_PGMAP_OWNER(adev);
 
+   if (adev->gmc.xgmi.connected_to_cpu)
+   migrate.flags = MIGRATE_VMA_SELECT_DEVICE_COHERENT;
+   else
+   migrate.flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE;
size = 2 * sizeof(*migrate.src) + sizeof(uint64_t) + sizeof(dma_addr_t);
size *= npages;
buf = kvmalloc(size, GFP_KERNEL | __GFP_ZERO);
-- 
2.32.0



[PATCH v1 08/15] lib: test_hmm add ioctl to get zone device type

2022-05-05 Thread Alex Sierra
new ioctl cmd added to query zone device type. This will be
used once the test_hmm adds zone device coherent type.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Poppple 
Signed-off-by: Christoph Hellwig 
---
 lib/test_hmm.c  | 23 +--
 lib/test_hmm_uapi.h |  8 
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/lib/test_hmm.c b/lib/test_hmm.c
index cfe632047839..7a27584484ce 100644
--- a/lib/test_hmm.c
+++ b/lib/test_hmm.c
@@ -87,6 +87,7 @@ struct dmirror_chunk {
 struct dmirror_device {
struct cdev cdevice;
struct hmm_devmem   *devmem;
+   unsigned intzone_device_type;
 
unsigned intdevmem_capacity;
unsigned intdevmem_count;
@@ -1026,6 +1027,15 @@ static int dmirror_snapshot(struct dmirror *dmirror,
return ret;
 }
 
+static int dmirror_get_device_type(struct dmirror *dmirror,
+   struct hmm_dmirror_cmd *cmd)
+{
+   mutex_lock(>mutex);
+   cmd->zone_device_type = dmirror->mdevice->zone_device_type;
+   mutex_unlock(>mutex);
+
+   return 0;
+}
 static long dmirror_fops_unlocked_ioctl(struct file *filp,
unsigned int command,
unsigned long arg)
@@ -1076,6 +1086,9 @@ static long dmirror_fops_unlocked_ioctl(struct file *filp,
ret = dmirror_snapshot(dmirror, );
break;
 
+   case HMM_DMIRROR_GET_MEM_DEV_TYPE:
+   ret = dmirror_get_device_type(dmirror, );
+   break;
default:
return -EINVAL;
}
@@ -1260,14 +1273,20 @@ static void dmirror_device_remove(struct dmirror_device 
*mdevice)
 static int __init hmm_dmirror_init(void)
 {
int ret;
-   int id;
+   int id = 0;
+   int ndevices = 0;
 
ret = alloc_chrdev_region(_dev, 0, DMIRROR_NDEVICES,
  "HMM_DMIRROR");
if (ret)
goto err_unreg;
 
-   for (id = 0; id < DMIRROR_NDEVICES; id++) {
+   memset(dmirror_devices, 0, DMIRROR_NDEVICES * 
sizeof(dmirror_devices[0]));
+   dmirror_devices[ndevices++].zone_device_type =
+   HMM_DMIRROR_MEMORY_DEVICE_PRIVATE;
+   dmirror_devices[ndevices++].zone_device_type =
+   HMM_DMIRROR_MEMORY_DEVICE_PRIVATE;
+   for (id = 0; id < ndevices; id++) {
ret = dmirror_device_init(dmirror_devices + id, id);
if (ret)
goto err_chrdev;
diff --git a/lib/test_hmm_uapi.h b/lib/test_hmm_uapi.h
index f14dea5dcd06..17f842f1aa02 100644
--- a/lib/test_hmm_uapi.h
+++ b/lib/test_hmm_uapi.h
@@ -19,6 +19,7 @@
  * @npages: (in) number of pages to read/write
  * @cpages: (out) number of pages copied
  * @faults: (out) number of device page faults seen
+ * @zone_device_type: (out) zone device memory type
  */
 struct hmm_dmirror_cmd {
__u64   addr;
@@ -26,6 +27,7 @@ struct hmm_dmirror_cmd {
__u64   npages;
__u64   cpages;
__u64   faults;
+   __u64   zone_device_type;
 };
 
 /* Expose the address space of the calling process through hmm device file */
@@ -35,6 +37,7 @@ struct hmm_dmirror_cmd {
 #define HMM_DMIRROR_SNAPSHOT   _IOWR('H', 0x03, struct hmm_dmirror_cmd)
 #define HMM_DMIRROR_EXCLUSIVE  _IOWR('H', 0x04, struct hmm_dmirror_cmd)
 #define HMM_DMIRROR_CHECK_EXCLUSIVE_IOWR('H', 0x05, struct hmm_dmirror_cmd)
+#define HMM_DMIRROR_GET_MEM_DEV_TYPE   _IOWR('H', 0x06, struct hmm_dmirror_cmd)
 
 /*
  * Values returned in hmm_dmirror_cmd.ptr for HMM_DMIRROR_SNAPSHOT.
@@ -62,4 +65,9 @@ enum {
HMM_DMIRROR_PROT_DEV_PRIVATE_REMOTE = 0x30,
 };
 
+enum {
+   /* 0 is reserved to catch uninitialized type fields */
+   HMM_DMIRROR_MEMORY_DEVICE_PRIVATE = 1,
+};
+
 #endif /* _LIB_TEST_HMM_UAPI_H */
-- 
2.32.0



[PATCH v1 04/15] mm: add device coherent checker to remove migration pte

2022-05-05 Thread Alex Sierra
During remove_migration_pte(), entries for device coherent type pages
that were not created through special migration ptes, ignore _PAGE_RW
flag. This path can be found at migrate_device_page(), where valid
vma is not required. In this case, migrate_vma_collect_pmd() is not
called and special migration ptes are not set.

Signed-off-by: Alex Sierra 
---
 mm/migrate.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mm/migrate.c b/mm/migrate.c
index 6c31ee1e1c9b..e18ddee56f37 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -206,7 +206,8 @@ static bool remove_migration_pte(struct folio *folio,
 * Recheck VMA as permissions can change since migration started
 */
entry = pte_to_swp_entry(*pvmw.pte);
-   if (is_writable_migration_entry(entry))
+   if (is_writable_migration_entry(entry) ||
+   is_device_coherent_page(pfn_to_page(pvmw.pfn)))
pte = maybe_mkwrite(pte, vma);
else if (pte_swp_uffd_wp(*pvmw.pte))
pte = pte_mkuffd_wp(pte);
-- 
2.32.0



[PATCH v1 06/15] drm/amdkfd: add SPM support for SVM

2022-05-05 Thread Alex Sierra
When CPU is connected throug XGMI, it has coherent
access to VRAM resource. In this case that resource
is taken from a table in the device gmc aperture base.
This resource is used along with the device type, which could
be DEVICE_PRIVATE or DEVICE_COHERENT to create the device
page map region.

Signed-off-by: Alex Sierra 
Reviewed-by: Felix Kuehling 
Signed-off-by: Christoph Hellwig 
---
 drivers/gpu/drm/amd/amdkfd/kfd_migrate.c | 28 ++--
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
index 7e3a7fcb9fe6..52bd3fa6a582 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
@@ -948,7 +948,7 @@ int svm_migrate_init(struct amdgpu_device *adev)
 {
struct kfd_dev *kfddev = adev->kfd.dev;
struct dev_pagemap *pgmap;
-   struct resource *res;
+   struct resource *res = NULL;
unsigned long size;
void *r;
 
@@ -963,28 +963,34 @@ int svm_migrate_init(struct amdgpu_device *adev)
 * should remove reserved size
 */
size = ALIGN(adev->gmc.real_vram_size, 2ULL << 20);
-   res = devm_request_free_mem_region(adev->dev, _resource, size);
-   if (IS_ERR(res))
-   return -ENOMEM;
+   if (adev->gmc.xgmi.connected_to_cpu) {
+   pgmap->range.start = adev->gmc.aper_base;
+   pgmap->range.end = adev->gmc.aper_base + adev->gmc.aper_size - 
1;
+   pgmap->type = MEMORY_DEVICE_COHERENT;
+   } else {
+   res = devm_request_free_mem_region(adev->dev, _resource, 
size);
+   if (IS_ERR(res))
+   return -ENOMEM;
+   pgmap->range.start = res->start;
+   pgmap->range.end = res->end;
+   pgmap->type = MEMORY_DEVICE_PRIVATE;
+   }
 
-   pgmap->type = MEMORY_DEVICE_PRIVATE;
pgmap->nr_range = 1;
-   pgmap->range.start = res->start;
-   pgmap->range.end = res->end;
pgmap->ops = _migrate_pgmap_ops;
pgmap->owner = SVM_ADEV_PGMAP_OWNER(adev);
-   pgmap->flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE;
-
+   pgmap->flags = 0;
/* Device manager releases device-specific resources, memory region and
 * pgmap when driver disconnects from device.
 */
r = devm_memremap_pages(adev->dev, pgmap);
if (IS_ERR(r)) {
pr_err("failed to register HMM device memory\n");
-
/* Disable SVM support capability */
pgmap->type = 0;
-   devm_release_mem_region(adev->dev, res->start, 
resource_size(res));
+   if (pgmap->type == MEMORY_DEVICE_PRIVATE)
+   devm_release_mem_region(adev->dev, res->start,
+   res->end - res->start + 1);
return PTR_ERR(r);
}
 
-- 
2.32.0



[PATCH v1 05/15] mm/gup: migrate device coherent pages when pinning instead of failing

2022-05-05 Thread Alex Sierra
From: Alistair Popple 

Currently any attempts to pin a device coherent page will fail. This is
because device coherent pages need to be managed by a device driver, and
pinning them would prevent a driver from migrating them off the device.

However this is no reason to fail pinning of these pages. These are
coherent and accessible from the CPU so can be migrated just like
pinning ZONE_MOVABLE pages. So instead of failing all attempts to pin
them first try migrating them out of ZONE_DEVICE.

Signed-off-by: Alistair Popple 
Acked-by: Felix Kuehling 
[hch: rebased to the split device memory checks,
  moved migrate_device_page to migrate_device.c]
Signed-off-by: Christoph Hellwig 
---
 mm/gup.c| 47 +++-
 mm/internal.h   |  1 +
 mm/migrate_device.c | 53 +
 3 files changed, 96 insertions(+), 5 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index f598a037eb04..a214c8df7140 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1786,9 +1786,43 @@ static long check_and_migrate_movable_pages(unsigned 
long nr_pages,
continue;
prev_folio = folio;
 
-   if (folio_is_pinnable(folio))
+   /*
+* Device private pages will get faulted in during gup so it
+* shouldn't be possible to see one here.
+*/
+   if (WARN_ON_ONCE(folio_is_device_private(folio))) {
+   ret = -EFAULT;
+   goto unpin_pages;
+   }
+
+   /*
+* Device coherent pages are managed by a driver and should not
+* be pinned indefinitely as it prevents the driver moving the
+* page. So when trying to pin with FOLL_LONGTERM instead try
+* to migrate the page out of device memory.
+*/
+   if (folio_is_device_coherent(folio)) {
+   WARN_ON_ONCE(PageCompound(>page));
+
+   /*
+* Migration will fail if the page is pinned, so convert
+* the pin on the source page to a normal reference.
+*/
+   if (gup_flags & FOLL_PIN) {
+   get_page(>page);
+   unpin_user_page(>page);
+   }
+
+   pages[i] = migrate_device_page(>page, gup_flags);
+   if (!pages[i]) {
+   ret = -EBUSY;
+   goto unpin_pages;
+   }
continue;
+   }
 
+   if (folio_is_pinnable(folio))
+   continue;
/*
 * Try to move out any movable page before pinning the range.
 */
@@ -1824,10 +1858,13 @@ static long check_and_migrate_movable_pages(unsigned 
long nr_pages,
return nr_pages;
 
 unpin_pages:
-   if (gup_flags & FOLL_PIN) {
-   unpin_user_pages(pages, nr_pages);
-   } else {
-   for (i = 0; i < nr_pages; i++)
+   for (i = 0; i < nr_pages; i++) {
+   if (!pages[i])
+   continue;
+
+   if (gup_flags & FOLL_PIN)
+   unpin_user_page(pages[i]);
+   else
put_page(pages[i]);
}
 
diff --git a/mm/internal.h b/mm/internal.h
index cf16280ce132..32c621416966 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -750,6 +750,7 @@ int numa_migrate_prep(struct page *page, struct 
vm_area_struct *vma,
  unsigned long addr, int page_nid, int *flags);
 
 void free_zone_device_page(struct page *page);
+struct page *migrate_device_page(struct page *page, unsigned int gup_flags);
 
 /*
  * mm/gup.c
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index b399c498f0aa..1e74aa7ab580 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -775,3 +775,56 @@ void migrate_vma_finalize(struct migrate_vma *migrate)
}
 }
 EXPORT_SYMBOL(migrate_vma_finalize);
+
+/*
+ * Migrate a device coherent page back to normal memory.  The caller should 
have
+ * a reference on page which will be copied to the new page if migration is
+ * successful or dropped on failure.
+ */
+struct page *migrate_device_page(struct page *page, unsigned int gup_flags)
+{
+   unsigned long src_pfn, dst_pfn = 0;
+   struct migrate_vma args;
+   struct page *dpage;
+
+   lock_page(page);
+   src_pfn = migrate_pfn(page_to_pfn(page)) | MIGRATE_PFN_MIGRATE;
+   args.src = _pfn;
+   args.dst = _pfn;
+   args.cpages = 1;
+   args.npages = 1;
+   args.vma = NULL;
+   migrate_vma_setup();
+   if (!(src_pfn & MIGRATE_PFN_MIGRATE))
+   return NULL;
+
+   dpage = alloc_pages(GFP_USER | __GFP_NOWARN, 0);
+
+   /*
+* get/pin the new 

[PATCH v1 03/15] mm: remove the vma check in migrate_vma_setup()

2022-05-05 Thread Alex Sierra
From: Alistair Popple 

migrate_vma_setup() checks that a valid vma is passed so that the page
tables can be walked to find the pfns associated with a given address
range. However in some cases the pfns are already known, such as when
migrating device coherent pages during pin_user_pages() meaning a valid
vma isn't required.

Signed-off-by: Alistair Popple 
Acked-by: Felix Kuehling 
Signed-off-by: Christoph Hellwig 
---
 mm/migrate_device.c | 34 +-
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index a0b997935cf9..b399c498f0aa 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -467,24 +467,24 @@ int migrate_vma_setup(struct migrate_vma *args)
 
args->start &= PAGE_MASK;
args->end &= PAGE_MASK;
-   if (!args->vma || is_vm_hugetlb_page(args->vma) ||
-   (args->vma->vm_flags & VM_SPECIAL) || vma_is_dax(args->vma))
-   return -EINVAL;
-   if (nr_pages <= 0)
-   return -EINVAL;
-   if (args->start < args->vma->vm_start ||
-   args->start >= args->vma->vm_end)
-   return -EINVAL;
-   if (args->end <= args->vma->vm_start || args->end > args->vma->vm_end)
-   return -EINVAL;
if (!args->src || !args->dst)
return -EINVAL;
-
-   memset(args->src, 0, sizeof(*args->src) * nr_pages);
-   args->cpages = 0;
-   args->npages = 0;
-
-   migrate_vma_collect(args);
+   if (args->vma) {
+   if (is_vm_hugetlb_page(args->vma) ||
+   (args->vma->vm_flags & VM_SPECIAL) || vma_is_dax(args->vma))
+   return -EINVAL;
+   if (args->start < args->vma->vm_start ||
+   args->start >= args->vma->vm_end)
+   return -EINVAL;
+   if (args->end <= args->vma->vm_start ||
+   args->end > args->vma->vm_end)
+   return -EINVAL;
+   memset(args->src, 0, sizeof(*args->src) * nr_pages);
+   args->cpages = 0;
+   args->npages = 0;
+
+   migrate_vma_collect(args);
+   }
 
if (args->cpages)
migrate_vma_unmap(args);
@@ -666,7 +666,7 @@ void migrate_vma_pages(struct migrate_vma *migrate)
continue;
}
 
-   if (!page) {
+   if (!page && migrate->vma) {
if (!(migrate->src[i] & MIGRATE_PFN_MIGRATE))
continue;
if (!notified) {
-- 
2.32.0



[PATCH v1 02/15] mm: add device coherent vma selection for memory migration

2022-05-05 Thread Alex Sierra
This case is used to migrate pages from device memory, back to system
memory. Device coherent type memory is cache coherent from device and CPU
point of view.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Poppple 
Signed-off-by: Christoph Hellwig 
---
 include/linux/migrate.h |  1 +
 mm/migrate_device.c | 12 +---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 90e75d5a54d6..a4a336fd81fc 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -138,6 +138,7 @@ static inline unsigned long migrate_pfn(unsigned long pfn)
 enum migrate_vma_direction {
MIGRATE_VMA_SELECT_SYSTEM = 1 << 0,
MIGRATE_VMA_SELECT_DEVICE_PRIVATE = 1 << 1,
+   MIGRATE_VMA_SELECT_DEVICE_COHERENT = 1 << 2,
 };
 
 struct migrate_vma {
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index 7e267142ea34..a0b997935cf9 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -148,15 +148,21 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
if (is_writable_device_private_entry(entry))
mpfn |= MIGRATE_PFN_WRITE;
} else {
-   if (!(migrate->flags & MIGRATE_VMA_SELECT_SYSTEM))
-   goto next;
pfn = pte_pfn(pte);
-   if (is_zero_pfn(pfn)) {
+   if (is_zero_pfn(pfn) &&
+   (migrate->flags & MIGRATE_VMA_SELECT_SYSTEM)) {
mpfn = MIGRATE_PFN_MIGRATE;
migrate->cpages++;
goto next;
}
page = vm_normal_page(migrate->vma, addr, pte);
+   if (page && !is_zone_device_page(page) &&
+   !(migrate->flags & MIGRATE_VMA_SELECT_SYSTEM))
+   goto next;
+   else if (page && is_device_coherent_page(page) &&
+   (!(migrate->flags & 
MIGRATE_VMA_SELECT_DEVICE_COHERENT) ||
+page->pgmap->owner != migrate->pgmap_owner))
+   goto next;
mpfn = migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE;
mpfn |= pte_write(pte) ? MIGRATE_PFN_WRITE : 0;
}
-- 
2.32.0



[PATCH v1 01/15] mm: add zone device coherent type memory support

2022-05-05 Thread Alex Sierra
Device memory that is cache coherent from device and CPU point of view.
This is used on platforms that have an advanced system bus (like CAPI
or CXL). Any page of a process can be migrated to such memory. However,
no one should be allowed to pin such memory so that it can always be
evicted.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Popple 
[hch: rebased ontop of the refcount changes,
  removed is_dev_private_or_coherent_page]
Signed-off-by: Christoph Hellwig 
---
 include/linux/memremap.h | 19 +++
 mm/memcontrol.c  |  7 ---
 mm/memory-failure.c  |  8 ++--
 mm/memremap.c| 10 ++
 mm/migrate_device.c  | 16 +++-
 mm/rmap.c|  3 ++-
 6 files changed, 48 insertions(+), 15 deletions(-)

diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 8af304f6b504..9f752ebed613 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -41,6 +41,13 @@ struct vmem_altmap {
  * A more complete discussion of unaddressable memory may be found in
  * include/linux/hmm.h and Documentation/vm/hmm.rst.
  *
+ * MEMORY_DEVICE_COHERENT:
+ * Device memory that is cache coherent from device and CPU point of view. This
+ * is used on platforms that have an advanced system bus (like CAPI or CXL). A
+ * driver can hotplug the device memory using ZONE_DEVICE and with that memory
+ * type. Any page of a process can be migrated to such memory. However no one
+ * should be allowed to pin such memory so that it can always be evicted.
+ *
  * MEMORY_DEVICE_FS_DAX:
  * Host memory that has similar access semantics as System RAM i.e. DMA
  * coherent and supports page pinning. In support of coordinating page
@@ -61,6 +68,7 @@ struct vmem_altmap {
 enum memory_type {
/* 0 is reserved to catch uninitialized type fields */
MEMORY_DEVICE_PRIVATE = 1,
+   MEMORY_DEVICE_COHERENT,
MEMORY_DEVICE_FS_DAX,
MEMORY_DEVICE_GENERIC,
MEMORY_DEVICE_PCI_P2PDMA,
@@ -143,6 +151,17 @@ static inline bool folio_is_device_private(const struct 
folio *folio)
return is_device_private_page(>page);
 }
 
+static inline bool is_device_coherent_page(const struct page *page)
+{
+   return is_zone_device_page(page) &&
+   page->pgmap->type == MEMORY_DEVICE_COHERENT;
+}
+
+static inline bool folio_is_device_coherent(const struct folio *folio)
+{
+   return is_device_coherent_page(>page);
+}
+
 static inline bool is_pci_p2pdma_page(const struct page *page)
 {
return IS_ENABLED(CONFIG_PCI_P2PDMA) &&
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 598fece89e2b..3e1f97c9fdc6 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5629,8 +5629,8 @@ static int mem_cgroup_move_account(struct page *page,
  *   2(MC_TARGET_SWAP): if the swap entry corresponding to this pte is a
  * target for charge migration. if @target is not NULL, the entry is stored
  * in target->ent.
- *   3(MC_TARGET_DEVICE): like MC_TARGET_PAGE  but page is 
MEMORY_DEVICE_PRIVATE
- * (so ZONE_DEVICE page and thus not on the lru).
+ *   3(MC_TARGET_DEVICE): like MC_TARGET_PAGE  but page is device memory and
+ *   thus not on the lru.
  * For now we such page is charge like a regular page would be as for all
  * intent and purposes it is just special memory taking the place of a
  * regular page.
@@ -5664,7 +5664,8 @@ static enum mc_target_type get_mctgt_type(struct 
vm_area_struct *vma,
 */
if (page_memcg(page) == mc.from) {
ret = MC_TARGET_PAGE;
-   if (is_device_private_page(page))
+   if (is_device_private_page(page) ||
+   is_device_coherent_page(page))
ret = MC_TARGET_DEVICE;
if (target)
target->page = page;
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 27760c19bad7..75d013df86a9 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -1695,12 +1695,16 @@ static int memory_failure_dev_pagemap(unsigned long 
pfn, int flags,
goto unlock;
}
 
-   if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
+   switch (pgmap->type) {
+   case MEMORY_DEVICE_PRIVATE:
+   case MEMORY_DEVICE_COHERENT:
/*
-* TODO: Handle HMM pages which may need coordination
+* TODO: Handle device pages which may need coordination
 * with device-side memory.
 */
goto unlock;
+   default:
+   break;
}
 
/*
diff --git a/mm/memremap.c b/mm/memremap.c
index af0223605e69..471ec84ed82b 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -314,6 +314,16 @@ void *memremap_pages(struct dev_pagemap *pgmap, int nid)
return ERR_PTR(-EINVAL);
}
break;
+   case 

[PATCH v1 00/15] Add MEMORY_DEVICE_COHERENT for coherent device memory mapping

2022-05-05 Thread Alex Sierra
This is our MEMORY_DEVICE_COHERENT patch series rebased and updated
for current 5.18-rc5.

Changes since the last version:
- Fixed problems with migration during long-term pinning in
get_user_pages
- Open coded vm_normal_lru_pages as suggested in previous code review
- Update hmm_gup_test with more get_user_pages calls, include
hmm_cow_in_device in hmm-test.

This patch series introduces MEMORY_DEVICE_COHERENT, a type of memory
owned by a device that can be mapped into CPU page tables like
MEMORY_DEVICE_GENERIC and can also be migrated like
MEMORY_DEVICE_PRIVATE.

This patch series is mostly self-contained except for a few places where
it needs to update other subsystems to handle the new memory type.

System stability and performance are not affected according to our
ongoing testing, including xfstests.

How it works: The system BIOS advertises the GPU device memory
(aka VRAM) as SPM (special purpose memory) in the UEFI system address
map.

The amdgpu driver registers the memory with devmap as
MEMORY_DEVICE_COHERENT using devm_memremap_pages. The initial user for
this hardware page migration capability is the Frontier supercomputer
project. This functionality is not AMD-specific. We expect other GPU
vendors to find this functionality useful, and possibly other hardware
types in the future.

Our test nodes in the lab are similar to the Frontier configuration,
with .5 TB of system memory plus 256 GB of device memory split across
4 GPUs, all in a single coherent address space. Page migration is
expected to improve application efficiency significantly. We will
report empirical results as they become available.

Coherent device type pages at gup are now migrated back to system
memory if they are being pinned long-term (FOLL_LONGTERM). The reason
is, that long-term pinning would interfere with the device memory
manager owning the device-coherent pages (e.g. evictions in TTM).
These series incorporate Alistair Popple patches to do this
migration from pin_user_pages() calls. hmm_gup_test has been added to
hmm-test to test different get user pages calls.

This series includes handling of device-managed anonymous pages
returned by vm_normal_pages. Although they behave like normal pages
for purposes of mapping in CPU page tables and for COW, they do not
support LRU lists, NUMA migration or THP.

We also introduced a FOLL_LRU flag that adds the same behaviour to
follow_page and related APIs, to allow callers to specify that they
expect to put pages on an LRU list.

Alex Sierra (13):
  mm: add zone device coherent type memory support
  mm: add device coherent vma selection for memory migration
  mm: add device coherent checker to remove migration pte
  drm/amdkfd: add SPM support for SVM
  drm/amdkfd: coherent type as sys mem on migration to ram
  lib: test_hmm add ioctl to get zone device type
  lib: test_hmm add module param for zone device type
  lib: add support for device coherent type in test_hmm
  tools: update hmm-test to support device coherent type
  tools: update test_hmm script to support SP config
  mm: handling Non-LRU pages returned by vm_normal_pages
  tools: add hmm gup tests for device coherent type
  tools: add selftests to hmm for COW in device memory

Alistair Popple (2):
  mm: remove the vma check in migrate_vma_setup()
  mm/gup: migrate device coherent pages when pinning instead of failing

 drivers/gpu/drm/amd/amdkfd/kfd_migrate.c |  33 ++-
 fs/proc/task_mmu.c   |   2 +-
 include/linux/memremap.h |  19 ++
 include/linux/migrate.h  |   1 +
 include/linux/mm.h   |   3 +-
 lib/test_hmm.c   | 349 +--
 lib/test_hmm_uapi.h  |  22 +-
 mm/gup.c |  49 +++-
 mm/huge_memory.c |   2 +-
 mm/internal.h|   1 +
 mm/khugepaged.c  |   9 +-
 mm/ksm.c |   6 +-
 mm/madvise.c |   4 +-
 mm/memcontrol.c  |   7 +-
 mm/memory-failure.c  |   8 +-
 mm/memory.c  |   9 +-
 mm/mempolicy.c   |   2 +-
 mm/memremap.c|  10 +
 mm/migrate.c |   7 +-
 mm/migrate_device.c  | 115 ++--
 mm/mlock.c   |   2 +-
 mm/mprotect.c|   2 +-
 mm/rmap.c|   3 +-
 tools/testing/selftests/vm/hmm-tests.c   | 307 ++--
 tools/testing/selftests/vm/test_hmm.sh   |  24 +-
 25 files changed, 814 insertions(+), 182 deletions(-)

-- 
2.32.0



Re: [PATCH] drm: Document that power requirements for DP AUX transfers

2022-05-05 Thread Doug Anderson
Hi,

On Thu, May 5, 2022 at 1:56 PM Dmitry Baryshkov
 wrote:
>
> On Thu, 5 May 2022 at 23:21, Doug Anderson  wrote:
> >
> > Hi,
> >
> > On Thu, May 5, 2022 at 1:10 PM Dmitry Baryshkov
> >  wrote:
> > >
> > > On Thu, 5 May 2022 at 18:53, Doug Anderson  wrote:
> > > >
> > > > Hi,
> > > >
> > > > On Thu, May 5, 2022 at 8:29 AM Ville Syrjälä
> > > >  wrote:
> > > > >
> > > > > On Thu, May 05, 2022 at 08:00:20AM -0700, Doug Anderson wrote:
> > > > > > Hi,
> > > > > >
> > > > > > On Thu, May 5, 2022 at 7:46 AM Ville Syrjälä
> > > > > >  wrote:
> > > > > > >
> > > > > > > On Wed, May 04, 2022 at 02:10:08PM -0400, Lyude Paul wrote:
> > > > > > > > On Wed, 2022-05-04 at 09:04 -0700, Doug Anderson wrote:
> > > > > > > > > Hi,
> > > > > > > > >
> > > > > > > > > On Wed, May 4, 2022 at 5:21 AM Ville Syrjälä
> > > > > > > > >  wrote:
> > > > > > > > > >
> > > > > > > > > > On Tue, May 03, 2022 at 04:21:08PM -0700, Douglas Anderson 
> > > > > > > > > > wrote:
> > > > > > > > > > > When doing DP AUX transfers there are two actors that 
> > > > > > > > > > > need to be
> > > > > > > > > > > powered in order for the DP AUX transfer to work: the DP 
> > > > > > > > > > > source and
> > > > > > > > > > > the DP sync. Commit bacbab58f09d ("drm: Mention the power 
> > > > > > > > > > > state
> > > > > > > > > > > requirement on side-channel operations") added some 
> > > > > > > > > > > documentation
> > > > > > > > > > > saying that the DP source is required to power itself up 
> > > > > > > > > > > (if needed)
> > > > > > > > > > > to do AUX transfers. However, that commit doesn't talk 
> > > > > > > > > > > anything about
> > > > > > > > > > > the DP sink.
> > > > > > > > > > >
> > > > > > > > > > > For full fledged DP the sink isn't really a problem. It's 
> > > > > > > > > > > expected
> > > > > > > > > > > that if an external DP monitor isn't plugged in that 
> > > > > > > > > > > attempting to do
> > > > > > > > > > > AUX transfers won't work. It's also expected that if a DP 
> > > > > > > > > > > monitor is
> > > > > > > > > > > plugged in (and thus asserting HPD) that it AUX transfers 
> > > > > > > > > > > will work.
> > > > > > > > > > >
> > > > > > > > > > > When we're looking at eDP, however, things are less 
> > > > > > > > > > > obvious. Let's add
> > > > > > > > > > > some documentation about expectations. Here's what we'll 
> > > > > > > > > > > say:
> > > > > > > > > > >
> > > > > > > > > > > 1. We don't expect the DP AUX transfer function to power 
> > > > > > > > > > > on an eDP
> > > > > > > > > > > panel. If an eDP panel is physically connected but 
> > > > > > > > > > > powered off then it
> > > > > > > > > > > makes sense for the transfer to fail.
> > > > > > > > > >
> > > > > > > > > > I don't agree with this. I think the panel should just get 
> > > > > > > > > > powred up
> > > > > > > > > > for AUX transfers.
> > > > > > > > >
> > > > > > > > > That's definitely a fair thing to think about and I have at 
> > > > > > > > > times
> > > > > > > > > thought about trying to make it work that way. It always ends 
> > > > > > > > > up
> > > > > > > > > hitting a roadblock.
> > > > > > >
> > > > > > > How do you even probe the panel initially if you can't power it on
> > > > > > > without doing some kind of full modeset/etc.?
> > > > > >
> > > > > > It's not that we can't power it on without a full modeset. It' that 
> > > > > > at
> > > > > > panel probe time all the DRM components haven't been hooked together
> > > > > > yet, so the bridge chain isn't available yet. The panel can power
> > > > > > itself on, though. This is why the documentation I added says: "if a
> > > > > > panel driver is initiating a DP AUX transfer it may power itself up
> > > > > > however it wants"
> > > > > >
> > > > > >
> > > > > > > > > The biggest roadblock that I recall is that to make this work 
> > > > > > > > > then
> > > > > > > > > you'd have to somehow ensure that the bridge chain's 
> > > > > > > > > pre_enable() call
> > > > > > > > > was made as part of the AUX transfer, right? Since the 
> > > > > > > > > transfer
> > > > > > > > > function can be called in any context at all, we have to 
> > > > > > > > > coordinate
> > > > > > > > > this with DRM. If, for instance, DRM is mid way through 
> > > > > > > > > powering the
> > > > > > > > > panel down then we need to wait for DRM to fully finish 
> > > > > > > > > powering down,
> > > > > > > > > then we need to power the panel back up. I don't believe that 
> > > > > > > > > we can
> > > > > > > > > just force the panel to stay on if DRM is turning it off 
> > > > > > > > > because of
> > > > > > > > > panel power sequencing requirements. At least I know it would 
> > > > > > > > > have the
> > > > > > > > > potential to break "samsung-atna33xc20.c" which absolutely 
> > > > > > > > > needs to
> > > > > > > > > see the panel power off after it's been disabled.
> > > > > > > > >
> > > > > > > > > We also, I believe, need to handle the fact that the bridge 
> > > > > 

Re: (subset) [PATCH 1/2] [RFC] regmap: Add bulk read/write callbacks into regmap_config

2022-05-05 Thread Mark Brown
On Thu, May 05, 2022 at 07:32:23PM +0200, Marek Vasut wrote:
> On 5/5/22 17:12, Mark Brown wrote:
> > On Sat, 30 Apr 2022 04:51:44 +0200, Marek Vasut wrote:

> > > Currently the regmap_config structure only allows the user to implement
> > > single element register read/write using .reg_read/.reg_write callbacks.

> > [1/2] regmap: Add bulk read/write callbacks into regmap_config
> >commit: d77e745613680c54708470402e2b623dcd769681

> I was really hoping this would get a lot more review / comments before this
> is applied.

I can easily punt for this release, though TBH I'm not anticipating huge
numbers of comments on a regmap patch unless it breaks things for
people, they tend to be very quiet.  I did go through it and didn't spot
any issues so it seemed like the testing coverage would be useful here.
Are there specific things you're worried about that you'd like feedback
on?


signature.asc
Description: PGP signature


Re: [PATCH] drm/mgag200: Fail on I2C initialization errors

2022-05-05 Thread kernel test robot
Hi Thomas,

I love your patch! Perhaps something to improve:

[auto build test WARNING on drm/drm-next]
[also build test WARNING on drm-exynos/exynos-drm-next drm-intel/for-linux-next 
drm-tip/drm-tip tegra-drm/drm/tegra/for-next v5.18-rc5 next-20220505]
[cannot apply to airlied/drm-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/intel-lab-lkp/linux/commits/Thomas-Zimmermann/drm-mgag200-Fail-on-I2C-initialization-errors/20220505-234643
base:   git://anongit.freedesktop.org/drm/drm drm-next
config: i386-randconfig-a013 
(https://download.01.org/0day-ci/archive/20220506/202205060439.bfj2fmzu-...@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 
5e004fb787698440a387750db7f8028e7cb14cfc)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/intel-lab-lkp/linux/commit/11682b9fc557a02edac08b0dedc91ce704c2f749
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Thomas-Zimmermann/drm-mgag200-Fail-on-I2C-initialization-errors/20220505-234643
git checkout 11682b9fc557a02edac08b0dedc91ce704c2f749
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=i386 SHELL=/bin/bash drivers/gpu/drm/mgag200/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/mgag200/mgag200_mode.c:819:47: warning: variable 'ret' is 
>> uninitialized when used here [-Wuninitialized]
   drm_err(dev, "failed to add DDC bus: %d\n", ret);
   ^~~
   include/drm/drm_print.h:438:46: note: expanded from macro 'drm_err'
   __drm_printk((drm), err,, "*ERROR* " fmt, ##__VA_ARGS__)
   ^~~
   include/drm/drm_print.h:425:48: note: expanded from macro '__drm_printk'
   dev_##level##type((drm)->dev, "[drm] " fmt, ##__VA_ARGS__)
 ^~~
   include/linux/dev_printk.h:144:65: note: expanded from macro 'dev_err'
   dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), 
##__VA_ARGS__)
  
^~~
   include/linux/dev_printk.h:110:23: note: expanded from macro 
'dev_printk_index_wrap'
   _p_func(dev, fmt, ##__VA_ARGS__);   \
   ^~~
   drivers/gpu/drm/mgag200/mgag200_mode.c:815:9: note: initialize the variable 
'ret' to silence this warning
   int ret;
  ^
   = 0
   1 warning generated.


vim +/ret +819 drivers/gpu/drm/mgag200/mgag200_mode.c

   808  
   809  static int mgag200_vga_connector_init(struct mga_device *mdev)
   810  {
   811  struct drm_device *dev = >base;
   812  struct mga_connector *mconnector = >connector;
   813  struct drm_connector *connector = >base;
   814  struct mga_i2c_chan *i2c;
   815  int ret;
   816  
   817  i2c = mgag200_i2c_create(dev);
   818  if (IS_ERR(i2c)) {
 > 819  drm_err(dev, "failed to add DDC bus: %d\n", ret);
   820  return PTR_ERR(i2c);
   821  }
   822  
   823  ret = drm_connector_init_with_ddc(dev, connector,
   824_vga_connector_funcs,
   825DRM_MODE_CONNECTOR_VGA,
   826>adapter);
   827  if (ret)
   828  goto err_mgag200_i2c_destroy;
   829  drm_connector_helper_add(connector, 
_vga_connector_helper_funcs);
   830  
   831  mconnector->i2c = i2c;
   832  
   833  return 0;
   834  
   835  err_mgag200_i2c_destroy:
   836  mgag200_i2c_destroy(i2c);
   837  return ret;
   838  }
   839  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp


Re: [Intel-gfx] [PATCH 07/11] drm/i915/pvc: Engines definitions for new copy engines

2022-05-05 Thread Matt Roper
On Tue, May 03, 2022 at 09:05:43AM +0100, Tvrtko Ursulin wrote:
> 
> On 02/05/2022 17:34, Matt Roper wrote:
> > This patch adds the basic definitions needed to support
> > new copy engines. Also updating the cmd_info to accommodate
> > new engines, as the engine id's of legacy engines have been
> > changed.
> > 
> > Original-author: CQ Tang
> > Signed-off-by: Matt Roper 
> > ---
> >   drivers/gpu/drm/i915/gt/intel_engine_cs.c| 56 
> >   drivers/gpu/drm/i915/gt/intel_engine_types.h | 10 +++-
> >   drivers/gpu/drm/i915/gt/intel_gt_regs.h  |  8 +++
> >   drivers/gpu/drm/i915/gvt/cmd_parser.c|  2 +-
> >   drivers/gpu/drm/i915/i915_reg.h  |  8 +++
> >   5 files changed, 82 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
> > b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > index 14c6ddbbfde8..4532c3ea9ace 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > @@ -71,6 +71,62 @@ static const struct engine_info intel_engines[] = {
> > { .graphics_ver = 6, .base = BLT_RING_BASE }
> > },
> > },
> > +   [BCS1] = {
> > +   .class = COPY_ENGINE_CLASS,
> > +   .instance = 1,
> > +   .mmio_bases = {
> > +   { .graphics_ver = 12, .base = XEHPC_BCS1_RING_BASE }
> > +   },
> > +   },
> > +   [BCS2] = {
> > +   .class = COPY_ENGINE_CLASS,
> > +   .instance = 2,
> > +   .mmio_bases = {
> > +   { .graphics_ver = 12, .base = XEHPC_BCS2_RING_BASE }
> > +   },
> > +   },
> > +   [BCS3] = {
> > +   .class = COPY_ENGINE_CLASS,
> > +   .instance = 3,
> > +   .mmio_bases = {
> > +   { .graphics_ver = 12, .base = XEHPC_BCS3_RING_BASE }
> > +   },
> > +   },
> > +   [BCS4] = {
> > +   .class = COPY_ENGINE_CLASS,
> > +   .instance = 4,
> > +   .mmio_bases = {
> > +   { .graphics_ver = 12, .base = XEHPC_BCS4_RING_BASE }
> > +   },
> > +   },
> > +   [BCS5] = {
> > +   .class = COPY_ENGINE_CLASS,
> > +   .instance = 5,
> > +   .mmio_bases = {
> > +   { .graphics_ver = 12, .base = XEHPC_BCS5_RING_BASE }
> > +   },
> > +   },
> > +   [BCS6] = {
> > +   .class = COPY_ENGINE_CLASS,
> > +   .instance = 6,
> > +   .mmio_bases = {
> > +   { .graphics_ver = 12, .base = XEHPC_BCS6_RING_BASE }
> > +   },
> > +   },
> > +   [BCS7] = {
> > +   .class = COPY_ENGINE_CLASS,
> > +   .instance = 7,
> > +   .mmio_bases = {
> > +   { .graphics_ver = 12, .base = XEHPC_BCS7_RING_BASE }
> > +   },
> > +   },
> > +   [BCS8] = {
> > +   .class = COPY_ENGINE_CLASS,
> > +   .instance = 8,
> > +   .mmio_bases = {
> > +   { .graphics_ver = 12, .base = XEHPC_BCS8_RING_BASE }
> > +   },
> > +   },
> > [VCS0] = {
> > .class = VIDEO_DECODE_CLASS,
> > .instance = 0,
> > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
> > b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> > index 298f2cc7a879..356c15cdccf0 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> > @@ -35,7 +35,7 @@
> >   #define OTHER_CLASS   4
> >   #define COMPUTE_CLASS 5
> >   #define MAX_ENGINE_CLASS  5
> > -#define MAX_ENGINE_INSTANCE7
> > +#define MAX_ENGINE_INSTANCE8
> >   #define I915_MAX_SLICES   3
> >   #define I915_MAX_SUBSLICES 8
> > @@ -107,6 +107,14 @@ struct i915_ctx_workarounds {
> >   enum intel_engine_id {
> > RCS0 = 0,
> > BCS0,
> > +   BCS1,
> > +   BCS2,
> > +   BCS3,
> > +   BCS4,
> > +   BCS5,
> > +   BCS6,
> > +   BCS7,
> > +   BCS8,
> 
> _BCS(n) macro will not be required?
> 
> > VCS0,
> > VCS1,
> > VCS2,
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
> > b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > index a0a49c16babd..aa2c0974b02c 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > @@ -1476,6 +1476,14 @@
> >   #define   GEN11_KCR   (19)
> >   #define   GEN11_GTPM  (16)
> >   #define   GEN11_BCS   (15)
> > +#define   XEHPC_BCS1   (14)
> > +#define   XEHPC_BCS2   (13)
> > +#define   XEHPC_BCS3   (12)
> > +#define   XEHPC_BCS4   (11)
> > +#define   XEHPC_BCS5   (10)
> > +#define   XEHPC_BCS6   (9)
> > +#define   XEHPC_BCS7   (8)
> > +#define   XEHPC_BCS8   (23)
> >   #define   GEN12_CCS3 

Re: [PATCH] drm: Document that power requirements for DP AUX transfers

2022-05-05 Thread Dmitry Baryshkov
On Thu, 5 May 2022 at 23:21, Doug Anderson  wrote:
>
> Hi,
>
> On Thu, May 5, 2022 at 1:10 PM Dmitry Baryshkov
>  wrote:
> >
> > On Thu, 5 May 2022 at 18:53, Doug Anderson  wrote:
> > >
> > > Hi,
> > >
> > > On Thu, May 5, 2022 at 8:29 AM Ville Syrjälä
> > >  wrote:
> > > >
> > > > On Thu, May 05, 2022 at 08:00:20AM -0700, Doug Anderson wrote:
> > > > > Hi,
> > > > >
> > > > > On Thu, May 5, 2022 at 7:46 AM Ville Syrjälä
> > > > >  wrote:
> > > > > >
> > > > > > On Wed, May 04, 2022 at 02:10:08PM -0400, Lyude Paul wrote:
> > > > > > > On Wed, 2022-05-04 at 09:04 -0700, Doug Anderson wrote:
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > On Wed, May 4, 2022 at 5:21 AM Ville Syrjälä
> > > > > > > >  wrote:
> > > > > > > > >
> > > > > > > > > On Tue, May 03, 2022 at 04:21:08PM -0700, Douglas Anderson 
> > > > > > > > > wrote:
> > > > > > > > > > When doing DP AUX transfers there are two actors that need 
> > > > > > > > > > to be
> > > > > > > > > > powered in order for the DP AUX transfer to work: the DP 
> > > > > > > > > > source and
> > > > > > > > > > the DP sync. Commit bacbab58f09d ("drm: Mention the power 
> > > > > > > > > > state
> > > > > > > > > > requirement on side-channel operations") added some 
> > > > > > > > > > documentation
> > > > > > > > > > saying that the DP source is required to power itself up 
> > > > > > > > > > (if needed)
> > > > > > > > > > to do AUX transfers. However, that commit doesn't talk 
> > > > > > > > > > anything about
> > > > > > > > > > the DP sink.
> > > > > > > > > >
> > > > > > > > > > For full fledged DP the sink isn't really a problem. It's 
> > > > > > > > > > expected
> > > > > > > > > > that if an external DP monitor isn't plugged in that 
> > > > > > > > > > attempting to do
> > > > > > > > > > AUX transfers won't work. It's also expected that if a DP 
> > > > > > > > > > monitor is
> > > > > > > > > > plugged in (and thus asserting HPD) that it AUX transfers 
> > > > > > > > > > will work.
> > > > > > > > > >
> > > > > > > > > > When we're looking at eDP, however, things are less 
> > > > > > > > > > obvious. Let's add
> > > > > > > > > > some documentation about expectations. Here's what we'll 
> > > > > > > > > > say:
> > > > > > > > > >
> > > > > > > > > > 1. We don't expect the DP AUX transfer function to power on 
> > > > > > > > > > an eDP
> > > > > > > > > > panel. If an eDP panel is physically connected but powered 
> > > > > > > > > > off then it
> > > > > > > > > > makes sense for the transfer to fail.
> > > > > > > > >
> > > > > > > > > I don't agree with this. I think the panel should just get 
> > > > > > > > > powred up
> > > > > > > > > for AUX transfers.
> > > > > > > >
> > > > > > > > That's definitely a fair thing to think about and I have at 
> > > > > > > > times
> > > > > > > > thought about trying to make it work that way. It always ends up
> > > > > > > > hitting a roadblock.
> > > > > >
> > > > > > How do you even probe the panel initially if you can't power it on
> > > > > > without doing some kind of full modeset/etc.?
> > > > >
> > > > > It's not that we can't power it on without a full modeset. It' that at
> > > > > panel probe time all the DRM components haven't been hooked together
> > > > > yet, so the bridge chain isn't available yet. The panel can power
> > > > > itself on, though. This is why the documentation I added says: "if a
> > > > > panel driver is initiating a DP AUX transfer it may power itself up
> > > > > however it wants"
> > > > >
> > > > >
> > > > > > > > The biggest roadblock that I recall is that to make this work 
> > > > > > > > then
> > > > > > > > you'd have to somehow ensure that the bridge chain's 
> > > > > > > > pre_enable() call
> > > > > > > > was made as part of the AUX transfer, right? Since the transfer
> > > > > > > > function can be called in any context at all, we have to 
> > > > > > > > coordinate
> > > > > > > > this with DRM. If, for instance, DRM is mid way through 
> > > > > > > > powering the
> > > > > > > > panel down then we need to wait for DRM to fully finish 
> > > > > > > > powering down,
> > > > > > > > then we need to power the panel back up. I don't believe that 
> > > > > > > > we can
> > > > > > > > just force the panel to stay on if DRM is turning it off 
> > > > > > > > because of
> > > > > > > > panel power sequencing requirements. At least I know it would 
> > > > > > > > have the
> > > > > > > > potential to break "samsung-atna33xc20.c" which absolutely 
> > > > > > > > needs to
> > > > > > > > see the panel power off after it's been disabled.
> > > > > > > >
> > > > > > > > We also, I believe, need to handle the fact that the bridge 
> > > > > > > > chain may
> > > > > > > > not have even been created yet. We do AUX transfers to read the 
> > > > > > > > EDID
> > > > > > > > and also to setup the backlight in the probe function of 
> > > > > > > > panel-edp. At
> > > > > > > > that point the panel hasn't been linked into the chain. We had 
> > > > > > > > _long_

Re: [PATCH] drm: Document that power requirements for DP AUX transfers

2022-05-05 Thread Doug Anderson
Hi,

On Thu, May 5, 2022 at 1:10 PM Dmitry Baryshkov
 wrote:
>
> On Thu, 5 May 2022 at 18:53, Doug Anderson  wrote:
> >
> > Hi,
> >
> > On Thu, May 5, 2022 at 8:29 AM Ville Syrjälä
> >  wrote:
> > >
> > > On Thu, May 05, 2022 at 08:00:20AM -0700, Doug Anderson wrote:
> > > > Hi,
> > > >
> > > > On Thu, May 5, 2022 at 7:46 AM Ville Syrjälä
> > > >  wrote:
> > > > >
> > > > > On Wed, May 04, 2022 at 02:10:08PM -0400, Lyude Paul wrote:
> > > > > > On Wed, 2022-05-04 at 09:04 -0700, Doug Anderson wrote:
> > > > > > > Hi,
> > > > > > >
> > > > > > > On Wed, May 4, 2022 at 5:21 AM Ville Syrjälä
> > > > > > >  wrote:
> > > > > > > >
> > > > > > > > On Tue, May 03, 2022 at 04:21:08PM -0700, Douglas Anderson 
> > > > > > > > wrote:
> > > > > > > > > When doing DP AUX transfers there are two actors that need to 
> > > > > > > > > be
> > > > > > > > > powered in order for the DP AUX transfer to work: the DP 
> > > > > > > > > source and
> > > > > > > > > the DP sync. Commit bacbab58f09d ("drm: Mention the power 
> > > > > > > > > state
> > > > > > > > > requirement on side-channel operations") added some 
> > > > > > > > > documentation
> > > > > > > > > saying that the DP source is required to power itself up (if 
> > > > > > > > > needed)
> > > > > > > > > to do AUX transfers. However, that commit doesn't talk 
> > > > > > > > > anything about
> > > > > > > > > the DP sink.
> > > > > > > > >
> > > > > > > > > For full fledged DP the sink isn't really a problem. It's 
> > > > > > > > > expected
> > > > > > > > > that if an external DP monitor isn't plugged in that 
> > > > > > > > > attempting to do
> > > > > > > > > AUX transfers won't work. It's also expected that if a DP 
> > > > > > > > > monitor is
> > > > > > > > > plugged in (and thus asserting HPD) that it AUX transfers 
> > > > > > > > > will work.
> > > > > > > > >
> > > > > > > > > When we're looking at eDP, however, things are less obvious. 
> > > > > > > > > Let's add
> > > > > > > > > some documentation about expectations. Here's what we'll say:
> > > > > > > > >
> > > > > > > > > 1. We don't expect the DP AUX transfer function to power on 
> > > > > > > > > an eDP
> > > > > > > > > panel. If an eDP panel is physically connected but powered 
> > > > > > > > > off then it
> > > > > > > > > makes sense for the transfer to fail.
> > > > > > > >
> > > > > > > > I don't agree with this. I think the panel should just get 
> > > > > > > > powred up
> > > > > > > > for AUX transfers.
> > > > > > >
> > > > > > > That's definitely a fair thing to think about and I have at times
> > > > > > > thought about trying to make it work that way. It always ends up
> > > > > > > hitting a roadblock.
> > > > >
> > > > > How do you even probe the panel initially if you can't power it on
> > > > > without doing some kind of full modeset/etc.?
> > > >
> > > > It's not that we can't power it on without a full modeset. It' that at
> > > > panel probe time all the DRM components haven't been hooked together
> > > > yet, so the bridge chain isn't available yet. The panel can power
> > > > itself on, though. This is why the documentation I added says: "if a
> > > > panel driver is initiating a DP AUX transfer it may power itself up
> > > > however it wants"
> > > >
> > > >
> > > > > > > The biggest roadblock that I recall is that to make this work then
> > > > > > > you'd have to somehow ensure that the bridge chain's pre_enable() 
> > > > > > > call
> > > > > > > was made as part of the AUX transfer, right? Since the transfer
> > > > > > > function can be called in any context at all, we have to 
> > > > > > > coordinate
> > > > > > > this with DRM. If, for instance, DRM is mid way through powering 
> > > > > > > the
> > > > > > > panel down then we need to wait for DRM to fully finish powering 
> > > > > > > down,
> > > > > > > then we need to power the panel back up. I don't believe that we 
> > > > > > > can
> > > > > > > just force the panel to stay on if DRM is turning it off because 
> > > > > > > of
> > > > > > > panel power sequencing requirements. At least I know it would 
> > > > > > > have the
> > > > > > > potential to break "samsung-atna33xc20.c" which absolutely needs 
> > > > > > > to
> > > > > > > see the panel power off after it's been disabled.
> > > > > > >
> > > > > > > We also, I believe, need to handle the fact that the bridge chain 
> > > > > > > may
> > > > > > > not have even been created yet. We do AUX transfers to read the 
> > > > > > > EDID
> > > > > > > and also to setup the backlight in the probe function of 
> > > > > > > panel-edp. At
> > > > > > > that point the panel hasn't been linked into the chain. We had 
> > > > > > > _long_
> > > > > > > discussions [1] about moving these out of probe and decided that 
> > > > > > > we
> > > > > > > could move the EDID read to be later but that it was going to 
> > > > > > > really
> > > > > > > ugly to move the AUX backlight later. The backlight would end up
> > > > > > > popping up at some point in time 

Re: [PATCH 2/2] drm/probe-helper: For DP, add 640x480 if all other modes are bad

2022-05-05 Thread Dmitry Baryshkov
On Tue, 26 Apr 2022 at 21:47, Douglas Anderson  wrote:
>
> As per Displayport spec section 5.2.1.2 ("Video Timing Format") says
> that all detachable sinks shall support 640x480 @60Hz as a fail safe
> mode.
>
> A DP compliance test expected us to utilize the above fact when all
> modes it presented to the DP source were not achievable. It presented
> only modes that would be achievable with more lanes and/or higher
> speeds than we had available and expected that when we couldn't do
> that then we'd fall back to 640x480 even though it didn't advertise
> this size.
>
> In order to pass the compliance test (and also support any users who
> might fall into a similar situation with their display), we need to
> add 640x480 into the list of modes. However, we don't want to add
> 640x480 all the time. Despite the fact that the DP spec says all sinks
> _shall support_ 640x480, they're not guaranteed to support it
> _well_. Continuing to read the spec you can see that the display is
> not required to really treat 640x480 equal to all the other modes. It
> doesn't need to scale or anything--just display the pixels somehow for
> failsafe purposes. It should also be noted that it's not hard to find
> a display hooked up via DisplayPort that _doesn't_ support 640x480 at
> all. The HP ZR30w screen I'm sitting in front of has a native DP port
> and doesn't work at 640x480. I also plugged in a tiny 800x480 HDMI
> display via a DP to HDMI adapter and that screen definitely doesn't
> support 640x480.
>
> As a compromise solution, let's only add the 640x480 mode if:
> * We're on DP.
> * All other modes have been pruned.
>
> This acknowledges that 640x480 might not be the best mode to use but,
> since sinks are _supposed_ to support it, we will at least fall back
> to it if there's nothing else.
>
> Note that we _don't_ add higher resolution modes like 1024x768 in this
> case. We only add those modes for a failed EDID read where we have no
> idea what's going on. In the case where we've pruned all modes then
> instead we only want 640x480 which is the only defined "Fail Safe"
> resolution.
>
> This patch originated in response to Kuogee Hsieh's patch [1].
>
> [1] 
> https://lore.kernel.org/r/1650671124-14030-1-git-send-email-quic_khs...@quicinc.com
>
> Signed-off-by: Douglas Anderson 

Reviewed-by: Dmitry Baryshkov 

> ---
>
>  drivers/gpu/drm/drm_probe_helper.c | 26 +-
>  1 file changed, 21 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> b/drivers/gpu/drm/drm_probe_helper.c
> index 819225629010..90cd46cbfec1 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -476,7 +476,6 @@ int drm_helper_probe_single_connector_modes(struct 
> drm_connector *connector,
> const struct drm_connector_helper_funcs *connector_funcs =
> connector->helper_private;
> int count = 0, ret;
> -   bool verbose_prune = true;
> enum drm_connector_status old_status;
> struct drm_modeset_acquire_ctx ctx;
>
> @@ -556,8 +555,8 @@ int drm_helper_probe_single_connector_modes(struct 
> drm_connector *connector,
> DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
> connector->base.id, connector->name);
> drm_connector_update_edid_property(connector, NULL);
> -   verbose_prune = false;
> -   goto prune;
> +   drm_mode_prune_invalid(dev, >modes, false);
> +   goto exit;
> }
>
> count = (*connector_funcs->get_modes)(connector);
> @@ -580,9 +579,26 @@ int drm_helper_probe_single_connector_modes(struct 
> drm_connector *connector,
> }
> }
>
> -prune:
> -   drm_mode_prune_invalid(dev, >modes, verbose_prune);
> +   drm_mode_prune_invalid(dev, >modes, true);
>
> +   /*
> +* Displayport spec section 5.2.1.2 ("Video Timing Format") says that
> +* all detachable sinks shall support 640x480 @60Hz as a fail safe
> +* mode. If all modes were pruned, perhaps because they need more
> +* lanes or a higher pixel clock than available, at least try to add
> +* in 640x480.
> +*/
> +   if (list_empty(>modes) &&
> +   connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
> +   count = drm_add_modes_noedid(connector, 640, 480);
> +   if (_drm_helper_update_and_validate(connector, maxX, maxY, 
> )) {
> +   drm_modeset_backoff();
> +   goto retry;
> +   }
> +   drm_mode_prune_invalid(dev, >modes, true);
> +   }
> +
> +exit:
> drm_modeset_drop_locks();
> drm_modeset_acquire_fini();
>
> --
> 2.36.0.rc2.479.g8af0fa9b8e-goog
>


-- 
With best wishes
Dmitry


Re: [PATCH] drm: Document that power requirements for DP AUX transfers

2022-05-05 Thread Doug Anderson
Hi,

On Thu, May 5, 2022 at 12:19 PM Ville Syrjälä
 wrote:
>
> On Thu, May 05, 2022 at 08:53:12AM -0700, Doug Anderson wrote:
> > Hi,
> >
> > On Thu, May 5, 2022 at 8:29 AM Ville Syrjälä
> >  wrote:
> > >
> > > On Thu, May 05, 2022 at 08:00:20AM -0700, Doug Anderson wrote:
> > > > Hi,
> > > >
> > > > On Thu, May 5, 2022 at 7:46 AM Ville Syrjälä
> > > >  wrote:
> > > > >
> > > > > On Wed, May 04, 2022 at 02:10:08PM -0400, Lyude Paul wrote:
> > > > > > On Wed, 2022-05-04 at 09:04 -0700, Doug Anderson wrote:
> > > > > > > Hi,
> > > > > > >
> > > > > > > On Wed, May 4, 2022 at 5:21 AM Ville Syrjälä
> > > > > > >  wrote:
> > > > > > > >
> > > > > > > > On Tue, May 03, 2022 at 04:21:08PM -0700, Douglas Anderson 
> > > > > > > > wrote:
> > > > > > > > > When doing DP AUX transfers there are two actors that need to 
> > > > > > > > > be
> > > > > > > > > powered in order for the DP AUX transfer to work: the DP 
> > > > > > > > > source and
> > > > > > > > > the DP sync. Commit bacbab58f09d ("drm: Mention the power 
> > > > > > > > > state
> > > > > > > > > requirement on side-channel operations") added some 
> > > > > > > > > documentation
> > > > > > > > > saying that the DP source is required to power itself up (if 
> > > > > > > > > needed)
> > > > > > > > > to do AUX transfers. However, that commit doesn't talk 
> > > > > > > > > anything about
> > > > > > > > > the DP sink.
> > > > > > > > >
> > > > > > > > > For full fledged DP the sink isn't really a problem. It's 
> > > > > > > > > expected
> > > > > > > > > that if an external DP monitor isn't plugged in that 
> > > > > > > > > attempting to do
> > > > > > > > > AUX transfers won't work. It's also expected that if a DP 
> > > > > > > > > monitor is
> > > > > > > > > plugged in (and thus asserting HPD) that it AUX transfers 
> > > > > > > > > will work.
> > > > > > > > >
> > > > > > > > > When we're looking at eDP, however, things are less obvious. 
> > > > > > > > > Let's add
> > > > > > > > > some documentation about expectations. Here's what we'll say:
> > > > > > > > >
> > > > > > > > > 1. We don't expect the DP AUX transfer function to power on 
> > > > > > > > > an eDP
> > > > > > > > > panel. If an eDP panel is physically connected but powered 
> > > > > > > > > off then it
> > > > > > > > > makes sense for the transfer to fail.
> > > > > > > >
> > > > > > > > I don't agree with this. I think the panel should just get 
> > > > > > > > powred up
> > > > > > > > for AUX transfers.
> > > > > > >
> > > > > > > That's definitely a fair thing to think about and I have at times
> > > > > > > thought about trying to make it work that way. It always ends up
> > > > > > > hitting a roadblock.
> > > > >
> > > > > How do you even probe the panel initially if you can't power it on
> > > > > without doing some kind of full modeset/etc.?
> > > >
> > > > It's not that we can't power it on without a full modeset. It' that at
> > > > panel probe time all the DRM components haven't been hooked together
> > > > yet, so the bridge chain isn't available yet. The panel can power
> > > > itself on, though. This is why the documentation I added says: "if a
> > > > panel driver is initiating a DP AUX transfer it may power itself up
> > > > however it wants"
> > > >
> > > >
> > > > > > > The biggest roadblock that I recall is that to make this work then
> > > > > > > you'd have to somehow ensure that the bridge chain's pre_enable() 
> > > > > > > call
> > > > > > > was made as part of the AUX transfer, right? Since the transfer
> > > > > > > function can be called in any context at all, we have to 
> > > > > > > coordinate
> > > > > > > this with DRM. If, for instance, DRM is mid way through powering 
> > > > > > > the
> > > > > > > panel down then we need to wait for DRM to fully finish powering 
> > > > > > > down,
> > > > > > > then we need to power the panel back up. I don't believe that we 
> > > > > > > can
> > > > > > > just force the panel to stay on if DRM is turning it off because 
> > > > > > > of
> > > > > > > panel power sequencing requirements. At least I know it would 
> > > > > > > have the
> > > > > > > potential to break "samsung-atna33xc20.c" which absolutely needs 
> > > > > > > to
> > > > > > > see the panel power off after it's been disabled.
> > > > > > >
> > > > > > > We also, I believe, need to handle the fact that the bridge chain 
> > > > > > > may
> > > > > > > not have even been created yet. We do AUX transfers to read the 
> > > > > > > EDID
> > > > > > > and also to setup the backlight in the probe function of 
> > > > > > > panel-edp. At
> > > > > > > that point the panel hasn't been linked into the chain. We had 
> > > > > > > _long_
> > > > > > > discussions [1] about moving these out of probe and decided that 
> > > > > > > we
> > > > > > > could move the EDID read to be later but that it was going to 
> > > > > > > really
> > > > > > > ugly to move the AUX backlight later. The backlight would end up
> > > > > > > popping up at some point 

Re: [PATCH 2/2] drm/probe-helper: For DP, add 640x480 if all other modes are bad

2022-05-05 Thread Dmitry Baryshkov
On Thu, 5 May 2022 at 20:30, Kuogee Hsieh  wrote:
>
>
> On 5/5/2022 10:20 AM, Abhinav Kumar wrote:
> > Hi Doug
> >
> > On 5/5/2022 8:44 AM, Doug Anderson wrote:
> >> Ville,
> >>
> >> On Tue, Apr 26, 2022 at 11:47 AM Douglas Anderson
> >>  wrote:
> >>>
> >>> As per Displayport spec section 5.2.1.2 ("Video Timing Format") says
> >>> that all detachable sinks shall support 640x480 @60Hz as a fail safe
> >>> mode.
> >>>
> >>> A DP compliance test expected us to utilize the above fact when all
> >>> modes it presented to the DP source were not achievable. It presented
> >>> only modes that would be achievable with more lanes and/or higher
> >>> speeds than we had available and expected that when we couldn't do
> >>> that then we'd fall back to 640x480 even though it didn't advertise
> >>> this size.
> >>>
> >>> In order to pass the compliance test (and also support any users who
> >>> might fall into a similar situation with their display), we need to
> >>> add 640x480 into the list of modes. However, we don't want to add
> >>> 640x480 all the time. Despite the fact that the DP spec says all sinks
> >>> _shall support_ 640x480, they're not guaranteed to support it
> >>> _well_. Continuing to read the spec you can see that the display is
> >>> not required to really treat 640x480 equal to all the other modes. It
> >>> doesn't need to scale or anything--just display the pixels somehow for
> >>> failsafe purposes. It should also be noted that it's not hard to find
> >>> a display hooked up via DisplayPort that _doesn't_ support 640x480 at
> >>> all. The HP ZR30w screen I'm sitting in front of has a native DP port
> >>> and doesn't work at 640x480. I also plugged in a tiny 800x480 HDMI
> >>> display via a DP to HDMI adapter and that screen definitely doesn't
> >>> support 640x480.
> >>>
> >>> As a compromise solution, let's only add the 640x480 mode if:
> >>> * We're on DP.
> >>> * All other modes have been pruned.
> >>>
> >>> This acknowledges that 640x480 might not be the best mode to use but,
> >>> since sinks are _supposed_ to support it, we will at least fall back
> >>> to it if there's nothing else.
> >>>
> >>> Note that we _don't_ add higher resolution modes like 1024x768 in this
> >>> case. We only add those modes for a failed EDID read where we have no
> >>> idea what's going on. In the case where we've pruned all modes then
> >>> instead we only want 640x480 which is the only defined "Fail Safe"
> >>> resolution.
> >>>
> >>> This patch originated in response to Kuogee Hsieh's patch [1].
> >>>
> >>> [1]
> >>> https://lore.kernel.org/r/1650671124-14030-1-git-send-email-quic_khs...@quicinc.com
> >>>
> >>> Signed-off-by: Douglas Anderson 
> >>> ---
> >>>
> >>>   drivers/gpu/drm/drm_probe_helper.c | 26 +-
> >>>   1 file changed, 21 insertions(+), 5 deletions(-)
> >>
> >> I think this patch is fairly safe / non-controversial, but someone
> >> suggested you might have an opinion on it and another patch I posted
> >> recently [1] so I wanted to double-check. Just to be clear: I'm hoping
> >> to land _both_ this patch and [1]. If you don't have an opinion,
> >> that's OK too.
> >>
> >> Abhinav: I think maybe you're happy with this now? Would you be
> >> willing to give a Reviewed-by?
> >
> > Yes, I have no concerns with this approach from DP spec standpoint and
> > in addition, kuogee has tested this out and this does help us to pass
> > the tests.
> >
> > Although, I might be missing some historical context on why this is
> > not already done.
> >
> > But apart from that, LGTM. Hence,
> >
> > Reviewed-by: Abhinav Kumar 
> > Tested-by: Kuogee Hsieh 

This line got wrong quotation level, so it will not be noticed by
patchwork (and can be easily missed by other people too). Please
resend.

> >>
> >> [1]
> >> https://lore.kernel.org/r/20220426132121.RFC.1.I31ec454f8d4ffce51a7708a8092f8a6f9c929092@changeid
> >>
> >> -Doug



-- 
With best wishes
Dmitry


Re: [PATCH] drm: Document that power requirements for DP AUX transfers

2022-05-05 Thread Dmitry Baryshkov
On Thu, 5 May 2022 at 18:53, Doug Anderson  wrote:
>
> Hi,
>
> On Thu, May 5, 2022 at 8:29 AM Ville Syrjälä
>  wrote:
> >
> > On Thu, May 05, 2022 at 08:00:20AM -0700, Doug Anderson wrote:
> > > Hi,
> > >
> > > On Thu, May 5, 2022 at 7:46 AM Ville Syrjälä
> > >  wrote:
> > > >
> > > > On Wed, May 04, 2022 at 02:10:08PM -0400, Lyude Paul wrote:
> > > > > On Wed, 2022-05-04 at 09:04 -0700, Doug Anderson wrote:
> > > > > > Hi,
> > > > > >
> > > > > > On Wed, May 4, 2022 at 5:21 AM Ville Syrjälä
> > > > > >  wrote:
> > > > > > >
> > > > > > > On Tue, May 03, 2022 at 04:21:08PM -0700, Douglas Anderson wrote:
> > > > > > > > When doing DP AUX transfers there are two actors that need to be
> > > > > > > > powered in order for the DP AUX transfer to work: the DP source 
> > > > > > > > and
> > > > > > > > the DP sync. Commit bacbab58f09d ("drm: Mention the power state
> > > > > > > > requirement on side-channel operations") added some 
> > > > > > > > documentation
> > > > > > > > saying that the DP source is required to power itself up (if 
> > > > > > > > needed)
> > > > > > > > to do AUX transfers. However, that commit doesn't talk anything 
> > > > > > > > about
> > > > > > > > the DP sink.
> > > > > > > >
> > > > > > > > For full fledged DP the sink isn't really a problem. It's 
> > > > > > > > expected
> > > > > > > > that if an external DP monitor isn't plugged in that attempting 
> > > > > > > > to do
> > > > > > > > AUX transfers won't work. It's also expected that if a DP 
> > > > > > > > monitor is
> > > > > > > > plugged in (and thus asserting HPD) that it AUX transfers will 
> > > > > > > > work.
> > > > > > > >
> > > > > > > > When we're looking at eDP, however, things are less obvious. 
> > > > > > > > Let's add
> > > > > > > > some documentation about expectations. Here's what we'll say:
> > > > > > > >
> > > > > > > > 1. We don't expect the DP AUX transfer function to power on an 
> > > > > > > > eDP
> > > > > > > > panel. If an eDP panel is physically connected but powered off 
> > > > > > > > then it
> > > > > > > > makes sense for the transfer to fail.
> > > > > > >
> > > > > > > I don't agree with this. I think the panel should just get powred 
> > > > > > > up
> > > > > > > for AUX transfers.
> > > > > >
> > > > > > That's definitely a fair thing to think about and I have at times
> > > > > > thought about trying to make it work that way. It always ends up
> > > > > > hitting a roadblock.
> > > >
> > > > How do you even probe the panel initially if you can't power it on
> > > > without doing some kind of full modeset/etc.?
> > >
> > > It's not that we can't power it on without a full modeset. It' that at
> > > panel probe time all the DRM components haven't been hooked together
> > > yet, so the bridge chain isn't available yet. The panel can power
> > > itself on, though. This is why the documentation I added says: "if a
> > > panel driver is initiating a DP AUX transfer it may power itself up
> > > however it wants"
> > >
> > >
> > > > > > The biggest roadblock that I recall is that to make this work then
> > > > > > you'd have to somehow ensure that the bridge chain's pre_enable() 
> > > > > > call
> > > > > > was made as part of the AUX transfer, right? Since the transfer
> > > > > > function can be called in any context at all, we have to coordinate
> > > > > > this with DRM. If, for instance, DRM is mid way through powering the
> > > > > > panel down then we need to wait for DRM to fully finish powering 
> > > > > > down,
> > > > > > then we need to power the panel back up. I don't believe that we can
> > > > > > just force the panel to stay on if DRM is turning it off because of
> > > > > > panel power sequencing requirements. At least I know it would have 
> > > > > > the
> > > > > > potential to break "samsung-atna33xc20.c" which absolutely needs to
> > > > > > see the panel power off after it's been disabled.
> > > > > >
> > > > > > We also, I believe, need to handle the fact that the bridge chain 
> > > > > > may
> > > > > > not have even been created yet. We do AUX transfers to read the EDID
> > > > > > and also to setup the backlight in the probe function of panel-edp. 
> > > > > > At
> > > > > > that point the panel hasn't been linked into the chain. We had 
> > > > > > _long_
> > > > > > discussions [1] about moving these out of probe and decided that we
> > > > > > could move the EDID read to be later but that it was going to really
> > > > > > ugly to move the AUX backlight later. The backlight would end up
> > > > > > popping up at some point in time later (the first call to panel
> > > > > > prepare() or maybe get_modes()) and that seemed weird.
> > > > > >
> > > > > > [1]
> > > > > > https://lore.kernel.org/lkml/CAD=FV=u5-stdlydkejwlaog-0wgxr49vxtwuyuo7z2puibl...@mail.gmail.com/
> > > > > >
> > > > > >
> > > > > > > Otherwise you can't trust that eg. the /dev/aux
> > > > > > > stuff is actually usable.
> > > > > >
> > > > > > Yeah, it's been on my mind to talk more about 

Re: [PATCH 18/48] ARM: pxa: hx4700: use gpio descriptors for audio

2022-05-05 Thread Arnd Bergmann
On Thu, May 5, 2022 at 5:04 PM Mark Brown  wrote:
> On Thu, May 05, 2022 at 04:59:35PM +0200, Arnd Bergmann wrote:
> > On Thu, May 5, 2022 at 4:39 PM Mark Brown  wrote:
> > > On Thu, May 05, 2022 at 04:33:06PM +0200, Linus Walleij wrote:
> > > > On Thu, May 5, 2022 at 8:04 AM Arnd Bergmann  wrote:
>
> > > > > static struct snd_soc_jack_pin hs_jack_pin[] = {
> > > > > {
> > > > > .pin= "Headphone Jack",
> > > > > .mask   = SND_JACK_HEADPHONE,
> > > > > },
> > > > > {
> > > > > .pin= "Speaker",
> > > > > /* disable speaker when hp jack is inserted */
> > > > > .mask   = SND_JACK_HEADPHONE,
> > > > > .invert = 1,
> > > > > },
>
> > > > Hm some ASoC thingie. No idea what that is, but I suppose another
> > > > place where a subsystem for legacy reasons try to do the gpiolib
> > > > inversion on it's own accord. That one isn't flagged as active low in 
> > > > the
> > > > descriptor so it's fine I guess.
>
> > > It's saying that when the headphone is inserted the headphone output
> > > should be enabled and the speaker output should be disabled, and vice
> > > versa.
>
> > Ok, that sounds like I should remove the flag here if I declare the
> > GPIO line as GPIO_ACTIVE_LOW instead of GPIO_ACTIVE_HIGH, right?
>
> If you change the sense of the GPIO you'll need to flip the invert to
> the headphone instead of the speaker - whichever way round the GPIO
> sense is each of the pins should be taking the opposite sense from the
> GPIO state to the other.

Ok, I hope I got it this time:

- The hs_jack_gpio/"earphone-det" is declared as GPIO_ACTIVE_LOW,
with the ".invert" dropped in the snd_soc_jack_gpio definition to match

- "spk-sd" is declared as GPIO_ACTIVE_LOW, so both
  this and  "hp-driver" are enabled by setting the gpio to active, rather than
  the two being opposites

- snd_soc_jack_pin flips the 'invert' flag from speaker to headphone, since
  the "earphone-det" is now  reversed

- hx4700_spk_power() flips polarity when setting the output to match the
  GPIO_ACTIVE_LOW setting, but hx4700_hp_power() does not change.

Arnd

commit 20a9b05eff0488b78aa02c07f58654daa294069a
Author: Arnd Bergmann 
Date:   Wed Sep 11 14:27:13 2019 +0200

ARM: pxa: hx4700: use gpio descriptors for audio

The audio driver should not use a hardwired gpio number
from the header. Change it to use a lookup table.

Cc: Philipp Zabel 
Cc: Paul Parsons 
Acked-by: Mark Brown 
Acked-by: Robert Jarzmik 
Cc: alsa-de...@alsa-project.org
Signed-off-by: Arnd Bergmann 

diff --git a/arch/arm/mach-pxa/hx4700-pcmcia.c
b/arch/arm/mach-pxa/hx4700-pcmcia.c
index e8acbfc9ef6c..e2331dfe427d 100644
--- a/arch/arm/mach-pxa/hx4700-pcmcia.c
+++ b/arch/arm/mach-pxa/hx4700-pcmcia.c
@@ -10,7 +10,7 @@
 #include 

 #include 
-#include 
+#include "hx4700.h"

 #include 

diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 140a44cb2989..2ae06edf413c 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -41,7 +41,7 @@

 #include "pxa27x.h"
 #include "addr-map.h"
-#include 
+#include "hx4700.h"
 #include 

 #include 
@@ -834,6 +834,19 @@ static struct i2c_board_info i2c_board_info[]
__initdata = {
},
 };

+static struct gpiod_lookup_table hx4700_audio_gpio_table = {
+   .dev_id = "hx4700-audio",
+   .table = {
+   GPIO_LOOKUP("gpio-pxa", GPIO75_HX4700_EARPHONE_nDET,
+   "earphone-det", GPIO_ACTIVE_LOW),
+   GPIO_LOOKUP("gpio-pxa", GPIO92_HX4700_HP_DRIVER,
+   "hp-driver", GPIO_ACTIVE_HIGH),
+   GPIO_LOOKUP("gpio-pxa", GPIO107_HX4700_SPK_nSD,
+   "spk-sd", GPIO_ACTIVE_LOW),
+   { },
+   },
+};
+
 static struct platform_device audio = {
.name   = "hx4700-audio",
.id = -1,
@@ -895,6 +908,7 @@ static void __init hx4700_init(void)

gpiod_add_lookup_table(_gpiod_table);
gpiod_add_lookup_table(_vbus_gpiod_table);
+   gpiod_add_lookup_table(_audio_gpio_table);
platform_add_devices(devices, ARRAY_SIZE(devices));
pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup));

diff --git a/arch/arm/mach-pxa/include/mach/hx4700.h
b/arch/arm/mach-pxa/hx4700.h
similarity index 99%
rename from arch/arm/mach-pxa/include/mach/hx4700.h
rename to arch/arm/mach-pxa/hx4700.h
index 0c30e6d9c660..ce2db33989e1 100644
--- a/arch/arm/mach-pxa/include/mach/hx4700.h
+++ b/arch/arm/mach-pxa/hx4700.h
@@ -10,7 +10,7 @@

 #include 
 #include 
-#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */
+#include  /* PXA_NR_BUILTIN_GPIO */

 #define HX4700_ASIC3_GPIO_BASE PXA_NR_BUILTIN_GPIO
 #define HX4700_EGPIO_BASE  (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS)
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c
index 7334fac758de..e6473c50e512 100644
--- a/sound/soc/pxa/hx4700.c
+++ 

Re: [PATCH] drm/nouveau: reorder nouveau_drm_device_fini

2022-05-05 Thread Lyude Paul
Hmm, I think we might just need to move the drm_kms_helper_poll_enable() call
to the end here instead of all of nouveau_display_init(). I realized this
because in nouveau_display_init() it seems that we actually rely on
nouveau_display_init() to setup hotplug interrupts - which we do actually need
this early on in the driver probe process.

That being said though, drm_kms_helper_poll_enable() shouldn't be required for
MST short HPD IRQs from working so moving that instead should work.

On Wed, 2022-05-04 at 19:18 +0200, Mark Menzynski wrote:
> Resources needed for output poll workers are destroyed in
> nouveau_fbcon_fini() before output poll workers are cleared in
> nouveau_display_fini(). This means there is a time between fbcon_fini
> and display_fini, where if output poll happens, it crashes.
> 
> BUG: KASAN: use-after-free in
> __drm_fb_helper_initial_config_and_unlock.cold+0x1f3/0x291
> [drm_kms_helper]
> 
> Cc: Ben Skeggs 
> Cc: Karol Herbst 
> Cc: Lyude Paul 
> Cc: David Airlie 
> Cc: Daniel Vetter 
> Cc: Sumit Semwal 
> Cc: "Christian König" 
> Cc: dri-devel@lists.freedesktop.org
> Cc: nouv...@lists.freedesktop.org
> Cc: linux-ker...@vger.kernel.org
> Cc: linux-me...@vger.kernel.org
> Cc: linaro-mm-...@lists.linaro.org
> Signed-off-by: Mark Menzynski 
> ---
>  drivers/gpu/drm/nouveau/nouveau_drm.c | 17 -
>  1 file changed, 8 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c
> b/drivers/gpu/drm/nouveau/nouveau_drm.c
> index 561309d447e0..773efdd20d2f 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drm.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
> @@ -588,12 +588,6 @@ nouveau_drm_device_init(struct drm_device *dev)
> if (ret)
> goto fail_dispctor;
>  
> -   if (dev->mode_config.num_crtc) {
> -   ret = nouveau_display_init(dev, false, false);
> -   if (ret)
> -   goto fail_dispinit;
> -   }
> -
> nouveau_debugfs_init(drm);
> nouveau_hwmon_init(dev);
> nouveau_svm_init(drm);
> @@ -601,6 +595,12 @@ nouveau_drm_device_init(struct drm_device *dev)
> nouveau_fbcon_init(dev);
> nouveau_led_init(dev);
>  
> +   if (dev->mode_config.num_crtc) {
> +   ret = nouveau_display_init(dev, false, false);
> +   if (ret)
> +   goto fail_dispinit;
> +   }
> +
> if (nouveau_pmops_runtime()) {
> pm_runtime_use_autosuspend(dev->dev);
> pm_runtime_set_autosuspend_delay(dev->dev, 5000);
> @@ -641,15 +641,14 @@ nouveau_drm_device_fini(struct drm_device *dev)
> pm_runtime_forbid(dev->dev);
> }
>  
> +   if (dev->mode_config.num_crtc)
> +   nouveau_display_fini(dev, false, false);
> nouveau_led_fini(dev);
> nouveau_fbcon_fini(dev);
> nouveau_dmem_fini(drm);
> nouveau_svm_fini(drm);
> nouveau_hwmon_fini(dev);
> nouveau_debugfs_fini(drm);
> -
> -   if (dev->mode_config.num_crtc)
> -   nouveau_display_fini(dev, false, false);
> nouveau_display_destroy(dev);
>  
> nouveau_accel_fini(drm);

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



Re: [v2,3/4] drm/i915/huc: Prepare for GSC-loaded HuC

2022-05-05 Thread Teres Alexis, Alan Previn
Because i reviewed this already and the only new change is the relocation
of the function "huc_is_authenticated()" from Patch 1 to this patch while
maintaining the same logic as rev-1, thus:

Acked-by: Alan Previn 


On Wed, 2022-05-04 at 13:48 -0700, Daniele Ceraolo Spurio wrote:
> HuC loading via GSC is performed via a PXP command sent through the mei
> modules, so we need both MEI_GSC and MEI_PXP to be available. Given that
> the GSC will do both the transfer and the authentication, the legacy HuC
> loading paths can be safely skipped.
> Also note that the GSC-loaded HuC survives GT reset.
> 
> v2: move the huc_is_authenticated() function to this patch.
> 
> Signed-off-by: Daniele Ceraolo Spurio 
> Reviewed-by: Alan Previn  #v1
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h |  1 +
>  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 95 ++
>  drivers/gpu/drm/i915/gt/uc/intel_huc.h |  6 ++
>  drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c  |  5 +-
>  drivers/gpu/drm/i915/gt/uc/intel_uc.c  | 11 ++-
>  5 files changed, 100 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
> index 66027a42cda9e..2516705b9f365 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
> @@ -96,6 +96,7 @@
>  
>  #define GUC_SHIM_CONTROL2_MMIO(0xc068)
>  #define   GUC_IS_PRIVILEGED  (1<<29)
> +#define   GSC_LOADS_HUC  (1<<30)
>  
>  #define GUC_SEND_INTERRUPT   _MMIO(0xc4c8)
>  #define   GUC_SEND_TRIGGER (1<<0)
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
> b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> index 7b759b99cf3c8..c36e2bf9b0f29 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> @@ -6,6 +6,7 @@
>  #include 
>  
>  #include "gt/intel_gt.h"
> +#include "intel_guc_reg.h"
>  #include "intel_huc.h"
>  #include "i915_drv.h"
>  
> @@ -17,11 +18,15 @@
>   * capabilities by adding HuC specific commands to batch buffers.
>   *
>   * The kernel driver is only responsible for loading the HuC firmware and
> - * triggering its security authentication, which is performed by the GuC. For
> - * The GuC to correctly perform the authentication, the HuC binary must be
> - * loaded before the GuC one. Loading the HuC is optional; however, not using
> - * the HuC might negatively impact power usage and/or performance of media
> - * workloads, depending on the use-cases.
> + * triggering its security authentication, which is performed by the GuC on
> + * older platforms and by the GSC on newer ones. For the GuC to correctly
> + * perform the authentication, the HuC binary must be loaded before the GuC 
> one.
> + * Loading the HuC is optional; however, not using the HuC might negatively
> + * impact power usage and/or performance of media workloads, depending on the
> + * use-cases.
> + * HuC must be reloaded on events that cause the WOPCM to lose its contents
> + * (S3/S4, FLR); GuC-authenticated HuC must also be reloaded on GuC/GT reset,
> + * while GSC-managed HuC will survive that.
>   *
>   * See https://github.com/intel/media-driver for the latest details on HuC
>   * functionality.
> @@ -54,11 +59,51 @@ void intel_huc_init_early(struct intel_huc *huc)
>   }
>  }
>  
> +#define HUC_LOAD_MODE_STRING(x) (x ? "GSC" : "legacy")
> +static int check_huc_loading_mode(struct intel_huc *huc)
> +{
> + struct intel_gt *gt = huc_to_gt(huc);
> + bool fw_needs_gsc = intel_huc_is_loaded_by_gsc(huc);
> + bool hw_uses_gsc = false;
> +
> + /*
> +  * The fuse for HuC load via GSC is only valid on platforms that have
> +  * GuC deprivilege.
> +  */
> + if (HAS_GUC_DEPRIVILEGE(gt->i915))
> + hw_uses_gsc = intel_uncore_read(gt->uncore, GUC_SHIM_CONTROL2) &
> +   GSC_LOADS_HUC;
> +
> + if (fw_needs_gsc != hw_uses_gsc) {
> + drm_err(>i915->drm,
> + "mismatch between HuC FW (%s) and HW (%s) load modes\n",
> + HUC_LOAD_MODE_STRING(fw_needs_gsc),
> + HUC_LOAD_MODE_STRING(hw_uses_gsc));
> + return -ENOEXEC;
> + }
> +
> + /* make sure we can access the GSC via the mei driver if we need it */
> + if (!(IS_ENABLED(CONFIG_INTEL_MEI_PXP) && 
> IS_ENABLED(CONFIG_INTEL_MEI_GSC)) &&
> + fw_needs_gsc) {
> + drm_info(>i915->drm,
> +  "Can't load HuC due to missing MEI modules\n");
> + return -EIO;
> + }
> +
> + drm_dbg(>i915->drm, "GSC loads huc=%s\n", str_yes_no(fw_needs_gsc));
> +
> + return 0;
> +}
> +
>  int intel_huc_init(struct intel_huc *huc)
>  {
>   struct drm_i915_private *i915 = huc_to_gt(huc)->i915;
>   int err;
>  
> + err = check_huc_loading_mode(huc);
> + if (err)
> + goto out;
> +
>   err = intel_uc_fw_init(>fw);
>

Re: [v2,1/4] drm/i915/huc: drop intel_huc_is_authenticated

2022-05-05 Thread Teres Alexis, Alan Previn
Reviewed-by: Alan Previn 

On Wed, 2022-05-04 at 13:48 -0700, Daniele Ceraolo Spurio wrote:
> The fuction name is confusing, because it doesn't check the actual auth
> status in HW but the SW status. Given that there is only one user (the
> huc_auth function itself), just get rid of it and use the FW status
> checker directly.
> 
> Signed-off-by: Daniele Ceraolo Spurio 
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 2 +-
>  drivers/gpu/drm/i915/gt/uc/intel_huc.h | 5 -
>  2 files changed, 1 insertion(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
> b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> index 556829de9c172..7b759b99cf3c8 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> @@ -96,7 +96,7 @@ int intel_huc_auth(struct intel_huc *huc)
>   struct intel_guc *guc = >uc.guc;
>   int ret;
>  
> - GEM_BUG_ON(intel_huc_is_authenticated(huc));
> + GEM_BUG_ON(intel_uc_fw_is_running(>fw));
>  
>   if (!intel_uc_fw_is_loaded(>fw))
>   return -ENOEXEC;
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h 
> b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
> index 73ec670800f2b..77d813840d76c 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
> @@ -50,11 +50,6 @@ static inline bool intel_huc_is_used(struct intel_huc *huc)
>   return intel_uc_fw_is_available(>fw);
>  }
>  
> -static inline bool intel_huc_is_authenticated(struct intel_huc *huc)
> -{
> - return intel_uc_fw_is_running(>fw);
> -}
> -
>  void intel_huc_load_status(struct intel_huc *huc, struct drm_printer *p);
>  
>  #endif



Re: [PATCH] drm: Document that power requirements for DP AUX transfers

2022-05-05 Thread Lyude Paul
So I think if Ville is OK with it (an ack at least) I'm fine with this
documentation change. I think it's worth me noting for other reviewers I made
this decision based on the fact that the documentation is for the transfer()
function - which I agree shouldn't need to be responsible for powering the
panel on.

Since that doesn't actually specify what we expect the behavior for userspace
accesses to be (since we could in theory add more behavior in those codepaths
around the transfer() calls that don't exist for the driver's own AUX usages)
I think this is totally fine

Reviewed-by: Lyude Paul 

On Tue, 2022-05-03 at 16:21 -0700, Douglas Anderson wrote:
> When doing DP AUX transfers there are two actors that need to be
> powered in order for the DP AUX transfer to work: the DP source and
> the DP sync. Commit bacbab58f09d ("drm: Mention the power state
> requirement on side-channel operations") added some documentation
> saying that the DP source is required to power itself up (if needed)
> to do AUX transfers. However, that commit doesn't talk anything about
> the DP sink.
> 
> For full fledged DP the sink isn't really a problem. It's expected
> that if an external DP monitor isn't plugged in that attempting to do
> AUX transfers won't work. It's also expected that if a DP monitor is
> plugged in (and thus asserting HPD) that it AUX transfers will work.
> 
> When we're looking at eDP, however, things are less obvious. Let's add
> some documentation about expectations. Here's what we'll say:
> 
> 1. We don't expect the DP AUX transfer function to power on an eDP
> panel. If an eDP panel is physically connected but powered off then it
> makes sense for the transfer to fail.
> 
> 2. We'll document that the official way to power on a panel is via the
> bridge chain, specifically by making sure that the panel's prepare
> function has been called (which is called by
> panel_bridge_pre_enable()). It's already specified in the kernel doc
> of drm_panel_prepare() that this is the way to power the panel on and
> also that after this call "it is possible to communicate with any
> integrated circuitry via a command bus."
> 
> 3. We'll also document that for code running in the panel driver
> itself that it is legal for the panel driver to power itself up
> however it wants (it doesn't need to officially call
> drm_panel_pre_enable()) and then it can do AUX bus transfers. This is
> currently the way that edp-panel works when it's running atop the DP
> AUX bus.
> 
> Signed-off-by: Douglas Anderson 
> ---
> 
>  include/drm/display/drm_dp_helper.h | 14 +++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/include/drm/display/drm_dp_helper.h
> b/include/drm/display/drm_dp_helper.h
> index dca40a045dd6..e5165b708a40 100644
> --- a/include/drm/display/drm_dp_helper.h
> +++ b/include/drm/display/drm_dp_helper.h
> @@ -370,9 +370,17 @@ struct drm_dp_aux {
>  * helpers assume this is the case.
>  *
>  * Also note that this callback can be called no matter the
> -    * state @dev is in. Drivers that need that device to be powered
> -    * to perform this operation will first need to make sure it's
> -    * been properly enabled.
> +    * state @dev is in and also no matter what state the panel is
> +    * in. It's expected:
> +    * - If the @dev providing the AUX bus is currently unpowered then
> +    *   it will power itself up for the transfer.
> +    * - If we're on eDP and the panel is not in a state where it can
> +    *   respond (it's not powered or it's in a low power state) then
> this
> +    *   function will return an error (but not crash). Note that if a
> +    *   panel driver is initiating a DP AUX transfer it may power
> itself
> +    *   up however it wants. All other code should ensure that the
> +    *   pre_enable() bridge chain (which eventually calls the panel
> +    *   prepare function) has powered the panel.
>  */
> ssize_t (*transfer)(struct drm_dp_aux *aux,
>     struct drm_dp_aux_msg *msg);

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



Re: [PATCH 1/2] drm/probe-helper: Add helper for drm_helper_probe_single_connector_modes()

2022-05-05 Thread Doug Anderson
Hi,

On Thu, May 5, 2022 at 11:34 AM Thomas Zimmermann  wrote:
>
> Hi
>
> Am 26.04.22 um 20:46 schrieb Douglas Anderson:
> > The drm_helper_probe_single_connector_modes() is a bit long. Let's
> > break a chunk off to update and validate modes. This helps avoid one
> > goto and also will allow us to more easily call the helper a second
> > time in a future patch without adding looping or another goto.
> >
> > This change is intended to be a no-op change--just code movement.
> >
> > Signed-off-by: Douglas Anderson 
>
>
> > ---
> >
> >   drivers/gpu/drm/drm_probe_helper.c | 105 -
> >   1 file changed, 59 insertions(+), 46 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> > b/drivers/gpu/drm/drm_probe_helper.c
> > index 682359512996..819225629010 100644
> > --- a/drivers/gpu/drm/drm_probe_helper.c
> > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > @@ -354,6 +354,61 @@ drm_helper_probe_detect(struct drm_connector 
> > *connector,
> >   }
> >   EXPORT_SYMBOL(drm_helper_probe_detect);
> >
> > +static bool _drm_helper_update_and_validate(struct drm_connector 
> > *connector,
>
> AFAIK convention is to use two underscores for internal names.

Sure! I'll spin with this.


> > + uint32_t maxX, uint32_t maxY,
> > + struct drm_modeset_acquire_ctx 
> > *ctx)
> > +{
> > + struct drm_device *dev = connector->dev;
> > + struct drm_display_mode *mode;
> > + int mode_flags = 0;
> > + int ret;
> > +
> > + drm_connector_list_update(connector);
> > +
> > + if (connector->interlace_allowed)
> > + mode_flags |= DRM_MODE_FLAG_INTERLACE;
> > + if (connector->doublescan_allowed)
> > + mode_flags |= DRM_MODE_FLAG_DBLSCAN;
> > + if (connector->stereo_allowed)
> > + mode_flags |= DRM_MODE_FLAG_3D_MASK;
> > +
> > + list_for_each_entry(mode, >modes, head) {
> > + if (mode->status != MODE_OK)
> > + continue;
> > +
> > + mode->status = drm_mode_validate_driver(dev, mode);
> > + if (mode->status != MODE_OK)
> > + continue;
> > +
> > + mode->status = drm_mode_validate_size(mode, maxX, maxY);
> > + if (mode->status != MODE_OK)
> > + continue;
> > +
> > + mode->status = drm_mode_validate_flag(mode, mode_flags);
> > + if (mode->status != MODE_OK)
> > + continue;
> > +
> > + ret = drm_mode_validate_pipeline(mode, connector, ctx,
> > +  >status);
> > + if (ret) {
> > + drm_dbg_kms(dev,
> > + "drm_mode_validate_pipeline failed: %d\n",
> > + ret);
> > +
> > + if (drm_WARN_ON_ONCE(dev, ret != -EDEADLK))
> > + mode->status = MODE_ERROR;
> > + else
> > + return true;
>
> Returning true is non-intuitive. It looks as if we report success when
> it actually signals a retry.
>
> I suggest to return 'ret' here and let the caller decide. On success at
> the end of the function, it would return 0 as usual.

There's a madness to my method. I originally had it returning "ret"
but then I felt like the callers now needed to handle three cases:

a) ret = -EDEADLK
b) ret = 0
c) ret = some other error

In reality _drm_helper_update_and_validate() never returned anything
other than a) or b), so adding the extra error handling for c) seemed
like a waste. ...but it also felt like if it violated the abstraction
of _drm_helper_update_and_validate() returning an error code if I
didn't handle c).

In any case, I'll change it back to an error code. Maybe a compromise would be:

ret = _drm_helper_update_and_validate(...)
if (ret == -EDEADLK) {
  drm_modeset_backoff(...)
  goto retry;
}
WARN_ON(ret);

...so we at least document that ret can only be one of the two values
and we'll get a warning splat if it ever happens, but we don't need to
add complex error handling for a case that the code can't hit. Ah,
looking above I guess that matches what the function does earlier too.

OK, I'll give a few more days for feedback on this series and I'll
spin with the two changes you've requested.

-Doug

-Doug


Re: [PATCH] drm: Document that power requirements for DP AUX transfers

2022-05-05 Thread Ville Syrjälä
On Thu, May 05, 2022 at 08:53:12AM -0700, Doug Anderson wrote:
> Hi,
> 
> On Thu, May 5, 2022 at 8:29 AM Ville Syrjälä
>  wrote:
> >
> > On Thu, May 05, 2022 at 08:00:20AM -0700, Doug Anderson wrote:
> > > Hi,
> > >
> > > On Thu, May 5, 2022 at 7:46 AM Ville Syrjälä
> > >  wrote:
> > > >
> > > > On Wed, May 04, 2022 at 02:10:08PM -0400, Lyude Paul wrote:
> > > > > On Wed, 2022-05-04 at 09:04 -0700, Doug Anderson wrote:
> > > > > > Hi,
> > > > > >
> > > > > > On Wed, May 4, 2022 at 5:21 AM Ville Syrjälä
> > > > > >  wrote:
> > > > > > >
> > > > > > > On Tue, May 03, 2022 at 04:21:08PM -0700, Douglas Anderson wrote:
> > > > > > > > When doing DP AUX transfers there are two actors that need to be
> > > > > > > > powered in order for the DP AUX transfer to work: the DP source 
> > > > > > > > and
> > > > > > > > the DP sync. Commit bacbab58f09d ("drm: Mention the power state
> > > > > > > > requirement on side-channel operations") added some 
> > > > > > > > documentation
> > > > > > > > saying that the DP source is required to power itself up (if 
> > > > > > > > needed)
> > > > > > > > to do AUX transfers. However, that commit doesn't talk anything 
> > > > > > > > about
> > > > > > > > the DP sink.
> > > > > > > >
> > > > > > > > For full fledged DP the sink isn't really a problem. It's 
> > > > > > > > expected
> > > > > > > > that if an external DP monitor isn't plugged in that attempting 
> > > > > > > > to do
> > > > > > > > AUX transfers won't work. It's also expected that if a DP 
> > > > > > > > monitor is
> > > > > > > > plugged in (and thus asserting HPD) that it AUX transfers will 
> > > > > > > > work.
> > > > > > > >
> > > > > > > > When we're looking at eDP, however, things are less obvious. 
> > > > > > > > Let's add
> > > > > > > > some documentation about expectations. Here's what we'll say:
> > > > > > > >
> > > > > > > > 1. We don't expect the DP AUX transfer function to power on an 
> > > > > > > > eDP
> > > > > > > > panel. If an eDP panel is physically connected but powered off 
> > > > > > > > then it
> > > > > > > > makes sense for the transfer to fail.
> > > > > > >
> > > > > > > I don't agree with this. I think the panel should just get powred 
> > > > > > > up
> > > > > > > for AUX transfers.
> > > > > >
> > > > > > That's definitely a fair thing to think about and I have at times
> > > > > > thought about trying to make it work that way. It always ends up
> > > > > > hitting a roadblock.
> > > >
> > > > How do you even probe the panel initially if you can't power it on
> > > > without doing some kind of full modeset/etc.?
> > >
> > > It's not that we can't power it on without a full modeset. It' that at
> > > panel probe time all the DRM components haven't been hooked together
> > > yet, so the bridge chain isn't available yet. The panel can power
> > > itself on, though. This is why the documentation I added says: "if a
> > > panel driver is initiating a DP AUX transfer it may power itself up
> > > however it wants"
> > >
> > >
> > > > > > The biggest roadblock that I recall is that to make this work then
> > > > > > you'd have to somehow ensure that the bridge chain's pre_enable() 
> > > > > > call
> > > > > > was made as part of the AUX transfer, right? Since the transfer
> > > > > > function can be called in any context at all, we have to coordinate
> > > > > > this with DRM. If, for instance, DRM is mid way through powering the
> > > > > > panel down then we need to wait for DRM to fully finish powering 
> > > > > > down,
> > > > > > then we need to power the panel back up. I don't believe that we can
> > > > > > just force the panel to stay on if DRM is turning it off because of
> > > > > > panel power sequencing requirements. At least I know it would have 
> > > > > > the
> > > > > > potential to break "samsung-atna33xc20.c" which absolutely needs to
> > > > > > see the panel power off after it's been disabled.
> > > > > >
> > > > > > We also, I believe, need to handle the fact that the bridge chain 
> > > > > > may
> > > > > > not have even been created yet. We do AUX transfers to read the EDID
> > > > > > and also to setup the backlight in the probe function of panel-edp. 
> > > > > > At
> > > > > > that point the panel hasn't been linked into the chain. We had 
> > > > > > _long_
> > > > > > discussions [1] about moving these out of probe and decided that we
> > > > > > could move the EDID read to be later but that it was going to really
> > > > > > ugly to move the AUX backlight later. The backlight would end up
> > > > > > popping up at some point in time later (the first call to panel
> > > > > > prepare() or maybe get_modes()) and that seemed weird.
> > > > > >
> > > > > > [1]
> > > > > > https://lore.kernel.org/lkml/CAD=FV=u5-stdlydkejwlaog-0wgxr49vxtwuyuo7z2puibl...@mail.gmail.com/
> > > > > >
> > > > > >
> > > > > > > Otherwise you can't trust that eg. the /dev/aux
> > > > > > > stuff is actually usable.
> > > > > >
> > > > > > Yeah, it's been on my mind to talk 

Re: [PATCH] drm/nouveau/gr/gf100-: Clean up some inconsistent indenting

2022-05-05 Thread Lyude Paul
Thanks!

Reviewed-by: Lyude Paul 

Will push upstream in a moment

On Thu, 2022-05-05 at 16:13 +0800, Jiapeng Chong wrote:
> Eliminate the follow smatch warning:
> 
> drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c:1925
> gf100_gr_oneinit_tiles() warn: inconsistent indenting.
> 
> Reported-by: Abaci Robot 
> Signed-off-by: Jiapeng Chong 
> ---
>  drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
> b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
> index 397ff4fe9df8..f16eabf4f642 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
> @@ -1922,8 +1922,8 @@ gf100_gr_oneinit_tiles(struct gf100_gr *gr)
>  
> for (i = 0; i < gr->gpc_nr; i++) {
> init_frac[i] = gr->tpc_nr[gpc_map[i]] * gr->gpc_nr *
> mul_factor;
> -    init_err[i] = i * gr->tpc_max * mul_factor - comm_denom/2;
> - run_err[i] = init_frac[i] + init_err[i];
> +   init_err[i] = i * gr->tpc_max * mul_factor - comm_denom/2;
> +   run_err[i] = init_frac[i] + init_err[i];
> }
>  
> for (i = 0; i < gr->tpc_total;) {

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



[Bug 201957] amdgpu: ring gfx timeout

2022-05-05 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=201957

--- Comment #69 from Danil (s48g...@gmail.com) ---
Edit - got freeze after using PC for 4 hours, before it was 20 min longest time
I could use integrated GPU, so it not fixed completely look like, just some
improvement(or I just got lucky)... im back to use Discrete GPU.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

RE: [PATCH 1/2] dt-bindings: msm/dp: List supplies in the bindings

2022-05-05 Thread Stephen Boyd
Quoting Sankeerth Billakanti (QUIC) (2022-05-05 11:47:20)
> >Quoting Sankeerth Billakanti (2022-05-05 11:02:36)
> >>
> >> Our internal power grid documents list the regulators as VDD_A_*_1P2
> >> and VDD_A_*_0P9 for all the platforms.
> >
> >Do your internal power grid documents indicate what these supplies are
> >powering? The question is if these supplies power any of the logic inside the
> >eDP controller or if they only supply power to the analog circuits in the eDP
> >phy. If it's the eDP phy only then the regulator usage in the eDP driver 
> >should
> >be removed. I would suspect this is the case because the controller is
> >probably all digital logic and runs at the typical 1.8V that the rest of the 
> >SoC
> >uses. Similarly, these are voltage references which sound like a PLL 
> >reference
> >voltage.
> >
> >Please clarify this further.
> >
>
> For the DP driver using the usb-dp combo phy, there were cases where the usb 
> driver
> was turning off the phy and pll regulators whenever usb-dp concurrent mode 
> need not be supported.
> This caused phy and pll to be powered down causing aux transaction failures 
> and display blankouts.
> From then on, it became a practice for the controller driver to vote for the 
> phy and pll regulators also.
>

That sounds like USB-DP combo phy driver had improper regulator power
management where aux transactions from DP didn't keep the power on to
the phy. Where does the power physically go? If the power isn't
physically going to the DP controller it shouldn't be controlled from
the DP controller driver. If the aux bus needs the DP phy enabled, the
DP controller driver should enable the phy power (via phy_power_on()?).


Re: [PATCH v2] drm/i915/guc: Support programming the EU priority in the GuC descriptor

2022-05-05 Thread John Harrison

On 5/4/2022 16:46, Daniele Ceraolo Spurio wrote:

From: Matthew Brost 

In GuC submission mode the EU priority must be updated by the GuC rather
than the driver as the GuC owns the programming of the context descriptor.

Given that the GuC code uses the GuC priorities, we can't use a generic
function using i915 priorities for both execlists and GuC submission.
The existing function has therefore been pushed to the execlists
back-end while a new one has been added for GuC.

v2: correctly use the GuC prio.

Cc: John Harrison 
Cc: Matt Roper 
Signed-off-by: Matthew Brost 
Signed-off-by: Aravind Iddamsetty 
Signed-off-by: Daniele Ceraolo Spurio 

Reviewed-by: John Harrison 


---
  .../drm/i915/gt/intel_execlists_submission.c  | 12 +-
  drivers/gpu/drm/i915/gt/intel_lrc.h   | 10 -
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 22 +++
  3 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 86f7a9ac1c394..2b0266cab66b9 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -661,6 +661,16 @@ static inline void execlists_schedule_out(struct 
i915_request *rq)
i915_request_put(rq);
  }
  
+static u32 map_i915_prio_to_lrc_desc_prio(int prio)

+{
+   if (prio > I915_PRIORITY_NORMAL)
+   return GEN12_CTX_PRIORITY_HIGH;
+   else if (prio < I915_PRIORITY_NORMAL)
+   return GEN12_CTX_PRIORITY_LOW;
+   else
+   return GEN12_CTX_PRIORITY_NORMAL;
+}
+
  static u64 execlists_update_context(struct i915_request *rq)
  {
struct intel_context *ce = rq->context;
@@ -669,7 +679,7 @@ static u64 execlists_update_context(struct i915_request *rq)
  
  	desc = ce->lrc.desc;

if (rq->engine->flags & I915_ENGINE_HAS_EU_PRIORITY)
-   desc |= lrc_desc_priority(rq_prio(rq));
+   desc |= map_i915_prio_to_lrc_desc_prio(rq_prio(rq));
  
  	/*

 * WaIdleLiteRestore:bdw,skl
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.h 
b/drivers/gpu/drm/i915/gt/intel_lrc.h
index 31be734010db3..a390f0813c8b6 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.h
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.h
@@ -111,16 +111,6 @@ enum {
  #define XEHP_SW_COUNTER_SHIFT 58
  #define XEHP_SW_COUNTER_WIDTH 6
  
-static inline u32 lrc_desc_priority(int prio)

-{
-   if (prio > I915_PRIORITY_NORMAL)
-   return GEN12_CTX_PRIORITY_HIGH;
-   else if (prio < I915_PRIORITY_NORMAL)
-   return GEN12_CTX_PRIORITY_LOW;
-   else
-   return GEN12_CTX_PRIORITY_NORMAL;
-}
-
  static inline void lrc_runtime_start(struct intel_context *ce)
  {
struct intel_context_stats *stats = >stats;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 75291e9846c50..8bf8b6d588d43 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2394,6 +2394,26 @@ static int guc_context_policy_init(struct intel_context 
*ce, bool loop)
return ret;
  }
  
+static u32 map_guc_prio_to_lrc_desc_prio(u8 prio)

+{
+   /*
+* this matches the mapping we do in map_i915_prio_to_guc_prio()
+* (e.g. prio < I915_PRIORITY_NORMAL maps to GUC_CLIENT_PRIORITY_NORMAL)
+*/
+   switch (prio) {
+   default:
+   MISSING_CASE(prio);
+   fallthrough;
+   case GUC_CLIENT_PRIORITY_KMD_NORMAL:
+   return GEN12_CTX_PRIORITY_NORMAL;
+   case GUC_CLIENT_PRIORITY_NORMAL:
+   return GEN12_CTX_PRIORITY_LOW;
+   case GUC_CLIENT_PRIORITY_HIGH:
+   case GUC_CLIENT_PRIORITY_KMD_HIGH:
+   return GEN12_CTX_PRIORITY_HIGH;
+   }
+}
+
  static void prepare_context_registration_info(struct intel_context *ce,
  struct guc_ctxt_registration_info 
*info)
  {
@@ -2420,6 +2440,8 @@ static void prepare_context_registration_info(struct 
intel_context *ce,
 */
info->hwlrca_lo = lower_32_bits(ce->lrc.lrca);
info->hwlrca_hi = upper_32_bits(ce->lrc.lrca);
+   if (engine->flags & I915_ENGINE_HAS_EU_PRIORITY)
+   info->hwlrca_lo |= 
map_guc_prio_to_lrc_desc_prio(ce->guc_state.prio);
info->flags = CONTEXT_REGISTRATION_FLAG_KMD;
  
  	/*




RE: [PATCH 2/2] dt-bindings: phy: List supplies for qcom,edp-phy

2022-05-05 Thread Sankeerth Billakanti (QUIC)
>We're supposed to list the supplies in the dt bindings but there are none in
>the eDP PHY bindings.
>
>Looking at the driver in Linux, I can see that there seem to be two relevant
>supplies: "vdda-phy" and "vdda-pll". Let's add those to the bindings.
>
>NOTE: from looking at the Qualcomm datasheet for sc7280, it's not
>immediately clear how to figure out how to fill in these supplies. The only two
>eDP related supplies are simply described as "power for eDP 0.9V circuits" and
>"power for eDP 1.2V circuits". From guessing and from comparing how a
>similar PHY is hooked up on other similar Qualcomm boards, I'll make the
>educated guess that the 1.2V supply goes to "vdda-phy" and the 0.9V supply
>goes to "vdda-pll" and I'll use that in the example here.
>
>Signed-off-by: Douglas Anderson 
>---
>
> Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml | 6 ++
> 1 file changed, 6 insertions(+)
>
>diff --git a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
>b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
>index a5850ff529f8..cf9e9b8011cb 100644
>--- a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
>+++ b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
>@@ -41,6 +41,9 @@ properties:
>   "#phy-cells":
> const: 0
>
>+  vdda-phy-supply: true
>+  vdda-pll-supply: true
>+
> required:
>   - compatible
>   - reg
>@@ -65,5 +68,8 @@ examples:
>
>   #clock-cells = <1>;
>   #phy-cells = <0>;
>+
>+  vdda-phy-supply = <_a_edp_0_1p2>;
>+  vdda-pll-supply = <_a_edp_0_0p9>;
> };
> ...
>--
>2.36.0.rc2.479.g8af0fa9b8e-goog

Reviewed-by: Sankeerth Billakanti 


RE: [PATCH 1/2] dt-bindings: msm/dp: List supplies in the bindings

2022-05-05 Thread Sankeerth Billakanti (QUIC)
>Quoting Sankeerth Billakanti (2022-05-05 11:02:36)
>> >>
>> >> Quoting Douglas Anderson (2022-04-25 14:06:42)
>> >>
>> >> Having 'a' in 'vdda' typically means 'analog' for 'analog'
>> >> circuits, so I'd expect this to only matter for the phy that
>> >> contains the analog circuitry. It would be great to remove the
>> >> regulator code from drivers/gpu/drm/msm/dp/dp_power.c and move
>the
>> >> regulator_set_load() call to the phy driver if possible. Hopefully
>> >> qcom folks can help clarify here.
>> >
>> >Interesting. Oddly enough, the sc7280 datasheet doesn't list the "_A".
>> >It calls these "VDD_VREF_0P9" and "VDD_VREF_1P2". However, on the
>> >schematic in front of me someone labeled these pins on the sc7280
>> >with the "A". ...and the driver looks for a supply with the "a". :-/
>> >
>> >It would be good to get clarification from someone with better
>information.
>> >
>> >-Doug
>>
>> Our internal power grid documents list the regulators as VDD_A_*_1P2
>> and VDD_A_*_0P9 for all the platforms.
>
>Do your internal power grid documents indicate what these supplies are
>powering? The question is if these supplies power any of the logic inside the
>eDP controller or if they only supply power to the analog circuits in the eDP
>phy. If it's the eDP phy only then the regulator usage in the eDP driver should
>be removed. I would suspect this is the case because the controller is
>probably all digital logic and runs at the typical 1.8V that the rest of the 
>SoC
>uses. Similarly, these are voltage references which sound like a PLL reference
>voltage.
>
>Please clarify this further.
>

For the DP driver using the usb-dp combo phy, there were cases where the usb 
driver
was turning off the phy and pll regulators whenever usb-dp concurrent mode need 
not be supported.
This caused phy and pll to be powered down causing aux transaction failures and 
display blankouts. 
From then on, it became a practice for the controller driver to vote for the 
phy and pll regulators also.

>>
>> So, as a practice, we put the same name in the DT files. Hence,
>>
>> Reviewed-by: Sankeerth Billakanti 
>>


Re: [Intel-gfx] [PATCH] drm/i915/guc/slpc: Use non-blocking H2G for waitboost

2022-05-05 Thread John Harrison

On 5/5/2022 10:21, Belgaumkar, Vinay wrote:

On 5/5/2022 5:13 AM, Tvrtko Ursulin wrote:

On 05/05/2022 06:40, Vinay Belgaumkar wrote:

SLPC min/max frequency updates require H2G calls. We are seeing
timeouts when GuC channel is backed up and it is unable to respond
in a timely fashion causing warnings and affecting CI.


Is it the "Unable to force min freq" error? Do you have a link to the 
GitLab issue to add to commit message?
We don't have a specific error for this one, but have seen similar 
issues with other H2G which are blocking.



This is seen when waitboosting happens during a stress test.
this patch updates the waitboost path to use a non-blocking
H2G call instead, which returns as soon as the message is
successfully transmitted.


AFAIU with this approach, when CT channel is congested, you instead 
achieve silent dropping of the waitboost request, right?

We are hoping it makes it, but just not waiting for it to complete.
We are not 'hoping it makes it'. We know for a fact that it will make 
it. We just don't know when. The issue is not about whether the 
waitboost request itself gets dropped/lost it is about the ack that 
comes back. The GuC will process the message and it will send an ack. 
It's just a question of whether the i915 driver has given up waiting for 
it yet. And if it has, then you get the initial 'timed out waiting for 
ack' followed by a later 'got unexpected ack' message.


Whereas, if we make the call asynchronous, there is no ack. i915 doesn't 
bother waiting and it won't get surprised later.


Also, note that this is only an issue when GuC itself is backed up. 
Normally that requires the creation/destruction of large numbers of 
contexts in rapid succession (context management is about the slowest 
thing we do with GuC). Some of the IGTs and selftests do that with 
thousands of contexts all at once. Those are generally where we see this 
kind of problem. It would be highly unlikely (but not impossible) to hit 
it in real world usage.


The general design philosophy of H2G messages is that asynchronous mode 
should be used for everything if at all possible. It is fire and forget 
and will all get processed in the order sent (same as batch buffer 
execution, really). Synchronous messages should only be used when an 
ack/status is absolutely required. E.g. start of day initialisation or 
things like TLB invalidation where we need to know that a cache has been 
cleared/flushed before updating memory from the CPU.


John.




It sounds like a potentially important feedback from the field to 
lose so easily. How about you added drm_notice to the worker when it 
fails?


Or simply a "one line patch" to replace i915_probe_error (!?) with 
drm_notice and keep the blocking behavior. (I have no idea what is 
the typical time to drain the CT buffer, and so to decide whether 
waiting or dropping makes more sense for effectiveness of waitboosting.)


Or since the congestion /should not/ happen in production, then the 
argument is why complicate with more code, in which case going with 
one line patch is an easy way forward?


Even if we soften the blow here, the actual timeout error occurs in 
the intel_guc_ct.c code, so we cannot hide that error anyways. Making 
this call non-blocking will achieve both things.


Thanks,

Vinay.



Regards,

Tvrtko


Signed-off-by: Vinay Belgaumkar 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 38 
-

  1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c

index 1db833da42df..c852f73cf521 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
@@ -98,6 +98,30 @@ static u32 slpc_get_state(struct intel_guc_slpc 
*slpc)

  return data->header.global_state;
  }
  +static int guc_action_slpc_set_param_nb(struct intel_guc *guc, u8 
id, u32 value)

+{
+    u32 request[] = {
+    GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST,
+    SLPC_EVENT(SLPC_EVENT_PARAMETER_SET, 2),
+    id,
+    value,
+    };
+    int ret;
+
+    ret = intel_guc_send_nb(guc, request, ARRAY_SIZE(request), 0);
+
+    return ret > 0 ? -EPROTO : ret;
+}
+
+static int slpc_set_param_nb(struct intel_guc_slpc *slpc, u8 id, 
u32 value)

+{
+    struct intel_guc *guc = slpc_to_guc(slpc);
+
+    GEM_BUG_ON(id >= SLPC_MAX_PARAM);
+
+    return guc_action_slpc_set_param_nb(guc, id, value);
+}
+
  static int guc_action_slpc_set_param(struct intel_guc *guc, u8 id, 
u32 value)

  {
  u32 request[] = {
@@ -208,12 +232,10 @@ static int slpc_force_min_freq(struct 
intel_guc_slpc *slpc, u32 freq)

   */
    with_intel_runtime_pm(>runtime_pm, wakeref) {
-    ret = slpc_set_param(slpc,
- SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
- freq);
-    if (ret)
-    i915_probe_error(i915, "Unable to force min freq to %u: 
%d",

- freq, ret);
+    /* 

Re: [PATCH 1/2] drm/probe-helper: Add helper for drm_helper_probe_single_connector_modes()

2022-05-05 Thread Thomas Zimmermann

Hi

Am 26.04.22 um 20:46 schrieb Douglas Anderson:

The drm_helper_probe_single_connector_modes() is a bit long. Let's
break a chunk off to update and validate modes. This helps avoid one
goto and also will allow us to more easily call the helper a second
time in a future patch without adding looping or another goto.

This change is intended to be a no-op change--just code movement.

Signed-off-by: Douglas Anderson 




---

  drivers/gpu/drm/drm_probe_helper.c | 105 -
  1 file changed, 59 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index 682359512996..819225629010 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -354,6 +354,61 @@ drm_helper_probe_detect(struct drm_connector *connector,
  }
  EXPORT_SYMBOL(drm_helper_probe_detect);
  
+static bool _drm_helper_update_and_validate(struct drm_connector *connector,


AFAIK convention is to use two underscores for internal names.


+   uint32_t maxX, uint32_t maxY,
+   struct drm_modeset_acquire_ctx *ctx)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_display_mode *mode;
+   int mode_flags = 0;
+   int ret;
+
+   drm_connector_list_update(connector);
+
+   if (connector->interlace_allowed)
+   mode_flags |= DRM_MODE_FLAG_INTERLACE;
+   if (connector->doublescan_allowed)
+   mode_flags |= DRM_MODE_FLAG_DBLSCAN;
+   if (connector->stereo_allowed)
+   mode_flags |= DRM_MODE_FLAG_3D_MASK;
+
+   list_for_each_entry(mode, >modes, head) {
+   if (mode->status != MODE_OK)
+   continue;
+
+   mode->status = drm_mode_validate_driver(dev, mode);
+   if (mode->status != MODE_OK)
+   continue;
+
+   mode->status = drm_mode_validate_size(mode, maxX, maxY);
+   if (mode->status != MODE_OK)
+   continue;
+
+   mode->status = drm_mode_validate_flag(mode, mode_flags);
+   if (mode->status != MODE_OK)
+   continue;
+
+   ret = drm_mode_validate_pipeline(mode, connector, ctx,
+>status);
+   if (ret) {
+   drm_dbg_kms(dev,
+   "drm_mode_validate_pipeline failed: %d\n",
+   ret);
+
+   if (drm_WARN_ON_ONCE(dev, ret != -EDEADLK))
+   mode->status = MODE_ERROR;
+   else
+   return true;


Returning true is non-intuitive. It looks as if we report success when 
it actually signals a retry.


I suggest to return 'ret' here and let the caller decide. On success at 
the end of the function, it would return 0 as usual.


Best regards
Thomas


+   }
+
+   if (mode->status != MODE_OK)
+   continue;
+   mode->status = drm_mode_validate_ycbcr420(mode, connector);
+   }
+
+   return false;
+}
+
  /**
   * drm_helper_probe_single_connector_modes - get complete set of display modes
   * @connector: connector to probe
@@ -421,7 +476,6 @@ int drm_helper_probe_single_connector_modes(struct 
drm_connector *connector,
const struct drm_connector_helper_funcs *connector_funcs =
connector->helper_private;
int count = 0, ret;
-   int mode_flags = 0;
bool verbose_prune = true;
enum drm_connector_status old_status;
struct drm_modeset_acquire_ctx ctx;
@@ -519,52 +573,11 @@ int drm_helper_probe_single_connector_modes(struct 
drm_connector *connector,
   connector->status == connector_status_unknown))
count = drm_add_modes_noedid(connector, 1024, 768);
count += drm_helper_probe_add_cmdline_mode(connector);
-   if (count == 0)
-   goto prune;
-
-   drm_connector_list_update(connector);
-
-   if (connector->interlace_allowed)
-   mode_flags |= DRM_MODE_FLAG_INTERLACE;
-   if (connector->doublescan_allowed)
-   mode_flags |= DRM_MODE_FLAG_DBLSCAN;
-   if (connector->stereo_allowed)
-   mode_flags |= DRM_MODE_FLAG_3D_MASK;
-
-   list_for_each_entry(mode, >modes, head) {
-   if (mode->status != MODE_OK)
-   continue;
-
-   mode->status = drm_mode_validate_driver(dev, mode);
-   if (mode->status != MODE_OK)
-   continue;
-
-   mode->status = drm_mode_validate_size(mode, maxX, maxY);
-   if (mode->status != MODE_OK)
-   continue;
-
-   mode->status = drm_mode_validate_flag(mode, mode_flags);
-   if (mode->status != 

RE: [PATCH 1/2] dt-bindings: msm/dp: List supplies in the bindings

2022-05-05 Thread Stephen Boyd
Quoting Sankeerth Billakanti (2022-05-05 11:02:36)
> >>
> >> Quoting Douglas Anderson (2022-04-25 14:06:42)
> >>
> >> Having 'a' in 'vdda' typically means 'analog' for 'analog' circuits,
> >> so I'd expect this to only matter for the phy that contains the analog
> >> circuitry. It would be great to remove the regulator code from
> >> drivers/gpu/drm/msm/dp/dp_power.c and move the regulator_set_load()
> >> call to the phy driver if possible. Hopefully qcom folks can help
> >> clarify here.
> >
> >Interesting. Oddly enough, the sc7280 datasheet doesn't list the "_A".
> >It calls these "VDD_VREF_0P9" and "VDD_VREF_1P2". However, on the
> >schematic in front of me someone labeled these pins on the sc7280 with the
> >"A". ...and the driver looks for a supply with the "a". :-/
> >
> >It would be good to get clarification from someone with better information.
> >
> >-Doug
>
> Our internal power grid documents list the regulators as VDD_A_*_1P2 and 
> VDD_A_*_0P9
> for all the platforms.

Do your internal power grid documents indicate what these supplies are
powering? The question is if these supplies power any of the logic
inside the eDP controller or if they only supply power to the analog
circuits in the eDP phy. If it's the eDP phy only then the regulator
usage in the eDP driver should be removed. I would suspect this is the
case because the controller is probably all digital logic and runs at
the typical 1.8V that the rest of the SoC uses. Similarly, these are
voltage references which sound like a PLL reference voltage.

Please clarify this further.

>
> So, as a practice, we put the same name in the DT files. Hence,
>
> Reviewed-by: Sankeerth Billakanti 
>


Re: [PATCH] MAINTAINERS: Add simpledrm driver co-maintainer

2022-05-05 Thread Thomas Zimmermann



Am 05.05.22 um 19:26 schrieb Javier Martinez Canillas:

Thomas asked me to serve as co-maintainer for the simpledrm driver.

Signed-off-by: Javier Martinez Canillas 


Acked-by: Thomas Zimmermann 

Thanks for all the work you're doing, Javier.


---

  MAINTAINERS | 1 +
  1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1a04950c1a8f..bfe43560f9d5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6389,6 +6389,7 @@ F:include/uapi/drm/savage_drm.h
  
  DRM DRIVER FOR SIMPLE FRAMEBUFFERS

  M:Thomas Zimmermann 
+M: Javier Martinez Canillas 
  L:dri-devel@lists.freedesktop.org
  S:Maintained
  T:git git://anongit.freedesktop.org/drm/drm-misc


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


RE: [PATCH 1/2] dt-bindings: msm/dp: List supplies in the bindings

2022-05-05 Thread Sankeerth Billakanti
Hi Doug,

>>
>> Quoting Douglas Anderson (2022-04-25 14:06:42)
>> > We're supposed to list the supplies in the dt bindings but there are
>> > none in the DP controller bindings. Looking at the Linux driver and
>> > existing device trees, we can see that two supplies are expected:
>> > - vdda-0p9-supply
>> > - vdda-1p2-supply
>> >
>> > Let's list them both in the bindings. Note that the datasheet for
>> > sc7280 doesn't describe these supplies very verbosely. For the 0p9
>> > supply, for instance, it says "Power for eDP 0.9 V circuits". This
>> > this is obvious from the property name, we don't bother cluttering
>> > the bindings with a description.
>> >
>> > Signed-off-by: Douglas Anderson 
>> > ---
>> >
>> >  .../devicetree/bindings/display/msm/dp-controller.yaml  | 6 ++
>> >  1 file changed, 6 insertions(+)
>> >
>> > diff --git
>> > a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
>> > b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
>> > index cd05cfd76536..dba31108db51 100644
>> > ---
>> > a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
>> > +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.ya
>> > +++ ml
>> > @@ -76,6 +76,9 @@ properties:
>> >"#sound-dai-cells":
>> >  const: 0
>> >
>> > +  vdda-0p9-supply: true
>> > +  vdda-1p2-supply: true
>> > +
>> >ports:
>> >  $ref: /schemas/graph.yaml#/properties/ports
>> >  properties:
>> > @@ -137,6 +140,9 @@ examples:
>> >
>> >  power-domains = < SC7180_CX>;
>> >
>> > +vdda-0p9-supply = <_usb_ss_dp_core>;
>>
>> Having 'a' in 'vdda' typically means 'analog' for 'analog' circuits,
>> so I'd expect this to only matter for the phy that contains the analog
>> circuitry. It would be great to remove the regulator code from
>> drivers/gpu/drm/msm/dp/dp_power.c and move the regulator_set_load()
>> call to the phy driver if possible. Hopefully qcom folks can help
>> clarify here.
>
>Interesting. Oddly enough, the sc7280 datasheet doesn't list the "_A".
>It calls these "VDD_VREF_0P9" and "VDD_VREF_1P2". However, on the
>schematic in front of me someone labeled these pins on the sc7280 with the
>"A". ...and the driver looks for a supply with the "a". :-/
>
>It would be good to get clarification from someone with better information.
>
>-Doug

Our internal power grid documents list the regulators as VDD_A_*_1P2 and 
VDD_A_*_0P9
for all the platforms.

So, as a practice, we put the same name in the DT files. Hence,

Reviewed-by: Sankeerth Billakanti 

Thank you,
Sankeerth 


Re: [PATCH 1/5] dma-buf: cleanup dma_fence_unwrap selftest

2022-05-05 Thread Christian König

Am 05.05.22 um 15:29 schrieb Daniel Vetter:

On Wed, May 04, 2022 at 02:22:52PM +0200, Christian König wrote:

The selftests, fix the error handling, remove unused functions and stop
leaking memory in failed tests.

Signed-off-by: Christian König 
---
  drivers/dma-buf/st-dma-fence-unwrap.c | 40 +++
  1 file changed, 16 insertions(+), 24 deletions(-)

diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c 
b/drivers/dma-buf/st-dma-fence-unwrap.c
index 039f016b57be..59628add93f5 100644
--- a/drivers/dma-buf/st-dma-fence-unwrap.c
+++ b/drivers/dma-buf/st-dma-fence-unwrap.c
@@ -4,27 +4,19 @@
   * Copyright (C) 2022 Advanced Micro Devices, Inc.
   */
  
+#include 

+#include 
+#include 
  #include 
-#if 0
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#endif
  
  #include "selftest.h"
  
  #define CHAIN_SZ (4 << 10)
  
-static inline struct mock_fence {

+struct mock_fence {
struct dma_fence base;
spinlock_t lock;
-} *to_mock_fence(struct dma_fence *f) {
-   return container_of(f, struct mock_fence, base);
-}
+};
  
  static const char *mock_name(struct dma_fence *f)

  {
@@ -45,7 +37,8 @@ static struct dma_fence *mock_fence(void)
return NULL;
  
  	spin_lock_init(>lock);

-   dma_fence_init(>base, _ops, >lock, 0, 0);
+   dma_fence_init(>base, _ops, >lock,
+  dma_fence_context_alloc(1), 1);
  
  	return >base;

  }
@@ -113,7 +106,6 @@ static int sanitycheck(void *arg)
if (!chain)
return -ENOMEM;
  
-	dma_fence_signal(f);

dma_fence_put(chain);
return err;
  }
@@ -154,10 +146,10 @@ static int unwrap_array(void *arg)
err = -EINVAL;
}
  
-	dma_fence_signal(f1);

-   dma_fence_signal(f2);
+   dma_fence_put(f1);
+   dma_fence_put(f2);

I'm completely lost on why you add these _put() calls?


Because my five year old had a nightmare and I had not enough caffeine 
in my blood stream on the next morning.


Fixed in the next round.

Thanks,
Christian.


  The reference we
create all get transferred over to the container object, and that takes
care of releasing them.

The other bits with error handling and code cleanup all look good, and
dropping dma_fence_signal calls also makes sense. But this one I don't
get.
-Daniel


dma_fence_put(array);
-   return 0;
+   return err;
  }
  
  static int unwrap_chain(void *arg)

@@ -196,10 +188,10 @@ static int unwrap_chain(void *arg)
err = -EINVAL;
}
  
-	dma_fence_signal(f1);

-   dma_fence_signal(f2);
+   dma_fence_put(f1);
+   dma_fence_put(f2);
dma_fence_put(chain);
-   return 0;
+   return err;
  }
  
  static int unwrap_chain_array(void *arg)

@@ -242,10 +234,10 @@ static int unwrap_chain_array(void *arg)
err = -EINVAL;
}
  
-	dma_fence_signal(f1);

-   dma_fence_signal(f2);
+   dma_fence_put(f1);
+   dma_fence_put(f2);
dma_fence_put(chain);
-   return 0;
+   return err;
  }
  
  int dma_fence_unwrap(void)

--
2.25.1





Re: [PATCH] drm/stm: dsi: Enable wrapper glue regulator early

2022-05-05 Thread Marek Vasut

On 5/4/22 09:59, Raphael Gallais-Pou wrote:

Hi Marek,


Hi,

[...]


@@ -499,8 +512,16 @@ static int dw_mipi_dsi_stm_probe(struct platform_device 
*pdev)
}
  
  	dsi->hw_version = dsi_read(dsi, DSI_VERSION) & VERSION;

+
+   ret = dw_mipi_dsi_phy_regulator_on(dsi);
clk_disable_unprepare(pclk);
  
+	if (ret) {

+   DRM_ERROR("%s: Failed to enable wrapper regulator, ret=%d\n",
+ __func__, ret);
+   goto err_dsi_probe;
+   }
+


I have no problem until here. If I understand this correctly, it enables the 
regulator during all the life of the driver.

If you feel an urge to merge this patch into the Linux kernel, the st display 
team could gladly do it because it enables more hardware bridges. However 
another solution could be to rework a bit the regulator part of the driver so 
that you would have only device tree to change, introducing a 'reg-always-on' 
property.

This driver needs in fact a bit of a rework with the power management. A 
solution could be to move the regulator-related part in 
dw_mipi_dsi_stm_power_on/off() so that it is only activated when needed. Those 
functions would integrate the enabling of the regulator, the switch for the 
internal regulator, and eventually handle the PLL if it cannot lock when the 
regulator is off.

With the DT property, the power management would be only in the 
probe()/remove(). In that way the DSI bridges would have the logic they need to 
work.

Ultimately there is two possibilities :
  * You really need this patch to be merged asap
  * You are ok to wait until we send the solution described above

If you want to write those patches (each for DT and regulator), feel free to do 
it.

What do you think about it ?


Maybe a more generic question first -- is there a way to pull the data 
lanes to LP11 without enabling the regulator ?


Also note that you likely want to wait with this patch, there is likely 
soon going to be a discussion about how to handle all those different 
requirements for initial DSI LP states and clock needed by DSI bridges, 
encoding such policy into DT is not the right approach.


Re: [PATCH v2 00/20] drm/edid: CEA data block iterators, and more

2022-05-05 Thread Jani Nikula
On Thu, 05 May 2022, Ville Syrjälä  wrote:
> On Tue, May 03, 2022 at 12:23:45PM +0300, Jani Nikula wrote:
>> I've kind of lost track of the version numbers on some of the iterator
>> patches, but this is the next version (or mostly a resend) of
>> [1]. There's an additional rename patch for SCDS.
>> 
>> BR,
>> Jani.
>> 
>> 
>> [1] https://patchwork.freedesktop.org/series/102703/
>> 
>> 
>> Jani Nikula (19):
>>   drm/edid: reset display info in drm_add_edid_modes() for NULL edid
>>   drm/edid: rename HDMI Forum VSDB to SCDS
>>   drm/edid: clean up CTA data block tag definitions
>>   drm/edid: add iterator for EDID base and extension blocks
>>   drm/edid: add iterator for CTA data blocks
>>   drm/edid: clean up cea_db_is_*() functions
>>   drm/edid: convert add_cea_modes() to use cea db iter
>>   drm/edid: convert drm_edid_to_speaker_allocation() to use cea db iter
>>   drm/edid: convert drm_edid_to_sad() to use cea db iter
>>   drm/edid: convert drm_detect_hdmi_monitor() to use cea db iter
>>   drm/edid: convert drm_detect_monitor_audio() to use cea db iter
>>   drm/edid: convert drm_parse_cea_ext() to use cea db iter
>>   drm/edid: convert drm_edid_to_eld() to use cea db iter
>>   drm/edid: sunset the old unused cea data block iterators
>>   drm/edid: restore some type safety to cea_db_*() functions
>>   drm/edid: detect basic audio in all CEA extensions
>>   drm/edid: skip CTA extension scan in drm_edid_to_eld() just for CTA
>> rev
>>   drm/edid: sunset drm_find_cea_extension()
>> 
>> Lee Shawn C (1):
>>   drm/edid: check for HF-SCDB block
>
> All of the above patches look OK to me.
> Reviewed-by: Ville Syrjälä 

Thanks a bunch, pushed the lot to drm-misc-next.

BR,
Jani.


>
>>   drm/edid: detect color formats and CTA revision in all CTA extensions
>
> For this one I'm not entirely convinced the behavioural change
> for the no-CTA ext case is what we want. Replied to that one
> individually.
>
>> 
>>  drivers/gpu/drm/drm_edid.c | 799 +
>>  1 file changed, 458 insertions(+), 341 deletions(-)
>> 
>> -- 
>> 2.30.2

-- 
Jani Nikula, Intel Open Source Graphics Center


Re: [PATCH v2] drm/msm/mdp5: Return error code in mdp5_pipe_release when deadlock is detected

2022-05-05 Thread Jessica Zhang




On 5/5/2022 1:48 AM, Dmitry Baryshkov wrote:

On Thu, 5 May 2022 at 05:06, Rob Clark  wrote:


On Wed, May 4, 2022 at 6:55 PM Jessica Zhang  wrote:


mdp5_get_global_state runs the risk of hitting a -EDEADLK when acquiring
the modeset lock, but currently mdp5_pipe_release doesn't check for if
an error is returned. Because of this, there is a possibility of
mdp5_pipe_release hitting a NULL dereference error.

To avoid this, let's have mdp5_pipe_release check if
mdp5_get_global_state returns an error and propogate that error.

Changes since v1:
- Separated declaration and initialization of *new_state to avoid
   compiler warning
- Fixed some spelling mistakes in commit message



Note that mdp5_mixer_release() needs the same treatment.. one more comment below


Got it, will submit a fix for that.




Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c  | 15 +++
  drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h  |  2 +-
  drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 20 
  3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
index ba6695963aa6..97887a2be082 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
@@ -119,18 +119,23 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct 
drm_plane *plane,
 return 0;
  }

-void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe)
+int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe)
  {
 struct msm_drm_private *priv = s->dev->dev_private;
 struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
 struct mdp5_global_state *state = mdp5_get_global_state(s);
-   struct mdp5_hw_pipe_state *new_state = >hwpipe;
+   struct mdp5_hw_pipe_state *new_state;

 if (!hwpipe)
-   return;
+   return -EINVAL;


At least per the current code, !hwpipe is "normal".. I think that fits
the model of things like kfree(NULL), so lets make this just return 0


Especially since we release the r_hwpipe w/o additional check. And
r_hwpipe frequently is NULL.


Noted.

Thanks,
Jessica Zhang






+
+   if (IS_ERR(state))
+   return PTR_ERR(state);
+
+   new_state = >hwpipe;

 if (WARN_ON(!new_state->hwpipe_to_plane[hwpipe->idx]))
-   return;
+   return -EINVAL;

 DBG("%s: release from plane %s", hwpipe->name,
 new_state->hwpipe_to_plane[hwpipe->idx]->name);
@@ -141,6 +146,8 @@ void mdp5_pipe_release(struct drm_atomic_state *s, struct 
mdp5_hw_pipe *hwpipe)
 }

 new_state->hwpipe_to_plane[hwpipe->idx] = NULL;
+
+   return 0;
  }

  void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe)
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h
index 9b26d0761bd4..cca67938cab2 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h
@@ -37,7 +37,7 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct 
drm_plane *plane,
  uint32_t caps, uint32_t blkcfg,
  struct mdp5_hw_pipe **hwpipe,
  struct mdp5_hw_pipe **r_hwpipe);
-void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe 
*hwpipe);
+int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe);

  struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe,
 uint32_t reg_offset, uint32_t caps);
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index 228b22830970..979458482841 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -311,12 +311,24 @@ static int mdp5_plane_atomic_check_with_state(struct 
drm_crtc_state *crtc_state,
 mdp5_state->r_hwpipe = NULL;


-   mdp5_pipe_release(state->state, old_hwpipe);
-   mdp5_pipe_release(state->state, old_right_hwpipe);
+   ret = mdp5_pipe_release(state->state, old_hwpipe);
+   if (ret)
+   return ret;
+
+   ret = mdp5_pipe_release(state->state, old_right_hwpipe);
+   if (ret)
+   return ret;
+
 }
 } else {
-   mdp5_pipe_release(state->state, mdp5_state->hwpipe);
-   mdp5_pipe_release(state->state, mdp5_state->r_hwpipe);
+   ret = mdp5_pipe_release(state->state, mdp5_state->hwpipe);
+   if (ret)
+   return ret;
+
+   ret = mdp5_pipe_release(state->state, mdp5_state->r_hwpipe);
+   if (ret)
+   return ret;
+
 mdp5_state->hwpipe = 

Re: (subset) [PATCH 1/2] [RFC] regmap: Add bulk read/write callbacks into regmap_config

2022-05-05 Thread Marek Vasut

On 5/5/22 17:12, Mark Brown wrote:

On Sat, 30 Apr 2022 04:51:44 +0200, Marek Vasut wrote:

Currently the regmap_config structure only allows the user to implement
single element register read/write using .reg_read/.reg_write callbacks.
The regmap_bus already implements bulk counterparts of both, and is being
misused as a workaround for the missing bulk read/write callbacks in
regmap_config by a couple of drivers. To stop this misuse, add the bulk
read/write callbacks to regmap_config and call them from the regmap core
code.

[...]


Applied to

https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git for-next

Thanks!

[1/2] regmap: Add bulk read/write callbacks into regmap_config
   commit: d77e745613680c54708470402e2b623dcd769681


I was really hoping this would get a lot more review / comments before 
this is applied.


Re: [PATCH 2/2] drm/probe-helper: For DP, add 640x480 if all other modes are bad

2022-05-05 Thread Kuogee Hsieh



On 5/5/2022 10:20 AM, Abhinav Kumar wrote:

Hi Doug

On 5/5/2022 8:44 AM, Doug Anderson wrote:

Ville,

On Tue, Apr 26, 2022 at 11:47 AM Douglas Anderson 
 wrote:


As per Displayport spec section 5.2.1.2 ("Video Timing Format") says
that all detachable sinks shall support 640x480 @60Hz as a fail safe
mode.

A DP compliance test expected us to utilize the above fact when all
modes it presented to the DP source were not achievable. It presented
only modes that would be achievable with more lanes and/or higher
speeds than we had available and expected that when we couldn't do
that then we'd fall back to 640x480 even though it didn't advertise
this size.

In order to pass the compliance test (and also support any users who
might fall into a similar situation with their display), we need to
add 640x480 into the list of modes. However, we don't want to add
640x480 all the time. Despite the fact that the DP spec says all sinks
_shall support_ 640x480, they're not guaranteed to support it
_well_. Continuing to read the spec you can see that the display is
not required to really treat 640x480 equal to all the other modes. It
doesn't need to scale or anything--just display the pixels somehow for
failsafe purposes. It should also be noted that it's not hard to find
a display hooked up via DisplayPort that _doesn't_ support 640x480 at
all. The HP ZR30w screen I'm sitting in front of has a native DP port
and doesn't work at 640x480. I also plugged in a tiny 800x480 HDMI
display via a DP to HDMI adapter and that screen definitely doesn't
support 640x480.

As a compromise solution, let's only add the 640x480 mode if:
* We're on DP.
* All other modes have been pruned.

This acknowledges that 640x480 might not be the best mode to use but,
since sinks are _supposed_ to support it, we will at least fall back
to it if there's nothing else.

Note that we _don't_ add higher resolution modes like 1024x768 in this
case. We only add those modes for a failed EDID read where we have no
idea what's going on. In the case where we've pruned all modes then
instead we only want 640x480 which is the only defined "Fail Safe"
resolution.

This patch originated in response to Kuogee Hsieh's patch [1].

[1] 
https://lore.kernel.org/r/1650671124-14030-1-git-send-email-quic_khs...@quicinc.com


Signed-off-by: Douglas Anderson 
---

  drivers/gpu/drm/drm_probe_helper.c | 26 +-
  1 file changed, 21 insertions(+), 5 deletions(-)


I think this patch is fairly safe / non-controversial, but someone
suggested you might have an opinion on it and another patch I posted
recently [1] so I wanted to double-check. Just to be clear: I'm hoping
to land _both_ this patch and [1]. If you don't have an opinion,
that's OK too.

Abhinav: I think maybe you're happy with this now? Would you be
willing to give a Reviewed-by?


Yes, I have no concerns with this approach from DP spec standpoint and 
in addition, kuogee has tested this out and this does help us to pass 
the tests.


Although, I might be missing some historical context on why this is 
not already done.


But apart from that, LGTM. Hence,

Reviewed-by: Abhinav Kumar 
Tested-by: Kuogee Hsieh 


[1] 
https://lore.kernel.org/r/20220426132121.RFC.1.I31ec454f8d4ffce51a7708a8092f8a6f9c929092@changeid


-Doug


  1   2   3   >