diff mbox

[libdrm,v2,1/2] intel: Add EXEC_OBJECT_SUPPORTS_48B_ADDRESS flag.

Message ID 1435764490-12029-1-git-send-email-michel.thierry@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Michel Thierry July 1, 2015, 3:28 p.m. UTC
Gen8+ supports 48-bit virtual addresses, but some objects must always be
allocated inside the 32-bit address range.

In specific, any resource used with flat/heapless (0x00000000-0xfffff000)
General State Heap (GSH) or Intruction State Heap (ISH) must be in a
32-bit range, because the General State Offset and Instruction State Offset
are limited to 32-bits.

Provide a flag to set when the 4GB limit is not necessary in a given bo.
48-bit range will only be used when explicitly requested.

Calls to the new drm_intel_bo_emit_reloc_48bit function will have this flag
set automatically, while calls to drm_intel_bo_emit_reloc will clear it.

v2: Make set/clear functions nops on pre-gen8 platforms, and use them
    internally in emit_reloc functions (Ben)
    s/48BADDRESS/48B_ADDRESS/ (Dave)

Cc: Ben Widawsky <ben@bwidawsk.net>
Cc: Dave Gordon <david.s.gordon@intel.com>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Michel Thierry <michel.thierry@intel.com>
---
 include/drm/i915_drm.h    |  3 ++-
 intel/intel_bufmgr.c      | 24 +++++++++++++++++++++
 intel/intel_bufmgr.h      |  8 ++++++-
 intel/intel_bufmgr_gem.c  | 54 +++++++++++++++++++++++++++++++++++++++++++----
 intel/intel_bufmgr_priv.h | 11 ++++++++++
 5 files changed, 94 insertions(+), 6 deletions(-)

Comments

Emil Velikov July 1, 2015, 5:06 p.m. UTC | #1
Hi Michel,

Although I cannot comment on the exact implementation I can give you
general some tips which you might find useful.

On 1 July 2015 at 16:28, Michel Thierry <michel.thierry@intel.com> wrote:
> Gen8+ supports 48-bit virtual addresses, but some objects must always be
> allocated inside the 32-bit address range.
>
> In specific, any resource used with flat/heapless (0x00000000-0xfffff000)
> General State Heap (GSH) or Intruction State Heap (ISH) must be in a
> 32-bit range, because the General State Offset and Instruction State Offset
> are limited to 32-bits.
>
> Provide a flag to set when the 4GB limit is not necessary in a given bo.
> 48-bit range will only be used when explicitly requested.
>
> Calls to the new drm_intel_bo_emit_reloc_48bit function will have this flag
> set automatically, while calls to drm_intel_bo_emit_reloc will clear it.
>
> v2: Make set/clear functions nops on pre-gen8 platforms, and use them
>     internally in emit_reloc functions (Ben)
>     s/48BADDRESS/48B_ADDRESS/ (Dave)
>
> Cc: Ben Widawsky <ben@bwidawsk.net>
> Cc: Dave Gordon <david.s.gordon@intel.com>
> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: Michel Thierry <michel.thierry@intel.com>
> ---
>  include/drm/i915_drm.h    |  3 ++-
>  intel/intel_bufmgr.c      | 24 +++++++++++++++++++++
>  intel/intel_bufmgr.h      |  8 ++++++-
>  intel/intel_bufmgr_gem.c  | 54 +++++++++++++++++++++++++++++++++++++++++++----
>  intel/intel_bufmgr_priv.h | 11 ++++++++++
>  5 files changed, 94 insertions(+), 6 deletions(-)
>
> diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
> index ded43b1..426b25c 100644
> --- a/include/drm/i915_drm.h
> +++ b/include/drm/i915_drm.h
> @@ -680,7 +680,8 @@ struct drm_i915_gem_exec_object2 {
>  #define EXEC_OBJECT_NEEDS_FENCE (1<<0)
>  #define EXEC_OBJECT_NEEDS_GTT  (1<<1)
>  #define EXEC_OBJECT_WRITE      (1<<2)
> -#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_WRITE<<1)
> +#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3)
> +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48B_ADDRESS<<1)
Perhaps you already know this but changes like these go in _after_ the
updated kernel header is part of linux-next or a released kernel
version.

>         __u64 flags;
>
>         __u64 rsvd1;
> diff --git a/intel/intel_bufmgr.c b/intel/intel_bufmgr.c
> index 14ea9f9..590a855 100644
> --- a/intel/intel_bufmgr.c
> +++ b/intel/intel_bufmgr.c
> @@ -188,6 +188,18 @@ drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count)
>         return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);
>  }
>
> +void drm_intel_bo_set_supports_48b_address(drm_intel_bo *bo)
> +{
> +       if (bo->bufmgr->bo_set_supports_48b_address)
> +               bo->bufmgr->bo_set_supports_48b_address(bo);
> +}
> +
> +void drm_intel_bo_clear_supports_48b_address(drm_intel_bo *bo)
> +{
> +       if (bo->bufmgr->bo_clear_supports_48b_address)
> +               bo->bufmgr->bo_clear_supports_48b_address(bo);
> +}
> +
>  int
>  drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name)
>  {
> @@ -202,6 +214,18 @@ drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
>                         drm_intel_bo *target_bo, uint32_t target_offset,
>                         uint32_t read_domains, uint32_t write_domain)
>  {
> +       drm_intel_bo_clear_supports_48b_address(target_bo);
> +       return bo->bufmgr->bo_emit_reloc(bo, offset,
> +                                        target_bo, target_offset,
> +                                        read_domains, write_domain);
> +}
> +
> +int
> +drm_intel_bo_emit_reloc_48bit(drm_intel_bo *bo, uint32_t offset,
> +                       drm_intel_bo *target_bo, uint32_t target_offset,
> +                       uint32_t read_domains, uint32_t write_domain)
> +{
> +       drm_intel_bo_set_supports_48b_address(target_bo);
>         return bo->bufmgr->bo_emit_reloc(bo, offset,
>                                          target_bo, target_offset,
>                                          read_domains, write_domain);
> diff --git a/intel/intel_bufmgr.h b/intel/intel_bufmgr.h
> index 285919e..62480cb 100644
> --- a/intel/intel_bufmgr.h
> +++ b/intel/intel_bufmgr.h
> @@ -87,7 +87,8 @@ struct _drm_intel_bo {
>         /**
>          * Last seen card virtual address (offset from the beginning of the
>          * aperture) for the object.  This should be used to fill relocation
> -        * entries when calling drm_intel_bo_emit_reloc()
> +        * entries when calling drm_intel_bo_emit_reloc() or
> +        * drm_intel_bo_emit_reloc_48bit()
>          */
>         uint64_t offset64;
>  };
> @@ -137,6 +138,8 @@ void drm_intel_bo_wait_rendering(drm_intel_bo *bo);
>
>  void drm_intel_bufmgr_set_debug(drm_intel_bufmgr *bufmgr, int enable_debug);
>  void drm_intel_bufmgr_destroy(drm_intel_bufmgr *bufmgr);
> +void drm_intel_bo_set_supports_48b_address(drm_intel_bo *bo);
> +void drm_intel_bo_clear_supports_48b_address(drm_intel_bo *bo);
Are these two are internal/implementation specific functions ? If so
please don't include them in this public header and annotate both
declaration and definition with drm_private.

>  int drm_intel_bo_exec(drm_intel_bo *bo, int used,
>                       struct drm_clip_rect *cliprects, int num_cliprects, int DR4);
>  int drm_intel_bo_mrb_exec(drm_intel_bo *bo, int used,
> @@ -147,6 +150,9 @@ int drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count);
>  int drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
>                             drm_intel_bo *target_bo, uint32_t target_offset,
>                             uint32_t read_domains, uint32_t write_domain);
> +int drm_intel_bo_emit_reloc_48bit(drm_intel_bo *bo, uint32_t offset,
> +                                 drm_intel_bo *target_bo, uint32_t target_offset,
> +                                 uint32_t read_domains, uint32_t write_domain);
Please add new (public) symbols to the test (intel-symbol-check). If
in doubt make check will give you a lovely message.

Patches that bump the version number are not normally posted to the
ML, but are committed as part of the release process (see RELEASING
for more info).

Cheers,
Emil
Michel Thierry July 2, 2015, 11:04 a.m. UTC | #2
On 7/1/2015 6:06 PM, Emil Velikov wrote:
> Hi Michel,
>
> Although I cannot comment on the exact implementation I can give you
> general some tips which you might find useful.
>
Hi Emil,

> On 1 July 2015 at 16:28, Michel Thierry <michel.thierry@intel.com> wrote:
>> Gen8+ supports 48-bit virtual addresses, but some objects must always be
>> allocated inside the 32-bit address range.
>>
>> diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
>> index ded43b1..426b25c 100644
>> --- a/include/drm/i915_drm.h
>> +++ b/include/drm/i915_drm.h
>> @@ -680,7 +680,8 @@ struct drm_i915_gem_exec_object2 {
>>   #define EXEC_OBJECT_NEEDS_FENCE (1<<0)
>>   #define EXEC_OBJECT_NEEDS_GTT  (1<<1)
>>   #define EXEC_OBJECT_WRITE      (1<<2)
>> -#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_WRITE<<1)
>> +#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3)
>> +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48B_ADDRESS<<1)
> Perhaps you already know this but changes like these go in _after_ the
> updated kernel header is part of linux-next or a released kernel
> version.
>

The kernel changes have just been reviewed in drm-intel. I included the 
userland patches (there's a mesa patch too) so more people could see the 
whole picture.

>>          __u64 flags;
>>
>>          __u64 rsvd1;
>> diff --git a/intel/intel_bufmgr.c b/intel/intel_bufmgr.c
>> index 14ea9f9..590a855 100644
>> --- a/intel/intel_bufmgr.c
>> +++ b/intel/intel_bufmgr.c
>> @@ -188,6 +188,18 @@ drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count)
>>          return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);
>>   }
>>
>> +void drm_intel_bo_set_supports_48b_address(drm_intel_bo *bo)
>> +{
>> +       if (bo->bufmgr->bo_set_supports_48b_address)
>> +               bo->bufmgr->bo_set_supports_48b_address(bo);
>> +}
>> +
>> +void drm_intel_bo_clear_supports_48b_address(drm_intel_bo *bo)
>> +{
>> +       if (bo->bufmgr->bo_clear_supports_48b_address)
>> +               bo->bufmgr->bo_clear_supports_48b_address(bo);
>> +}
>> +
>>   int
>>   drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name)
>>   {
>> @@ -202,6 +214,18 @@ drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
>>                          drm_intel_bo *target_bo, uint32_t target_offset,
>>                          uint32_t read_domains, uint32_t write_domain)
>>   {
>> +       drm_intel_bo_clear_supports_48b_address(target_bo);
>> +       return bo->bufmgr->bo_emit_reloc(bo, offset,
>> +                                        target_bo, target_offset,
>> +                                        read_domains, write_domain);
>> +}
>> +
>> +int
>> +drm_intel_bo_emit_reloc_48bit(drm_intel_bo *bo, uint32_t offset,
>> +                       drm_intel_bo *target_bo, uint32_t target_offset,
>> +                       uint32_t read_domains, uint32_t write_domain)
>> +{
>> +       drm_intel_bo_set_supports_48b_address(target_bo);
>>          return bo->bufmgr->bo_emit_reloc(bo, offset,
>>                                           target_bo, target_offset,
>>                                           read_domains, write_domain);
>> diff --git a/intel/intel_bufmgr.h b/intel/intel_bufmgr.h
>> index 285919e..62480cb 100644
>> --- a/intel/intel_bufmgr.h
>> +++ b/intel/intel_bufmgr.h
>> @@ -87,7 +87,8 @@ struct _drm_intel_bo {
>>          /**
>>           * Last seen card virtual address (offset from the beginning of the
>>           * aperture) for the object.  This should be used to fill relocation
>> -        * entries when calling drm_intel_bo_emit_reloc()
>> +        * entries when calling drm_intel_bo_emit_reloc() or
>> +        * drm_intel_bo_emit_reloc_48bit()
>>           */
>>          uint64_t offset64;
>>   };
>> @@ -137,6 +138,8 @@ void drm_intel_bo_wait_rendering(drm_intel_bo *bo);
>>
>>   void drm_intel_bufmgr_set_debug(drm_intel_bufmgr *bufmgr, int enable_debug);
>>   void drm_intel_bufmgr_destroy(drm_intel_bufmgr *bufmgr);
>> +void drm_intel_bo_set_supports_48b_address(drm_intel_bo *bo);
>> +void drm_intel_bo_clear_supports_48b_address(drm_intel_bo *bo);
> Are these two are internal/implementation specific functions ? If so
> please don't include them in this public header and annotate both
> declaration and definition with drm_private.
>
>>   int drm_intel_bo_exec(drm_intel_bo *bo, int used,
>>                        struct drm_clip_rect *cliprects, int num_cliprects, int DR4);
>>   int drm_intel_bo_mrb_exec(drm_intel_bo *bo, int used,
>> @@ -147,6 +150,9 @@ int drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count);
>>   int drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
>>                              drm_intel_bo *target_bo, uint32_t target_offset,
>>                              uint32_t read_domains, uint32_t write_domain);
>> +int drm_intel_bo_emit_reloc_48bit(drm_intel_bo *bo, uint32_t offset,
>> +                                 drm_intel_bo *target_bo, uint32_t target_offset,
>> +                                 uint32_t read_domains, uint32_t write_domain);
> Please add new (public) symbols to the test (intel-symbol-check). If
> in doubt make check will give you a lovely message.
>
> Patches that bump the version number are not normally posted to the
> ML, but are committed as part of the release process (see RELEASING
> for more info).

I'll update the intel-symbol-check and follow the release process after 
the kernel patch is merged.

Just to confirm, anyone can push to git://anongit.freedesktop.org/mesa/drm ?

Thanks for the tips,

-Michel
>
> Cheers,
> Emil
>
diff mbox

Patch

diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index ded43b1..426b25c 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -680,7 +680,8 @@  struct drm_i915_gem_exec_object2 {
 #define EXEC_OBJECT_NEEDS_FENCE (1<<0)
 #define EXEC_OBJECT_NEEDS_GTT	(1<<1)
 #define EXEC_OBJECT_WRITE	(1<<2)
-#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_WRITE<<1)
+#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3)
+#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48B_ADDRESS<<1)
 	__u64 flags;
 
 	__u64 rsvd1;
diff --git a/intel/intel_bufmgr.c b/intel/intel_bufmgr.c
index 14ea9f9..590a855 100644
--- a/intel/intel_bufmgr.c
+++ b/intel/intel_bufmgr.c
@@ -188,6 +188,18 @@  drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count)
 	return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);
 }
 
+void drm_intel_bo_set_supports_48b_address(drm_intel_bo *bo)
+{
+	if (bo->bufmgr->bo_set_supports_48b_address)
+		bo->bufmgr->bo_set_supports_48b_address(bo);
+}
+
+void drm_intel_bo_clear_supports_48b_address(drm_intel_bo *bo)
+{
+	if (bo->bufmgr->bo_clear_supports_48b_address)
+		bo->bufmgr->bo_clear_supports_48b_address(bo);
+}
+
 int
 drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name)
 {
@@ -202,6 +214,18 @@  drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
 			drm_intel_bo *target_bo, uint32_t target_offset,
 			uint32_t read_domains, uint32_t write_domain)
 {
+	drm_intel_bo_clear_supports_48b_address(target_bo);
+	return bo->bufmgr->bo_emit_reloc(bo, offset,
+					 target_bo, target_offset,
+					 read_domains, write_domain);
+}
+
+int
+drm_intel_bo_emit_reloc_48bit(drm_intel_bo *bo, uint32_t offset,
+			drm_intel_bo *target_bo, uint32_t target_offset,
+			uint32_t read_domains, uint32_t write_domain)
+{
+	drm_intel_bo_set_supports_48b_address(target_bo);
 	return bo->bufmgr->bo_emit_reloc(bo, offset,
 					 target_bo, target_offset,
 					 read_domains, write_domain);
diff --git a/intel/intel_bufmgr.h b/intel/intel_bufmgr.h
index 285919e..62480cb 100644
--- a/intel/intel_bufmgr.h
+++ b/intel/intel_bufmgr.h
@@ -87,7 +87,8 @@  struct _drm_intel_bo {
 	/**
 	 * Last seen card virtual address (offset from the beginning of the
 	 * aperture) for the object.  This should be used to fill relocation
-	 * entries when calling drm_intel_bo_emit_reloc()
+	 * entries when calling drm_intel_bo_emit_reloc() or
+	 * drm_intel_bo_emit_reloc_48bit()
 	 */
 	uint64_t offset64;
 };
@@ -137,6 +138,8 @@  void drm_intel_bo_wait_rendering(drm_intel_bo *bo);
 
 void drm_intel_bufmgr_set_debug(drm_intel_bufmgr *bufmgr, int enable_debug);
 void drm_intel_bufmgr_destroy(drm_intel_bufmgr *bufmgr);
+void drm_intel_bo_set_supports_48b_address(drm_intel_bo *bo);
+void drm_intel_bo_clear_supports_48b_address(drm_intel_bo *bo);
 int drm_intel_bo_exec(drm_intel_bo *bo, int used,
 		      struct drm_clip_rect *cliprects, int num_cliprects, int DR4);
 int drm_intel_bo_mrb_exec(drm_intel_bo *bo, int used,
@@ -147,6 +150,9 @@  int drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count);
 int drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
 			    drm_intel_bo *target_bo, uint32_t target_offset,
 			    uint32_t read_domains, uint32_t write_domain);
+int drm_intel_bo_emit_reloc_48bit(drm_intel_bo *bo, uint32_t offset,
+				  drm_intel_bo *target_bo, uint32_t target_offset,
+				  uint32_t read_domains, uint32_t write_domain);
 int drm_intel_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset,
 				  drm_intel_bo *target_bo,
 				  uint32_t target_offset,
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index 60c06fc..e3e2b0e 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -143,6 +143,7 @@  typedef struct _drm_intel_bufmgr_gem {
 } drm_intel_bufmgr_gem;
 
 #define DRM_INTEL_RELOC_FENCE (1<<0)
+#define DRM_INTEL_RELOC_SUPPORTS_48B_ADDRESS (2<<0)
 
 typedef struct _drm_intel_reloc_target_info {
 	drm_intel_bo *bo;
@@ -240,6 +241,14 @@  struct _drm_intel_bo_gem {
 	bool is_userptr;
 
 	/**
+	 * Boolean of whether this buffer can be in the whole 48-bit address.
+	 *
+	 * By default, buffers will be keep in a 32-bit range, unless this
+	 * flag is explicitly set.
+	 */
+	bool supports_48b_address;
+
+	/**
 	 * Size in bytes of this buffer and its relocation descendents.
 	 *
 	 * Used to avoid costly tree walking in
@@ -471,13 +480,18 @@  drm_intel_add_validate_buffer(drm_intel_bo *bo)
 }
 
 static void
-drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
+drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence,
+			       int supports_48b_address)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
 	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
 	int index;
 
 	if (bo_gem->validate_index != -1) {
+		if (supports_48b_address) {
+			bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |=
+				EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+		}
 		if (need_fence)
 			bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |=
 				EXEC_OBJECT_NEEDS_FENCE;
@@ -516,6 +530,10 @@  drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
 		bufmgr_gem->exec2_objects[index].flags |=
 			EXEC_OBJECT_NEEDS_FENCE;
 	}
+	if (supports_48b_address) {
+		bufmgr_gem->exec2_objects[index].flags |=
+			EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+	}
 	bufmgr_gem->exec_count++;
 }
 
@@ -1931,11 +1949,33 @@  do_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
 	else
 		bo_gem->reloc_target_info[bo_gem->reloc_count].flags = 0;
 
+	if (target_bo_gem->supports_48b_address)
+		bo_gem->reloc_target_info[bo_gem->reloc_count].flags |=
+			DRM_INTEL_RELOC_SUPPORTS_48B_ADDRESS;
+
 	bo_gem->reloc_count++;
 
 	return 0;
 }
 
+static void drm_intel_gem_bo_set_supports_48b_address(drm_intel_bo *bo)
+{
+	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
+	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
+
+	if (bufmgr_gem->gen >= 8)
+		bo_gem->supports_48b_address = 1;
+}
+
+static void drm_intel_gem_bo_clear_supports_48b_address(drm_intel_bo *bo)
+{
+	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
+	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
+
+	if (bufmgr_gem->gen >= 8)
+		bo_gem->supports_48b_address = 0;
+}
+
 static int
 drm_intel_gem_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
 			    drm_intel_bo *target_bo, uint32_t target_offset,
@@ -2049,7 +2089,7 @@  drm_intel_gem_bo_process_reloc2(drm_intel_bo *bo)
 
 	for (i = 0; i < bo_gem->reloc_count; i++) {
 		drm_intel_bo *target_bo = bo_gem->reloc_target_info[i].bo;
-		int need_fence;
+		int need_fence, supports_48b_addr;
 
 		if (target_bo == bo)
 			continue;
@@ -2062,8 +2102,12 @@  drm_intel_gem_bo_process_reloc2(drm_intel_bo *bo)
 		need_fence = (bo_gem->reloc_target_info[i].flags &
 			      DRM_INTEL_RELOC_FENCE);
 
+		supports_48b_addr = (bo_gem->reloc_target_info[i].flags &
+				    DRM_INTEL_RELOC_SUPPORTS_48B_ADDRESS);
+
 		/* Add the target to the validate list */
-		drm_intel_add_validate_buffer2(target_bo, need_fence);
+		drm_intel_add_validate_buffer2(target_bo, need_fence,
+					       supports_48b_addr);
 	}
 }
 
@@ -2508,7 +2552,7 @@  do_exec2(drm_intel_bo *bo, int used, drm_intel_context *ctx,
 	/* Add the batch buffer to the validation list.  There are no relocations
 	 * pointing to it.
 	 */
-	drm_intel_add_validate_buffer2(bo, 0);
+	drm_intel_add_validate_buffer2(bo, 0, 0);
 
 	memclear(execbuf);
 	execbuf.buffers_ptr = (uintptr_t)bufmgr_gem->exec2_objects;
@@ -3657,6 +3701,8 @@  drm_intel_bufmgr_gem_init(int fd, int batch_size)
 	bufmgr_gem->bufmgr.bo_wait_rendering = drm_intel_gem_bo_wait_rendering;
 	bufmgr_gem->bufmgr.bo_emit_reloc = drm_intel_gem_bo_emit_reloc;
 	bufmgr_gem->bufmgr.bo_emit_reloc_fence = drm_intel_gem_bo_emit_reloc_fence;
+	bufmgr_gem->bufmgr.bo_set_supports_48b_address = drm_intel_gem_bo_set_supports_48b_address;
+	bufmgr_gem->bufmgr.bo_clear_supports_48b_address = drm_intel_gem_bo_clear_supports_48b_address;
 	bufmgr_gem->bufmgr.bo_pin = drm_intel_gem_bo_pin;
 	bufmgr_gem->bufmgr.bo_unpin = drm_intel_gem_bo_unpin;
 	bufmgr_gem->bufmgr.bo_get_tiling = drm_intel_gem_bo_get_tiling;
diff --git a/intel/intel_bufmgr_priv.h b/intel/intel_bufmgr_priv.h
index 59ebd18..774fa02 100644
--- a/intel/intel_bufmgr_priv.h
+++ b/intel/intel_bufmgr_priv.h
@@ -152,6 +152,17 @@  struct _drm_intel_bufmgr {
 	void (*destroy) (drm_intel_bufmgr *bufmgr);
 
 	/**
+	 * Set/Clear 48-bit address support flag in a given bo.
+	 *
+	 * Any resource used with flat/heapless (0x00000000-0xfffff000)
+	 * General State Heap (GSH) or Intructions State Heap (ISH) must
+	 * be in a 32-bit range. 48-bit range will only be used when explicitly
+	 * requested.
+	 */
+	void (*bo_set_supports_48b_address) (drm_intel_bo *bo);
+	void (*bo_clear_supports_48b_address) (drm_intel_bo *bo);
+
+	/**
 	 * Add relocation entry in reloc_buf, which will be updated with the
 	 * target buffer's real offset on on command submission.
 	 *