[PATCH v3 1/1] drm/ttm: Fix COW check
KFD Thunk maps invisible VRAM BOs with PROT_NONE, MAP_PRIVATE. is_cow_mapping returns true for these mappings. Add a check for vm_flags & VM_WRITE to avoid mmap failures on private read-only or PROT_NONE mappings. v2: protect against mprotect making a mapping writable after the fact v3: update driver-specific vm_operations_structs Fixes: f91142c62161 ("drm/ttm: nuke VM_MIXEDMAP on BO mappings v3") Signed-off-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 3 ++- drivers/gpu/drm/nouveau/nouveau_gem.c| 3 ++- drivers/gpu/drm/radeon/radeon_gem.c | 3 ++- drivers/gpu/drm/ttm/ttm_bo_vm.c | 14 +- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | 1 + include/drm/ttm/ttm_bo_api.h | 4 6 files changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index b3404c43a911..1aa750a6a5d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -79,7 +79,8 @@ static const struct vm_operations_struct amdgpu_gem_vm_ops = { .fault = amdgpu_gem_fault, .open = ttm_bo_vm_open, .close = ttm_bo_vm_close, - .access = ttm_bo_vm_access + .access = ttm_bo_vm_access, + .mprotect = ttm_bo_vm_mprotect }; static void amdgpu_gem_object_free(struct drm_gem_object *gobj) diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 5b27845075a1..164ea564bb7a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -70,7 +70,8 @@ static const struct vm_operations_struct nouveau_ttm_vm_ops = { .fault = nouveau_ttm_fault, .open = ttm_bo_vm_open, .close = ttm_bo_vm_close, - .access = ttm_bo_vm_access + .access = ttm_bo_vm_access, + .mprotect = ttm_bo_vm_mprotect }; void diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 458f92a70887..c19ad07eb7b5 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -77,7 +77,8 @@ static const struct vm_operations_struct radeon_gem_vm_ops = { .fault = radeon_gem_fault, .open = ttm_bo_vm_open, .close = ttm_bo_vm_close, - .access = ttm_bo_vm_access + .access = ttm_bo_vm_access, + .mprotect = ttm_bo_vm_mprotect }; static void radeon_gem_object_free(struct drm_gem_object *gobj) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index f56be5bc0861..fb325bad5db6 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -542,17 +542,29 @@ int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr, } EXPORT_SYMBOL(ttm_bo_vm_access); +int ttm_bo_vm_mprotect(struct vm_area_struct *vma, unsigned long start, + unsigned long end, unsigned long newflags) +{ + /* Enforce no COW since would have really strange behavior with it. */ + if (is_cow_mapping(newflags) && (newflags & VM_WRITE)) + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL(ttm_bo_vm_mprotect); + static const struct vm_operations_struct ttm_bo_vm_ops = { .fault = ttm_bo_vm_fault, .open = ttm_bo_vm_open, .close = ttm_bo_vm_close, .access = ttm_bo_vm_access, + .mprotect = ttm_bo_vm_mprotect, }; int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo) { /* Enforce no COW since would have really strange behavior with it. */ - if (is_cow_mapping(vma->vm_flags)) + if (is_cow_mapping(vma->vm_flags) && (vma->vm_flags & VM_WRITE)) return -EINVAL; ttm_bo_get(bo); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c index e6b1f98ec99f..e4bf7dc99320 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c @@ -61,6 +61,7 @@ int vmw_mmap(struct file *filp, struct vm_area_struct *vma) .fault = vmw_bo_vm_fault, .open = ttm_bo_vm_open, .close = ttm_bo_vm_close, + .mprotect = ttm_bo_vm_mprotect, #ifdef CONFIG_TRANSPARENT_HUGEPAGE .huge_fault = vmw_bo_vm_huge_fault, #endif diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index f681bbdbc698..40eb95875355 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -605,6 +605,10 @@ void ttm_bo_vm_close(struct vm_area_struct *vma); int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr, void *buf, int len, int write); + +int ttm_bo_vm_mprotect(struct vm_area_struct *vma, unsigned long start, + unsigned long end, unsigned long newflags); + bool ttm_bo_delayed_delete(struct ttm_device *bdev, bool remove_all); vm_fault_t
Re: [PATCH 3/3] drm/amdgpu: replace dce_virtual with amdgpu_vkms
Hi Ryan, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on next-20210712] [cannot apply to drm-intel/for-linux-next drm-tip/drm-tip drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next linus/master drm/drm-next v5.14-rc1 v5.13 v5.13-rc7 v5.14-rc1] [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/0day-ci/linux/commits/Ryan-Taylor/drm-amdgpu-modernize-virtual-display-feature/20210713-034827 base:db503865b9ba6284edfee3825846a464cc4f4c61 config: i386-randconfig-r013-20210712 (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/da96fc5ec68bb4054ce0f7f1c9c10d3305ba217f git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Ryan-Taylor/drm-amdgpu-modernize-virtual-display-feature/20210713-034827 git checkout da96fc5ec68bb4054ce0f7f1c9c10d3305ba217f # save the attached .config to linux build tree make W=1 ARCH=i386 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/amd/amdgpu/amdgpu_vkms.c:165:5: warning: no previous prototype for 'amdgpu_vkms_crtc_init' [-Wmissing-prototypes] 165 | int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, | ^ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:332:20: error: initialization of 'void (*)(struct drm_plane *, struct drm_atomic_state *)' from incompatible pointer type 'void (*)(struct drm_plane *, struct drm_plane_state *)' [-Werror=incompatible-pointer-types] 332 | .atomic_update = amdgpu_vkms_plane_atomic_update, |^~~ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:332:20: note: (near initialization for 'amdgpu_vkms_primary_helper_funcs.atomic_update') drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:333:19: error: initialization of 'int (*)(struct drm_plane *, struct drm_atomic_state *)' from incompatible pointer type 'int (*)(struct drm_plane *, struct drm_plane_state *)' [-Werror=incompatible-pointer-types] 333 | .atomic_check = amdgpu_vkms_plane_atomic_check, | ^~ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:333:19: note: (near initialization for 'amdgpu_vkms_primary_helper_funcs.atomic_check') drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:338:19: warning: no previous prototype for 'amdgpu_vkms_plane_init' [-Wmissing-prototypes] 338 | struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev, | ^~ >> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:363:5: warning: no previous >> prototype for 'amdgpu_vkms_output_init' [-Wmissing-prototypes] 363 | int amdgpu_vkms_output_init(struct drm_device *dev, | ^~~ cc1: some warnings being treated as errors vim +/amdgpu_vkms_output_init +363 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c 96f64e3b91a195 Ryan Taylor 2021-07-12 362 96f64e3b91a195 Ryan Taylor 2021-07-12 @363 int amdgpu_vkms_output_init(struct drm_device *dev, 96f64e3b91a195 Ryan Taylor 2021-07-12 364 struct amdgpu_vkms_output *output, int index) 96f64e3b91a195 Ryan Taylor 2021-07-12 365 { 96f64e3b91a195 Ryan Taylor 2021-07-12 366 struct drm_connector *connector = >connector; 96f64e3b91a195 Ryan Taylor 2021-07-12 367 struct drm_encoder *encoder = >encoder; 96f64e3b91a195 Ryan Taylor 2021-07-12 368 struct drm_crtc *crtc = >crtc; 96f64e3b91a195 Ryan Taylor 2021-07-12 369 struct drm_plane *primary, *cursor = NULL; 96f64e3b91a195 Ryan Taylor 2021-07-12 370 int ret; 96f64e3b91a195 Ryan Taylor 2021-07-12 371 96f64e3b91a195 Ryan Taylor 2021-07-12 372 primary = amdgpu_vkms_plane_init(dev, DRM_PLANE_TYPE_PRIMARY, index); 96f64e3b91a195 Ryan Taylor 2021-07-12 373 if (IS_ERR(primary)) 96f64e3b91a195 Ryan Taylor 2021-07-12 374 return PTR_ERR(primary); 96f64e3b91a195 Ryan Taylor 2021-07-12 375 96f64e3b91a195 Ryan Taylor 2021-07-12 376 ret = amdgpu_vkms_crtc_init(dev, crtc, primary, cursor); 96f64e3b91a195 Ryan Taylor 2021-07-12 377 if (ret) 96f64e3b91a195 Ryan Taylor 2021-07-12 378 goto err_crtc; 96f64e3b91a195 Ryan Taylor 2021-07-12 379 96f64e3b91a195 Ryan Taylor 2021-07-12 380 ret = drm_connector_init(dev, connector, _vkms_connector_funcs, 96f64e3b91a195 Ryan Taylor 2021-07-12 381 DRM_MODE_CONNECTOR_VIRTUAL); 96f64e3b91a195 Ryan Taylor 2021-07-12 382 if (ret) { 96f64e3b91a195 Ryan Taylor 2021-07-12 383 DRM_ERROR(&
Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms
Hi Ryan, Thank you for the patch! Yet something to improve: [auto build test ERROR on next-20210712] [also build test ERROR on v5.14-rc1] [cannot apply to drm-intel/for-linux-next drm-tip/drm-tip drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next linus/master drm/drm-next v5.14-rc1 v5.13 v5.13-rc7] [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/0day-ci/linux/commits/Ryan-Taylor/drm-amdgpu-modernize-virtual-display-feature/20210713-034827 base:db503865b9ba6284edfee3825846a464cc4f4c61 config: x86_64-randconfig-a013-20210712 (attached as .config) compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 8d69635ed9ecf36fd0ca85906bfde17949671cbe) 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 # install x86_64 cross compiling tool for clang build # apt-get install binutils-x86-64-linux-gnu # https://github.com/0day-ci/linux/commit/96f64e3b91a195cc37720de206b86c3f0378abbb git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Ryan-Taylor/drm-amdgpu-modernize-virtual-display-feature/20210713-034827 git checkout 96f64e3b91a195cc37720de206b86c3f0378abbb # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All error/warnings (new ones prefixed by >>): >> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:156:5: warning: no previous >> prototype for function 'amdgpu_vkms_crtc_init' [-Wmissing-prototypes] int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, ^ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:156:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, ^ static >> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:323:20: error: incompatible >> function pointer types initializing 'void (*)(struct drm_plane *, struct >> drm_atomic_state *)' with an expression of type 'void (struct drm_plane *, >> struct drm_plane_state *)' [-Werror,-Wincompatible-function-pointer-types] .atomic_update = amdgpu_vkms_plane_atomic_update, ^~~ >> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:324:19: error: incompatible >> function pointer types initializing 'int (*)(struct drm_plane *, struct >> drm_atomic_state *)' with an expression of type 'int (struct drm_plane *, >> struct drm_plane_state *)' [-Werror,-Wincompatible-function-pointer-types] .atomic_check = amdgpu_vkms_plane_atomic_check, ^~ >> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:329:19: warning: no previous >> prototype for function 'amdgpu_vkms_plane_init' [-Wmissing-prototypes] struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev, ^ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:329:1: note: declare 'static' if the function is not intended to be used outside of this translation unit struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev, ^ static 2 warnings and 2 errors generated. vim +323 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c 155 > 156 int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, 157struct drm_plane *primary, struct drm_plane *cursor) 158 { 159 int ret; 160 161 ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor, 162 _vkms_crtc_funcs, NULL); 163 if (ret) { 164 DRM_ERROR("Failed to init CRTC\n"); 165 return ret; 166 } 167 168 drm_crtc_helper_add(crtc, _vkms_crtc_helper_funcs); 169 170 return ret; 171 } 172 173 static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = { 174 .fill_modes = drm_helper_probe_single_connector_modes, 175 .destroy = drm_connector_cleanup, 176 .reset = drm_atomic_helper_connector_reset, 177 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 178 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 179 }; 180 181 static int amdgpu_vkms_conn_get_modes(struct drm_connector *connector) 182 { 183 int count;
Re: [PATCH 1/3] drm/amdgpu: create amdgpu_vkms
Hi Ryan, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on next-20210712] [also build test WARNING on v5.14-rc1] [cannot apply to drm-intel/for-linux-next drm-tip/drm-tip drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next linus/master drm/drm-next v5.14-rc1 v5.13 v5.13-rc7] [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/0day-ci/linux/commits/Ryan-Taylor/drm-amdgpu-modernize-virtual-display-feature/20210713-034827 base:db503865b9ba6284edfee3825846a464cc4f4c61 config: i386-randconfig-r013-20210712 (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/96f64e3b91a195cc37720de206b86c3f0378abbb git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Ryan-Taylor/drm-amdgpu-modernize-virtual-display-feature/20210713-034827 git checkout 96f64e3b91a195cc37720de206b86c3f0378abbb # save the attached .config to linux build tree make W=1 ARCH=i386 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/amd/amdgpu/amdgpu_vkms.c:156:5: warning: no previous >> prototype for 'amdgpu_vkms_crtc_init' [-Wmissing-prototypes] 156 | int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, | ^ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:323:20: error: initialization of 'void (*)(struct drm_plane *, struct drm_atomic_state *)' from incompatible pointer type 'void (*)(struct drm_plane *, struct drm_plane_state *)' [-Werror=incompatible-pointer-types] 323 | .atomic_update = amdgpu_vkms_plane_atomic_update, |^~~ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:323:20: note: (near initialization for 'amdgpu_vkms_primary_helper_funcs.atomic_update') drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:324:19: error: initialization of 'int (*)(struct drm_plane *, struct drm_atomic_state *)' from incompatible pointer type 'int (*)(struct drm_plane *, struct drm_plane_state *)' [-Werror=incompatible-pointer-types] 324 | .atomic_check = amdgpu_vkms_plane_atomic_check, | ^~ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:324:19: note: (near initialization for 'amdgpu_vkms_primary_helper_funcs.atomic_check') >> drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:329:19: warning: no previous >> prototype for 'amdgpu_vkms_plane_init' [-Wmissing-prototypes] 329 | struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev, | ^~ cc1: some warnings being treated as errors vim +/amdgpu_vkms_crtc_init +156 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c 155 > 156 int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, 157struct drm_plane *primary, struct drm_plane *cursor) 158 { 159 int ret; 160 161 ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor, 162 _vkms_crtc_funcs, NULL); 163 if (ret) { 164 DRM_ERROR("Failed to init CRTC\n"); 165 return ret; 166 } 167 168 drm_crtc_helper_add(crtc, _vkms_crtc_helper_funcs); 169 170 return ret; 171 } 172 173 static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = { 174 .fill_modes = drm_helper_probe_single_connector_modes, 175 .destroy = drm_connector_cleanup, 176 .reset = drm_atomic_helper_connector_reset, 177 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 178 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 179 }; 180 181 static int amdgpu_vkms_conn_get_modes(struct drm_connector *connector) 182 { 183 int count; 184 185 count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX); 186 drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF); 187 188 return count; 189 } 190 191 static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = { 192 .get_modes= amdgpu_vkms_conn_get_modes, 193 }; 194 195 static const struct drm_plane_funcs amdgpu_vkms_plane_funcs = { 196 .update_plane = drm_atomic_helper_update_plane, 197 .disable_plane = drm_atomic_helper_disable_plane, 198 .destroy
[PATCH 3/3] drm/amdgpu: replace dce_virtual with amdgpu_vkms
Move dce_virtual into amdgpu_vkms and update all references to dce_virtual with amdgpu_vkms. Signed-off-by: Ryan Taylor --- drivers/gpu/drm/amd/amdgpu/Makefile | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 195 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h | 3 - drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 223 --- drivers/gpu/drm/amd/amdgpu/dce_virtual.h | 30 --- drivers/gpu/drm/amd/amdgpu/nv.c | 20 +- drivers/gpu/drm/amd/amdgpu/soc15.c | 10 +- drivers/gpu/drm/amd/amdgpu/vi.c | 14 +- 8 files changed, 218 insertions(+), 280 deletions(-) delete mode 100644 drivers/gpu/drm/amd/amdgpu/dce_virtual.c delete mode 100644 drivers/gpu/drm/amd/amdgpu/dce_virtual.h diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index dfcf3b39a2f6..fd9c06c5d263 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -119,8 +119,7 @@ amdgpu-y += \ amdgpu-y += \ dce_v10_0.o \ dce_v11_0.o \ - amdgpu_vkms.o \ - dce_virtual.o + amdgpu_vkms.o # add GFX block amdgpu-y += \ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c index 58bd0d7b4602..1301df309aa4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c @@ -5,6 +5,15 @@ #include #include "amdgpu.h" +#ifdef CONFIG_DRM_AMDGPU_SI +#include "dce_v6_0.h" +#endif +#ifdef CONFIG_DRM_AMDGPU_CIK +#include "dce_v8_0.h" +#endif +#include "dce_v10_0.h" +#include "dce_v11_0.h" +#include "ivsrcid/ivsrcid_vislands30.h" #include "amdgpu_vkms.h" #include "amdgpu_display.h" @@ -408,3 +417,189 @@ int amdgpu_vkms_output_init(struct drm_device *dev, return ret; } + +const struct drm_mode_config_funcs amdgpu_vkms_mode_funcs = { + .fb_create = amdgpu_display_user_framebuffer_create, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; + +static int amdgpu_vkms_sw_init(void *handle) +{ + int r, i; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + adev_to_drm(adev)->max_vblank_count = 0; + + adev_to_drm(adev)->mode_config.funcs = _vkms_mode_funcs; + + adev_to_drm(adev)->mode_config.max_width = XRES_MAX; + adev_to_drm(adev)->mode_config.max_height = YRES_MAX; + + adev_to_drm(adev)->mode_config.preferred_depth = 24; + adev_to_drm(adev)->mode_config.prefer_shadow = 1; + + adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base; + + r = amdgpu_display_modeset_create_props(adev); + if (r) + return r; + + adev->amdgpu_vkms_output = kzalloc(sizeof(struct amdgpu_vkms_output) * adev->mode_info.num_crtc, GFP_KERNEL); + + /* allocate crtcs, encoders, connectors */ + for (i = 0; i < adev->mode_info.num_crtc; i++) { + r = amdgpu_vkms_output_init(adev_to_drm(adev), >amdgpu_vkms_output[i], i); + if (r) + return r; + } + + drm_kms_helper_poll_init(adev_to_drm(adev)); + + adev->mode_info.mode_config_initialized = true; + return 0; +} + +static int amdgpu_vkms_sw_fini(void *handle) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + int i = 0; + + for (i = 0; i < adev->mode_info.num_crtc; i++) + if (adev->mode_info.crtcs[i]) + hrtimer_cancel(>mode_info.crtcs[i]->vblank_timer); + + kfree(adev->mode_info.bios_hardcoded_edid); + kfree(adev->amdgpu_vkms_output); + + drm_kms_helper_poll_fini(adev_to_drm(adev)); + + adev->mode_info.mode_config_initialized = false; + return 0; +} + +static int amdgpu_vkms_hw_init(void *handle) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + switch (adev->asic_type) { +#ifdef CONFIG_DRM_AMDGPU_SI + case CHIP_TAHITI: + case CHIP_PITCAIRN: + case CHIP_VERDE: + case CHIP_OLAND: + dce_v6_0_disable_dce(adev); + break; +#endif +#ifdef CONFIG_DRM_AMDGPU_CIK + case CHIP_BONAIRE: + case CHIP_HAWAII: + case CHIP_KAVERI: + case CHIP_KABINI: + case CHIP_MULLINS: + dce_v8_0_disable_dce(adev); + break; +#endif + case CHIP_FIJI: + case CHIP_TONGA: + dce_v10_0_disable_dce(adev); + break; + case CHIP_CARRIZO: + case CHIP_STONEY: + case CHIP_POLARIS10: + case CHIP_POLARIS11: + case CHIP_VEGAM: + dce_v11_0_disable_dce(adev); + break; + case CHIP_TOPAZ: +#ifdef CONFIG_DRM_AMDGPU_SI + case CHIP_HAINAN: +#endif + /* no DCE */ + break; + default: + break; + } + return 0; +} + +static int amdgpu_vkms_hw_fini(void *handle) +{ + return 0; +} + +static int
[PATCH 2/3] drm/amdgpu: cleanup dce_virtual
Remove obsolete functions and variables from dce_virtual. Signed-off-by: Ryan Taylor --- drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 568 +-- 1 file changed, 3 insertions(+), 565 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c index 642c77533157..18369b47eac7 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c @@ -21,15 +21,9 @@ * */ -#include #include #include "amdgpu.h" -#include "amdgpu_pm.h" -#include "amdgpu_i2c.h" -#include "atom.h" -#include "amdgpu_pll.h" -#include "amdgpu_connectors.h" #ifdef CONFIG_DRM_AMDGPU_SI #include "dce_v6_0.h" #endif @@ -43,339 +37,6 @@ #include "amdgpu_display.h" #include "amdgpu_vkms.h" -#define DCE_VIRTUAL_VBLANK_PERIOD 1666 - - -static void dce_virtual_set_display_funcs(struct amdgpu_device *adev); -static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev); -static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev, - int index); -static int dce_virtual_pageflip(struct amdgpu_device *adev, - unsigned crtc_id); -static enum hrtimer_restart dce_virtual_vblank_timer_handle(struct hrtimer *vblank_timer); -static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev, - int crtc, - enum amdgpu_interrupt_state state); - -static u32 dce_virtual_vblank_get_counter(struct amdgpu_device *adev, int crtc) -{ - return 0; -} - -static void dce_virtual_page_flip(struct amdgpu_device *adev, - int crtc_id, u64 crtc_base, bool async) -{ - return; -} - -static int dce_virtual_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc, - u32 *vbl, u32 *position) -{ - *vbl = 0; - *position = 0; - - return -EINVAL; -} - -static bool dce_virtual_hpd_sense(struct amdgpu_device *adev, - enum amdgpu_hpd_id hpd) -{ - return true; -} - -static void dce_virtual_hpd_set_polarity(struct amdgpu_device *adev, - enum amdgpu_hpd_id hpd) -{ - return; -} - -static u32 dce_virtual_hpd_get_gpio_reg(struct amdgpu_device *adev) -{ - return 0; -} - -/** - * dce_virtual_bandwidth_update - program display watermarks - * - * @adev: amdgpu_device pointer - * - * Calculate and program the display watermarks and line - * buffer allocation (CIK). - */ -static void dce_virtual_bandwidth_update(struct amdgpu_device *adev) -{ - return; -} - -static int dce_virtual_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, - u16 *green, u16 *blue, uint32_t size, - struct drm_modeset_acquire_ctx *ctx) -{ - return 0; -} - -static void dce_virtual_crtc_destroy(struct drm_crtc *crtc) -{ - struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); - - drm_crtc_cleanup(crtc); - kfree(amdgpu_crtc); -} - -static const struct drm_crtc_funcs dce_virtual_crtc_funcs = { - .cursor_set2 = NULL, - .cursor_move = NULL, - .gamma_set = dce_virtual_crtc_gamma_set, - .set_config = amdgpu_display_crtc_set_config, - .destroy = dce_virtual_crtc_destroy, - .page_flip_target = amdgpu_display_crtc_page_flip_target, - .get_vblank_counter = amdgpu_get_vblank_counter_kms, - .enable_vblank = amdgpu_enable_vblank_kms, - .disable_vblank = amdgpu_disable_vblank_kms, - .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, -}; - -static void dce_virtual_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct drm_device *dev = crtc->dev; - struct amdgpu_device *adev = drm_to_adev(dev); - struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); - unsigned type; - - switch (mode) { - case DRM_MODE_DPMS_ON: - amdgpu_crtc->enabled = true; - /* Make sure VBLANK interrupts are still enabled */ - type = amdgpu_display_crtc_idx_to_irq_type(adev, - amdgpu_crtc->crtc_id); - amdgpu_irq_update(adev, >crtc_irq, type); - drm_crtc_vblank_on(crtc); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - drm_crtc_vblank_off(crtc); - amdgpu_crtc->enabled = false; - break; - } -} - - -static void dce_virtual_crtc_prepare(struct drm_crtc *crtc) -{ - dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); -} - -static void dce_virtual_crtc_commit(struct drm_crtc *crtc) -{ - dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_ON); -} - -static void dce_virtual_crtc_disable(struct drm_crtc *crtc) -{ -
[PATCH 0/3] drm/amdgpu: modernize virtual display feature
The amdgpu vkms interface provides a virtual KMS interface for several use cases: devices without display hardware, platforms where the actual display hardware is not useful (e.g., servers), SR-IOV virtual functions, device emulation/simulation, and device bring up prior to display hardware being usable. We previously emulated a legacy KMS interface, but there was a desire to move to the atomic KMS interface. The vkms driver did everything we needed, but we wanted KMS support natively in the driver without buffer sharing and the ability to support an instance of VKMS per device. We first looked at splitting vkms into a stub driver and a helper module that other drivers could use to implement a virtual display, but this strategy ended up being messy due to driver specific callbacks needed for buffer management. Ultimately, it proved easier to import the vkms code as it mostly used core drm helpers anyway. Ryan Taylor (3): drm/amdgpu: create amdgpu_vkms drm/amdgpu: cleanup dce_virtual drm/amdgpu: replace dce_virtual with amdgpu_vkms drivers/gpu/drm/amd/amdgpu/Makefile | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 605 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h | 26 + drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 780 --- drivers/gpu/drm/amd/amdgpu/dce_virtual.h | 30 - drivers/gpu/drm/amd/amdgpu/nv.c | 20 +- drivers/gpu/drm/amd/amdgpu/soc15.c | 10 +- drivers/gpu/drm/amd/amdgpu/vi.c | 14 +- 11 files changed, 657 insertions(+), 835 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h delete mode 100644 drivers/gpu/drm/amd/amdgpu/dce_virtual.c delete mode 100644 drivers/gpu/drm/amd/amdgpu/dce_virtual.h -- 2.32.0 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/3] drm/amdgpu: create amdgpu_vkms
Modify the VKMS driver into an api that dce_virtual can use to create virtual displays that obey drm's atomic modesetting api. Signed-off-by: Ryan Taylor --- drivers/gpu/drm/amd/amdgpu/Makefile | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 410 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h | 29 ++ drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 23 +- 7 files changed, 457 insertions(+), 11 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 7d292485ca7c..dfcf3b39a2f6 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -119,6 +119,7 @@ amdgpu-y += \ amdgpu-y += \ dce_v10_0.o \ dce_v11_0.o \ + amdgpu_vkms.o \ dce_virtual.o # add GFX block diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index d14b4968a026..a0198963fc8a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -912,6 +912,7 @@ struct amdgpu_device { /* display */ boolenable_virtual_display; + struct amdgpu_vkms_output *amdgpu_vkms_output; struct amdgpu_mode_info mode_info; /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */ struct work_struct hotplug_work; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 179f2d01a082..5c774d6625e4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -1222,7 +1222,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, int ret, retry = 0; bool supports_atomic = false; - if (!amdgpu_virtual_display && + if (amdgpu_virtual_display || amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK)) supports_atomic = true; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index 09b048647523..5a143ca02cf9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -344,7 +344,7 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev) } /* disable all the possible outputs/crtcs before entering KMS mode */ - if (!amdgpu_device_has_dc_support(adev)) + if (!amdgpu_device_has_dc_support(adev) && !amdgpu_virtual_display) drm_helper_disable_unused_functions(adev_to_drm(adev)); drm_fb_helper_initial_config(>helper, bpp_sel); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c new file mode 100644 index ..58bd0d7b4602 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c @@ -0,0 +1,410 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include + +#include "amdgpu.h" +#include "amdgpu_vkms.h" +#include "amdgpu_display.h" + +/** + * DOC: amdgpu_vkms + * + * The amdgpu vkms interface provides a virtual KMS interface for several use + * cases: devices without display hardware, platforms where the actual display + * hardware is not useful (e.g., servers), SR-IOV virtual functions, device + * emulation/simulation, and device bring up prior to display hardware being + * usable. We previously emulated a legacy KMS interface, but there was a desire + * to move to the atomic KMS interface. The vkms driver did everything we + * needed, but we wanted KMS support natively in the driver without buffer + * sharing and the ability to support an instance of VKMS per device. We first + * looked at splitting vkms into a stub driver and a helper module that other + * drivers could use to implement a virtual display, but this strategy ended up + * being messy due to driver specific callbacks needed for buffer management. + * Ultimately, it proved easier to import the vkms code as it mostly used core + * drm helpers anyway. + */ + +static const u32 amdgpu_vkms_formats[] = { + DRM_FORMAT_XRGB, +}; + +static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct hrtimer *timer) +{ + struct amdgpu_vkms_output *output = container_of(timer, +struct amdgpu_vkms_output, +vblank_hrtimer); + struct drm_crtc *crtc = >crtc; + u64 ret_overrun; + bool ret; + + ret_overrun = hrtimer_forward_now(>vblank_hrtimer, + output->period_ns); + WARN_ON(ret_overrun != 1); + + ret = drm_crtc_handle_vblank(crtc); + if (!ret) + DRM_ERROR("amdgpu_vkms failure on
Re: [PATCH 3/3] drm/amdgpu: replace dce_virtual with amdgpu_vkms
Hi Ryan, Thank you for the patch! Yet something to improve: [auto build test ERROR on next-20210712] [cannot apply to drm-intel/for-linux-next drm-tip/drm-tip drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next linus/master drm/drm-next v5.14-rc1 v5.13 v5.13-rc7 v5.14-rc1] [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/0day-ci/linux/commits/Ryan-Taylor/drm-amdgpu-modernize-virtual-display-feature/20210713-034827 base:db503865b9ba6284edfee3825846a464cc4f4c61 config: i386-randconfig-a013-20210712 (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/da96fc5ec68bb4054ce0f7f1c9c10d3305ba217f git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Ryan-Taylor/drm-amdgpu-modernize-virtual-display-feature/20210713-034827 git checkout da96fc5ec68bb4054ce0f7f1c9c10d3305ba217f # save the attached .config to linux build tree mkdir build_dir make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/gpu/drm/amd/amdgpu/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All errors (new ones prefixed by >>): >> drivers/gpu/drm/amd/amdgpu/cik.c:73:10: fatal error: dce_virtual.h: No such >> file or directory 73 | #include "dce_virtual.h" | ^~~ compilation terminated. vim +73 drivers/gpu/drm/amd/amdgpu/cik.c a2e73f56fa6282 Alex Deucher 2015-04-20 70 4562236b3bc0a2 Harry Wentland 2017-09-12 71 #include "amdgpu_dm.h" 130e0371b7d454 Oded Gabbay2015-06-12 72 #include "amdgpu_amdkfd.h" e9ed3a67cd1bfd Emily Deng 2016-08-08 @73 #include "dce_virtual.h" 130e0371b7d454 Oded Gabbay2015-06-12 74 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/pm: Fix a bug communicating with the SMU
This fixes a bug which if we probe a non-existing I2C device, and the SMU returns 0xFF, from then on we can never communicate with the SMU, because the code before this patch reads and interprets 0xFF as a terminal error, and thus we never write 0 into register 90 to clear the status (and subsequently send a new command to the SMU.) It is not an error that the SMU returns status 0xFF. This means that the SMU executed the last command successfully (execution status), but the command result is an error of some sort (execution result), depending on what the command was. When doing a status check of the SMU, before we send a new command, the only status which precludes us from sending a new command is 0--the SMU hasn't finished executing a previous command, and 0xFC--the SMU is busy. This bug was seen as the following line in the kernel log, amdgpu: Msg issuing pre-check failed(0xff) and SMU may be not in the right state! when subsequent SMU commands, not necessarily related to I2C, were sent to the SMU. This patch fixes this bug. Cc: Alex Deucher Cc: Evan Quan Fixes: fcb1fe9c9e0031 ("drm/amd/powerplay: pre-check the SMU state before issuing message") Signed-off-by: Luben Tuikov --- drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 196 +++-- drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 3 +- 2 files changed, 152 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c index c902fdf322c1be..775eb50a2e49a6 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -55,7 +55,7 @@ #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(type) #type -static const char* __smu_message_names[] = { +static const char * const __smu_message_names[] = { SMU_MESSAGE_TYPES }; @@ -76,46 +76,161 @@ static void smu_cmn_read_arg(struct smu_context *smu, *arg = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82); } -int smu_cmn_wait_for_response(struct smu_context *smu) +/** + * __smu_cmn_poll_stat -- poll for a status from the SMU + * smu: a pointer to SMU context + * + * Returns the status of the SMU, which could be, + * 0, the SMU is busy with your previous command; + * 1,execution status: success, execution result: success; + * 0xFF, execution status: success, execution result: failure; + * 0xFE, unknown command; + * 0xFD, valid command, but bad (command) prerequisites; + * 0xFC, the command was rejected as the SMU is busy; + * 0xFB, "SMC_Result_DebugDataDumpEnd". + */ +static u32 __smu_cmn_poll_stat(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; - uint32_t cur_value, i, timeout = adev->usec_timeout * 20; + int timeout = adev->usec_timeout * 20; + u32 reg; - for (i = 0; i < timeout; i++) { - cur_value = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90); - if ((cur_value & MP1_C2PMSG_90__CONTENT_MASK) != 0) - return cur_value; + for ( ; timeout > 0; timeout--) { + reg = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90); + if ((reg & MP1_C2PMSG_90__CONTENT_MASK) != 0) + break; udelay(1); } - /* timeout means wrong logic */ - if (i == timeout) - return -ETIME; - - return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90); + return reg; } -int smu_cmn_send_msg_without_waiting(struct smu_context *smu, -uint16_t msg, uint32_t param) +static void __smu_cmn_reg_print_error(struct smu_context *smu, + u32 reg_c2pmsg_90, + int msg_index, + u32 param, + enum smu_message_type msg) { struct amdgpu_device *adev = smu->adev; - int ret; + const char *message = smu_get_message_name(smu, msg); - ret = smu_cmn_wait_for_response(smu); - if (ret != 0x1) { - dev_err(adev->dev, "Msg issuing pre-check failed(0x%x) and " - "SMU may be not in the right state!\n", ret); - if (ret != -ETIME) - ret = -EIO; - return ret; + switch (reg_c2pmsg_90) { + case 0: + dev_err_ratelimited(adev->dev, + "SMU: I'm not done with your previous command!"); + break; + case 1: + /* The SMU executed the command. It completed with a +* successful result. +*/ + break; + case 0xFF: + /* The SMU executed the command. It completed with a +* unsuccessful result. +*/ + break; + case 0xFE: + dev_err_ratelimited(adev->dev, + "SMU: unknown command: index:%d param:0x%08X message:%s", +
Re: Waiting for fences timed out on MacBook Pro 2019
On Mon, Jul 12, 2021 at 5:57 AM Tomasz Moń wrote: > > Hello, > > I am having trouble getting Linux to run on MacBook Pro 2019 with > Radeon Pro Vega 20 4 GB. Basically as soon as graphical user interface > starts, the whole system freezes. This happens with every Linux kernel > version I have tried over the last few months, including 5.13. If this is a regression, can you bisect? Alex > > Using SSH I have been able to read dmesg output: > [ 207.113144] [drm:amdgpu_dm_atomic_commit_tail [amdgpu]] *ERROR* > Waiting for fences timed out! > [ 207.113168] [drm:amdgpu_dm_atomic_commit_tail [amdgpu]] *ERROR* > Waiting for fences timed out! > [ 212.029866] [drm:amdgpu_job_timedout [amdgpu]] *ERROR* ring gfx > timeout, signaled seq=1022, emitted seq=1024 > [ 212.030083] [drm:amdgpu_job_timedout [amdgpu]] *ERROR* Process > information: process Xorg pid 918 thread Xorg:cs0 pid 919 > [ 212.030276] amdgpu :03:00.0: amdgpu: GPU reset begin! > [ 216.030286] amdgpu :03:00.0: amdgpu: failed to suspend display audio > [ 227.396593] applesmc: driver init failed (ret=-5)! > > How do I debug this further? > > Best regards, > Tomasz Moń > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Waiting for fences timed out on MacBook Pro 2019
Hello, I am having trouble getting Linux to run on MacBook Pro 2019 with Radeon Pro Vega 20 4 GB. Basically as soon as graphical user interface starts, the whole system freezes. This happens with every Linux kernel version I have tried over the last few months, including 5.13. Using SSH I have been able to read dmesg output: [ 207.113144] [drm:amdgpu_dm_atomic_commit_tail [amdgpu]] *ERROR* Waiting for fences timed out! [ 207.113168] [drm:amdgpu_dm_atomic_commit_tail [amdgpu]] *ERROR* Waiting for fences timed out! [ 212.029866] [drm:amdgpu_job_timedout [amdgpu]] *ERROR* ring gfx timeout, signaled seq=1022, emitted seq=1024 [ 212.030083] [drm:amdgpu_job_timedout [amdgpu]] *ERROR* Process information: process Xorg pid 918 thread Xorg:cs0 pid 919 [ 212.030276] amdgpu :03:00.0: amdgpu: GPU reset begin! [ 216.030286] amdgpu :03:00.0: amdgpu: failed to suspend display audio [ 227.396593] applesmc: driver init failed (ret=-5)! How do I debug this further? Best regards, Tomasz Moń ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/1] drm/ttm: Fix COW check
Am 10.07.21 um 02:28 schrieb Felix Kuehling: KFD Thunk maps invisible VRAM BOs with PROT_NONE, MAP_PRIVATE. is_cow_mapping returns true for these mappings. Add a check for vm_flags & VM_WRITE to avoid mmap failures on private read-only or PROT_NONE mappings. v2: protect against mprotect making a mapping writable after the fact Fixes: f91142c62161 ("drm/ttm: nuke VM_MIXEDMAP on BO mappings v3") Signed-off-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index f56be5bc0861..9ad211ede611 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -542,17 +542,28 @@ int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr, } EXPORT_SYMBOL(ttm_bo_vm_access); +static int ttm_bo_vm_mprotect(struct vm_area_struct *vma, unsigned long start, + unsigned long end, unsigned long newflags) +{ + /* Enforce no COW since would have really strange behavior with it. */ + if (is_cow_mapping(newflags) && (newflags & VM_WRITE)) + return -EINVAL; + + return 0; +} + static const struct vm_operations_struct ttm_bo_vm_ops = { .fault = ttm_bo_vm_fault, .open = ttm_bo_vm_open, .close = ttm_bo_vm_close, .access = ttm_bo_vm_access, + .mprotect = ttm_bo_vm_mprotect, The problem is most drivers implement their own copy of this structure. You need to add this to those occasions as well, just search for references to ttm_bo_vm_open. Regards, Christian. }; int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo) { /* Enforce no COW since would have really strange behavior with it. */ - if (is_cow_mapping(vma->vm_flags)) + if (is_cow_mapping(vma->vm_flags) && (vma->vm_flags & VM_WRITE)) return -EINVAL; ttm_bo_get(bo); ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 2/2] drm/ttm: Fix COW check
Am 10.07.21 um 02:29 schrieb Felix Kuehling: On 2021-07-09 3:37 p.m., Christian König wrote: Am 09.07.21 um 21:31 schrieb Felix Kuehling: On 2021-07-09 2:38 a.m., Christian König wrote: Am 08.07.21 um 21:36 schrieb Alex Deucher: From: Felix Kuehling KFD Thunk maps invisible VRAM BOs with PROT_NONE, MAP_PRIVATE. is_cow_mapping returns true for these mappings. Add a check for vm_flags & VM_WRITE to avoid mmap failures on private read-only or PROT_NONE mappings. I'm pretty sure that this is not working as expected. Not sure what you mean. Debugger access to the memory through the PROT_NONE VMAs is definitely working, with both ptrace and /proc//mem. Fixes: f91142c62161 ("drm/ttm: nuke VM_MIXEDMAP on BO mappings v3") Signed-off-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index f56be5bc0861..a75e90c7d4aa 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -552,7 +552,7 @@ static const struct vm_operations_struct ttm_bo_vm_ops = { int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo) { /* Enforce no COW since would have really strange behavior with it. */ - if (is_cow_mapping(vma->vm_flags)) + if (is_cow_mapping(vma->vm_flags) && (vma->vm_flags & VM_WRITE)) is_cow_mapping() already checks for VM_MAYWRITE, so this here shouldn't be necessary. AFAICT, VM_MAYWRITE is not based on the PROT_... bits used to create the VMA, but based on the permissions of the file. So as long as the render node is writable, VM_MAYWRITE is set for all VMAs that map it. I would agree that it's probably a bad idea for the Thunk to map these VMAs with MAP_PRIVATE. We can try changing the Thunk to use MAP_SHARED for these PROT_NONE mappings. But that doesn't change the fact that this kernel patch broke existing usermode. For the record, changing the Thunk to use MAP_SHARED works. Yeah, but see the discussion around MAP_PRIVATE and COW regarding this. What Thunk did here was a really bad idea. Hindsight ... Which part was a bad idea? * Creating a PROT_NONE VMA? That's necessary to let ptrace or /proc//mem access the memory. It's a brilliant idea, IMHO * Making that VMA MAP_PRIVATE? Probably a bad idea in hindsight. The process itself can't access this memory, let alone write to it. So I didn't think too much about whether to make it shared or private. Either way, we are not causing any actual COW on these mappings because they are not writable, and we never make them writable with mprotect either * Introducing a COW check after letting it slide for 15 years? It's a reasonable check. In this case it catches a false positive. Had this check been in place 4 or 5 years ago, it would have easily prevented this mess A combination of everything. MAP_PRIVATE would have previously caused very odd behavior and/or a BUG_ON()/WARN_ON() in the VMA code (depending on platform). MAP_PRIVATE + PROT_NONE kind of worked because it never faulted a page so we never actually triggered a COW. I think we have only two options here: 1. Accept the breakage of thunk. Really? Only as last resort, I'm running out of ideas how to fix this cleanly. 2. Add a workaround in amdgpu/amdkfd to force MAP_PRIVATE into MAP_SHARED in the kernel. I tried to do this in amdgpu_gem_object_mmap and spent 4 hours debugging why it doesn't work. It breaks because the mapping->i_mmap_writable gets unbalanced and causes subsequent mappings to fail when that atomic counter becomes negative (indicating DENYWRITE). I could fix it by calling mapping_map_writable. But I don't think this is intended as driver API. I see no precedent of any driver calling this. For the record this works, but it feels fragile and ugly: --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -255,6 +255,20 @@ static int amdgpu_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_str if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) return -EPERM; + /* Workaround for Thunk bug creating PROT_NONE,MAP_PRIVATE mappings + * for debugger access to invisible VRAM. Should have used MAP_SHARED + * instead. + */ + if (is_cow_mapping(vma->vm_flags) && + !(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) { + int ret; + + ret = mapping_map_writable(vma->vm_file->f_mapping); + if (ret) + return ret; + vma->vm_flags |= VM_SHARED | VM_MAYSHARE; + } + Yeah, I'm on another thread where we are discussing mapping_map_writable() for vma_set_file() as well. return drm_gem_ttm_mmap(obj, vma); } 3. Improve my previous workaround by adding a similar check for COW in ttm_bo_vm_ops.mprotect. I'll send an updated patch. That has it's own
Re: AMDGPU error: "[drm:amdgpu_dm_atomic_commit_tail [amdgpu]] *ERROR* Waiting for fences timed out!"
On 2021-07-11 9:48 a.m., Ketsui wrote: >> So far, so good; no hang in a week. I'll try the rest of the new firmware as >> well now, will follow up if there's a hang again. > > I've noticed that the VM_L2_PROTECTION_FAULT_STATUS error doesn't always > result in a hang, looking through my journal I can see > maybe a dozen of them spread out across multiple boots but my system only > became non-functional like two times so far (I know > because I have the dmesg when the hangs happened saved, you can find them > attached to this mail). > > To make myself clear, I haven't actually had a hang too with the new > firmwares even though these messages still appear on my dmesg, > sorry if my feedback gave the wrong impression. I'm counting soft recovered hangs as hangs for the purpose of this issue. I.e. when I write "no hang" I mean no soft recovered ones either. If I hit a soft recovered hang, I consider that setup bad. -- Earthling Michel Dänzer | https://redhat.com Libre software enthusiast | Mesa and X developer ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/amdgpu: Recovery vcn instance iterate.
The previous logic is recording the amount of valid vcn instances to use them on SRIOV, it is a hard task due to the vcn accessment is based on the index of the vcn instance. there is a machanism which recording the invalid instance and skipping the invalid one, re-use this mechanism on SRIOV environment. Signed-off-by: Peng Ju Zhou --- drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 25 + 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c index c3580de3ea9c..954ab7e76926 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c @@ -88,10 +88,10 @@ static int vcn_v3_0_early_init(void *handle) int i; if (amdgpu_sriov_vf(adev)) { + adev->vcn.num_vcn_inst = VCN_INSTANCES_SIENNA_CICHLID; for (i = 0; i < VCN_INSTANCES_SIENNA_CICHLID; i++) if (amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, i)) - adev->vcn.num_vcn_inst++; - adev->vcn.harvest_config = 0; + adev->vcn.harvest_config |= 1 << i; adev->vcn.num_enc_rings = 1; } else { @@ -151,8 +151,7 @@ static int vcn_v3_0_sw_init(void *handle) adev->firmware.fw_size += ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); - if ((adev->vcn.num_vcn_inst == VCN_INSTANCES_SIENNA_CICHLID) || - (amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_SIENNA_CICHLID)) { + if (adev->vcn.num_vcn_inst == VCN_INSTANCES_SIENNA_CICHLID) { adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].ucode_id = AMDGPU_UCODE_ID_VCN1; adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].fw = adev->vcn.fw; adev->firmware.fw_size += @@ -322,17 +321,19 @@ static int vcn_v3_0_hw_init(void *handle) continue; ring = >vcn.inst[i].ring_dec; - ring->wptr = 0; - ring->wptr_old = 0; - vcn_v3_0_dec_ring_set_wptr(ring); - ring->sched.ready = true; + if (ring->sched.ready) { + ring->wptr = 0; + ring->wptr_old = 0; + vcn_v3_0_dec_ring_set_wptr(ring); + } for (j = 0; j < adev->vcn.num_enc_rings; ++j) { ring = >vcn.inst[i].ring_enc[j]; - ring->wptr = 0; - ring->wptr_old = 0; - vcn_v3_0_enc_ring_set_wptr(ring); - ring->sched.ready = true; + if (ring->sched.ready) { + ring->wptr = 0; + ring->wptr_old = 0; + vcn_v3_0_enc_ring_set_wptr(ring); + } } } } else { -- 2.17.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: drm/amd/display: Simplify hdcp validate_bksv
On Mon, 2021-07-12 at 07:02 +0800, kernel test robot wrote: > Hi Joe, > > I love your patch! Yet something to improve: > > [auto build test ERROR on drm-intel/for-linux-next] > [also build test ERROR on drm-exynos/exynos-drm-next linus/master > next-20210709] > [cannot apply to kees/for-next/pstore tegra-drm/drm/tegra/for-next > drm/drm-next v5.13] > [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/0day-ci/linux/commits/Joe-Perches/drm-amd-display-Simplify-hdcp-validate_bksv/20210712-034708 > base: git://anongit.freedesktop.org/drm-intel for-linux-next > config: i386-randconfig-a003-20210712 (attached as .config) > compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 > reproduce (this is a W=1 build): > # > https://github.com/0day-ci/linux/commit/66fae2c1becdcb71c95f2c6a6413de4dfe1deb51 > git remote add linux-review https://github.com/0day-ci/linux > git fetch --no-tags linux-review > Joe-Perches/drm-amd-display-Simplify-hdcp-validate_bksv/20210712-034708 > git checkout 66fae2c1becdcb71c95f2c6a6413de4dfe1deb51 > # save the attached .config to linux build tree > make W=1 ARCH=i386 > > If you fix the issue, kindly add following tag as appropriate > Reported-by: kernel test robot > > All errors (new ones prefixed by >>, old ones prefixed by <<): > > > > ERROR: modpost: "__popcountdi2" [drivers/gpu/drm/amd/amdgpu/amdgpu.ko] > > > undefined! curious. Anyone know why? ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: Fix identical code for different branches
The ternary expression: vrr->state == VRR_STATE_ACTIVE_VARIABLE ? max_refresh : max_refresh; has identical then and else expressions. So, simplify the code. Addresses-Coverity-ID: 1471122 ("Identical code for different branches") Fixes: 9bc4162665827 ("drm/amd/display: Implement VSIF V3 extended refresh rate feature") Signed-off-by: Len Baker --- drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 3f4f44b44e6a..54374c7d309b 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -613,9 +613,8 @@ static void build_vrr_infopacket_data_v3(const struct mod_vrr_params *vrr, (vrr->state == VRR_STATE_INACTIVE) ? min_refresh : max_refresh; // Non-fs case, program nominal range - max_programmed = (vrr->state == VRR_STATE_ACTIVE_FIXED) ? fixed_refresh : - (vrr->state == VRR_STATE_ACTIVE_VARIABLE) ? max_refresh : - max_refresh;// Non-fs case, program nominal range + max_programmed = (vrr->state == VRR_STATE_ACTIVE_FIXED) ? + fixed_refresh : max_refresh; /* PB7 = FreeSync Minimum refresh rate (Hz) */ infopacket->sb[7] = min_programmed & 0xFF; -- 2.25.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH] drm/amd/display: Fix identical code for different branches
On Sun, 2021-07-11 at 19:24 +0200, Len Baker wrote: > The branches of the "if" statement are the same. So remove the > unnecessary if and goto statements. > > Addresses-Coverity-ID: 1456916 ("Identical code for different branches") > Fixes: 4c283fdac08ab ("drm/amd/display: Add HDCP module") > Signed-off-by: Len Baker I'm not a big fan of this type of change. It's currently the same style used for six tests in this function and changing this last one would just make it harder to see the code blocks as consistent. I doubt any reasonable compiler would produce different objects. > diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c > b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c [] > @@ -305,10 +305,8 @@ static enum mod_hdcp_status wait_for_ready(struct > mod_hdcp *hdcp, > hdcp, "bcaps_read")) > goto out; > } > - if (!mod_hdcp_execute_and_set(check_ksv_ready, > - >ready_check, , > - hdcp, "ready_check")) > - goto out; > + mod_hdcp_execute_and_set(check_ksv_ready, >ready_check, , > + hdcp, "ready_check"); > out: > return status; > } > -- > 2.25.1 > ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
drm/amd/display: Simplify hdcp validate_bksv
commit 06888d571b51 ("drm/amd/display: Avoid HDCP over-read and corruption") fixed an overread with an invalid buffer length but added an unnecessary buffer and copy. Simplify the code by using a single uint64_t and __builtin_popcountll to count the number of bits set in the original bksv buffer instead of a loop. This also avoid a possible unaligned access of the temporary bksv. Signed-off-by: Joe Perches --- It seems quite odd 20 bits set is a magic number here. Should it be a specific be/le value instead? drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c | 11 ++- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c index de872e7958b06..78a4c6dd95d99 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c @@ -28,17 +28,10 @@ static inline enum mod_hdcp_status validate_bksv(struct mod_hdcp *hdcp) { uint64_t n = 0; - uint8_t count = 0; - u8 bksv[sizeof(n)] = { }; - memcpy(bksv, hdcp->auth.msg.hdcp1.bksv, sizeof(hdcp->auth.msg.hdcp1.bksv)); - n = *(uint64_t *)bksv; + memcpy(, hdcp->auth.msg.hdcp1.bksv, sizeof(hdcp->auth.msg.hdcp1.bksv)); - while (n) { - count++; - n &= (n - 1); - } - return (count == 20) ? MOD_HDCP_STATUS_SUCCESS : + return (__builtin_popcountll(n) == 20) ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_HDCP1_INVALID_BKSV; } ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: Fix identical code for different branches
The branches of the "if" statement are the same. So remove the unnecessary if and goto statements. Addresses-Coverity-ID: 1456916 ("Identical code for different branches") Fixes: 4c283fdac08ab ("drm/amd/display: Add HDCP module") Signed-off-by: Len Baker --- drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c index de872e7958b0..d0c565567102 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c @@ -305,10 +305,8 @@ static enum mod_hdcp_status wait_for_ready(struct mod_hdcp *hdcp, hdcp, "bcaps_read")) goto out; } - if (!mod_hdcp_execute_and_set(check_ksv_ready, - >ready_check, , - hdcp, "ready_check")) - goto out; + mod_hdcp_execute_and_set(check_ksv_ready, >ready_check, , +hdcp, "ready_check"); out: return status; } -- 2.25.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx