Rev 4569 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4569 | Rev 5078 | ||
---|---|---|---|
Line 34... | Line 34... | ||
34 | * struct vmw_user_surface - User-space visible surface resource |
34 | * struct vmw_user_surface - User-space visible surface resource |
35 | * |
35 | * |
36 | * @base: The TTM base object handling user-space visibility. |
36 | * @base: The TTM base object handling user-space visibility. |
37 | * @srf: The surface metadata. |
37 | * @srf: The surface metadata. |
38 | * @size: TTM accounting size for the surface. |
38 | * @size: TTM accounting size for the surface. |
- | 39 | * @master: master of the creating client. Used for security check. |
|
39 | */ |
40 | */ |
40 | struct vmw_user_surface { |
41 | struct vmw_user_surface { |
41 | struct ttm_prime_object prime; |
42 | struct ttm_prime_object prime; |
42 | struct vmw_surface srf; |
43 | struct vmw_surface srf; |
43 | uint32_t size; |
44 | uint32_t size; |
Line 679... | Line 680... | ||
679 | uint32_t cur_bo_offset; |
680 | uint32_t cur_bo_offset; |
680 | struct drm_vmw_size *cur_size; |
681 | struct drm_vmw_size *cur_size; |
681 | struct vmw_surface_offset *cur_offset; |
682 | struct vmw_surface_offset *cur_offset; |
682 | uint32_t num_sizes; |
683 | uint32_t num_sizes; |
683 | uint32_t size; |
684 | uint32_t size; |
684 | struct vmw_master *vmaster = vmw_master(file_priv->master); |
- | |
685 | const struct svga3d_surface_desc *desc; |
685 | const struct svga3d_surface_desc *desc; |
Line 686... | Line 686... | ||
686 | 686 | ||
687 | if (unlikely(vmw_user_surface_size == 0)) |
687 | if (unlikely(vmw_user_surface_size == 0)) |
688 | vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) + |
688 | vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) + |
Line 705... | Line 705... | ||
705 | if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) { |
705 | if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) { |
706 | DRM_ERROR("Invalid surface format for surface creation.\n"); |
706 | DRM_ERROR("Invalid surface format for surface creation.\n"); |
707 | return -EINVAL; |
707 | return -EINVAL; |
708 | } |
708 | } |
Line 709... | Line 709... | ||
709 | 709 | ||
710 | ret = ttm_read_lock(&vmaster->lock, true); |
710 | ret = ttm_read_lock(&dev_priv->reservation_sem, true); |
711 | if (unlikely(ret != 0)) |
711 | if (unlikely(ret != 0)) |
Line 712... | Line 712... | ||
712 | return ret; |
712 | return ret; |
713 | 713 | ||
Line 826... | Line 826... | ||
826 | } |
826 | } |
Line 827... | Line 827... | ||
827 | 827 | ||
828 | rep->sid = user_srf->prime.base.hash.key; |
828 | rep->sid = user_srf->prime.base.hash.key; |
Line 829... | Line 829... | ||
829 | vmw_resource_unreference(&res); |
829 | vmw_resource_unreference(&res); |
830 | 830 | ||
831 | ttm_read_unlock(&vmaster->lock); |
831 | ttm_read_unlock(&dev_priv->reservation_sem); |
832 | return 0; |
832 | return 0; |
833 | out_no_copy: |
833 | out_no_copy: |
834 | kfree(srf->offsets); |
834 | kfree(srf->offsets); |
835 | out_no_offsets: |
835 | out_no_offsets: |
836 | kfree(srf->sizes); |
836 | kfree(srf->sizes); |
837 | out_no_sizes: |
837 | out_no_sizes: |
838 | ttm_prime_object_kfree(user_srf, prime); |
838 | ttm_prime_object_kfree(user_srf, prime); |
839 | out_no_user_srf: |
839 | out_no_user_srf: |
840 | ttm_mem_global_free(vmw_mem_glob(dev_priv), size); |
840 | ttm_mem_global_free(vmw_mem_glob(dev_priv), size); |
- | 841 | out_unlock: |
|
841 | out_unlock: |
842 | ttm_read_unlock(&dev_priv->reservation_sem); |
842 | ttm_read_unlock(&vmaster->lock); |
843 | |
Line 843... | Line 844... | ||
843 | return ret; |
844 | return ret; |
844 | } |
845 | } |
Line 862... | Line 863... | ||
862 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; |
863 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; |
863 | struct vmw_surface *srf; |
864 | struct vmw_surface *srf; |
864 | struct vmw_user_surface *user_srf; |
865 | struct vmw_user_surface *user_srf; |
865 | struct drm_vmw_size __user *user_sizes; |
866 | struct drm_vmw_size __user *user_sizes; |
866 | struct ttm_base_object *base; |
867 | struct ttm_base_object *base; |
867 | int ret = -EINVAL; |
868 | int ret; |
868 | - | ||
869 | base = ttm_base_object_lookup_for_ref(dev_priv->tdev, req->sid); |
- | |
870 | if (unlikely(base == NULL)) { |
- | |
871 | DRM_ERROR("Could not find surface to reference.\n"); |
- | |
872 | return -EINVAL; |
- | |
873 | } |
- | |
Line 874... | Line 869... | ||
874 | 869 | ||
875 | if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE)) |
870 | ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid, |
- | 871 | req->handle_type, &base); |
|
- | 872 | if (unlikely(ret != 0)) |
|
Line 876... | Line 873... | ||
876 | goto out_bad_resource; |
873 | return ret; |
877 | 874 | ||
Line 878... | Line -... | ||
878 | user_srf = container_of(base, struct vmw_user_surface, prime.base); |
- | |
879 | srf = &user_srf->srf; |
- | |
880 | - | ||
881 | ret = ttm_ref_object_add(tfile, &user_srf->prime.base, |
- | |
882 | TTM_REF_USAGE, NULL); |
- | |
883 | if (unlikely(ret != 0)) { |
- | |
884 | DRM_ERROR("Could not add a reference to a surface.\n"); |
- | |
885 | goto out_no_reference; |
875 | user_srf = container_of(base, struct vmw_user_surface, prime.base); |
886 | } |
876 | srf = &user_srf->srf; |
887 | 877 | ||
888 | rep->flags = srf->flags; |
878 | rep->flags = srf->flags; |
889 | rep->format = srf->format; |
879 | rep->format = srf->format; |
Line 890... | Line 880... | ||
890 | memcpy(rep->mip_levels, srf->mip_levels, sizeof(srf->mip_levels)); |
880 | memcpy(rep->mip_levels, srf->mip_levels, sizeof(srf->mip_levels)); |
891 | user_sizes = (struct drm_vmw_size __user *)(unsigned long) |
881 | user_sizes = (struct drm_vmw_size __user *)(unsigned long) |
892 | rep->size_addr; |
882 | rep->size_addr; |
893 | 883 | ||
894 | if (user_sizes) |
884 | if (user_sizes) |
895 | ret = copy_to_user(user_sizes, srf->sizes, |
885 | ret = copy_to_user(user_sizes, &srf->base_size, |
- | 886 | sizeof(srf->base_size)); |
|
896 | srf->num_sizes * sizeof(*srf->sizes)); |
887 | if (unlikely(ret != 0)) { |
897 | if (unlikely(ret != 0)) { |
888 | DRM_ERROR("copy_to_user failed %p %u\n", |
898 | DRM_ERROR("copy_to_user failed %p %u\n", |
889 | user_sizes, srf->num_sizes); |
899 | user_sizes, srf->num_sizes); |
890 | ttm_ref_object_base_unref(tfile, base->hash.key, TTM_REF_USAGE); |
900 | ret = -EFAULT; |
891 | ret = -EFAULT; |