drm-fixes for 6.18-rc3
- drm_panic: bunch of size calculation fixes - pantor: fix kernel panic on partial gpu va unmap - rockchip: hdmi hotplug setup fix - amdgpu: dp mst, dc/display fixes - i915: fix panic structure leak - xe: madvise uapi fix, wq alloc error, vma flag handling fix -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEciDa6W7nX7VwIxa1EpWk/0GBDXwFAmj756wACgkQEpWk/0GB DXz3DQ//QDayceTkS9d7lUSRP7nkGpaq4bzugKTjbuDgvpmcWHbgaDyNnB+jyAFw dXW0OqGnxS0vzbcFhjtpbA7pkaOqb2FvY0aidJ5v9VV/dpfAH1FA3PndVMorVZoF +CsETtuGyqI3eQyni49wc2xpnaUr4WLydE4vUKyVG6xm9zn5ELMXAvz67P+UwtC6 4TlMKROzf34ZJB5OHMYGbSpe+e1oo6+EZNpV/gKd6xJrYyVdhpwUPr24I4xuC4vr iWIKCgpID6qfKjktDZJLFZOrePRf5TOiGw7JRTNzSsFkiOdbYknoBmIPbKIZII/q 7iN9kcmHCAlIXmO3hSY0Ocwk2FnQITHGPmtQsdWVnuv4XGHGZXuQlyF2gsbaoUbg tokc0gsUGaeqSZHJJrm96tI5onqgUYjh2Ig+sVsgvvMsDt3JWg46WpYNmKmtvwO+ +BsNaBIyKsI7BGl2OwHEQg7cYYMcosNbXUYJO6Zi6pe1DFXgIWE6UgXIpCsOaZka l1SopXiGHwsGOB23xkiqrZytZ6uzcyx2dmT45IF+xAu6IhotQ7JeoBi+dMCYkMXl PzsbUSmhKtpCG8hgjgFEdL7JHRYR7tIeqyzYpw8thG5VzbmejCzf1d0knUH9VdPx V/3mSbCxoCMosP42VJOKRV2oOonZchnnU+dwbYdRIysmUHgLwmQ= =EjON -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2025-10-24' of https://gitlab.freedesktop.org/drm/kernel Pull drm fixes from Simona Vetter: "Very quiet, all just small stuff and nothing scary pending to my knowledge: - drm_panic: bunch of size calculation fixes - pantor: fix kernel panic on partial gpu va unmap - rockchip: hdmi hotplug setup fix - amdgpu: dp mst, dc/display fixes - i915: fix panic structure leak - xe: madvise uapi fix, wq alloc error, vma flag handling fix" * tag 'drm-fixes-2025-10-24' of https://gitlab.freedesktop.org/drm/kernel: drm/xe: Check return value of GGTT workqueue allocation drm/amd/display: use GFP_NOWAIT for allocation in interrupt handler drm/amd/display: increase max link count and fix link->enc NULL pointer access drm/amd/display: Fix NULL pointer dereference drm/panic: Fix 24bit pixel crossing page boundaries drm/panic: Fix divide by 0 if the screen width < font width drm/panic: Fix kmsg text drawing rectangle drm/panic: Fix qr_code, ensure vmargin is positive drm/panic: Fix overlap between qr code and logo drm/panic: Fix drawing the logo on a small narrow screen drm/xe/uapi: Hide the madvise autoreset behind a VM_BIND flag drm/xe: Retain vma flags when recreating and splitting vmas for madvise drm/i915/panic: fix panic structure allocation memory leak drm/panthor: Fix kernel panic on partial unmap of a GPU VA region drm/rockchip: dw_hdmi: use correct SCLIN mask for RK3228pull/1354/merge
commit
3d08a425d2
|
|
@ -551,13 +551,13 @@ static void schedule_dc_vmin_vmax(struct amdgpu_device *adev,
|
||||||
struct dc_stream_state *stream,
|
struct dc_stream_state *stream,
|
||||||
struct dc_crtc_timing_adjust *adjust)
|
struct dc_crtc_timing_adjust *adjust)
|
||||||
{
|
{
|
||||||
struct vupdate_offload_work *offload_work = kzalloc(sizeof(*offload_work), GFP_KERNEL);
|
struct vupdate_offload_work *offload_work = kzalloc(sizeof(*offload_work), GFP_NOWAIT);
|
||||||
if (!offload_work) {
|
if (!offload_work) {
|
||||||
drm_dbg_driver(adev_to_drm(adev), "Failed to allocate vupdate_offload_work\n");
|
drm_dbg_driver(adev_to_drm(adev), "Failed to allocate vupdate_offload_work\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dc_crtc_timing_adjust *adjust_copy = kzalloc(sizeof(*adjust_copy), GFP_KERNEL);
|
struct dc_crtc_timing_adjust *adjust_copy = kzalloc(sizeof(*adjust_copy), GFP_NOWAIT);
|
||||||
if (!adjust_copy) {
|
if (!adjust_copy) {
|
||||||
drm_dbg_driver(adev_to_drm(adev), "Failed to allocate adjust_copy\n");
|
drm_dbg_driver(adev_to_drm(adev), "Failed to allocate adjust_copy\n");
|
||||||
kfree(offload_work);
|
kfree(offload_work);
|
||||||
|
|
|
||||||
|
|
@ -200,6 +200,9 @@ void dcn401_init_hw(struct dc *dc)
|
||||||
*/
|
*/
|
||||||
struct dc_link *link = dc->links[i];
|
struct dc_link *link = dc->links[i];
|
||||||
|
|
||||||
|
if (link->ep_type != DISPLAY_ENDPOINT_PHY)
|
||||||
|
continue;
|
||||||
|
|
||||||
link->link_enc->funcs->hw_init(link->link_enc);
|
link->link_enc->funcs->hw_init(link->link_enc);
|
||||||
|
|
||||||
/* Check for enabled DIG to identify enabled display */
|
/* Check for enabled DIG to identify enabled display */
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,13 @@
|
||||||
*/
|
*/
|
||||||
#define MAX_PIPES 6
|
#define MAX_PIPES 6
|
||||||
#define MAX_PHANTOM_PIPES (MAX_PIPES / 2)
|
#define MAX_PHANTOM_PIPES (MAX_PIPES / 2)
|
||||||
#define MAX_LINKS (MAX_PIPES * 2 +2)
|
|
||||||
|
#define MAX_DPIA 6
|
||||||
|
#define MAX_CONNECTOR 6
|
||||||
|
#define MAX_VIRTUAL_LINKS 4
|
||||||
|
|
||||||
|
#define MAX_LINKS (MAX_DPIA + MAX_CONNECTOR + MAX_VIRTUAL_LINKS)
|
||||||
|
|
||||||
#define MAX_DIG_LINK_ENCODERS 7
|
#define MAX_DIG_LINK_ENCODERS 7
|
||||||
#define MAX_DWB_PIPES 1
|
#define MAX_DWB_PIPES 1
|
||||||
#define MAX_HPO_DP2_ENCODERS 4
|
#define MAX_HPO_DP2_ENCODERS 4
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ static void dp_retrain_link_dp_test(struct dc_link *link,
|
||||||
struct audio_output audio_output[MAX_PIPES];
|
struct audio_output audio_output[MAX_PIPES];
|
||||||
struct dc_stream_state *streams_on_link[MAX_PIPES];
|
struct dc_stream_state *streams_on_link[MAX_PIPES];
|
||||||
int num_streams_on_link = 0;
|
int num_streams_on_link = 0;
|
||||||
|
struct dc *dc = (struct dc *)link->dc;
|
||||||
|
|
||||||
needs_divider_update = (link->dc->link_srv->dp_get_encoding_format(link_setting) !=
|
needs_divider_update = (link->dc->link_srv->dp_get_encoding_format(link_setting) !=
|
||||||
link->dc->link_srv->dp_get_encoding_format((const struct dc_link_settings *) &link->cur_link_settings));
|
link->dc->link_srv->dp_get_encoding_format((const struct dc_link_settings *) &link->cur_link_settings));
|
||||||
|
|
@ -150,7 +151,7 @@ static void dp_retrain_link_dp_test(struct dc_link *link,
|
||||||
if (streams_on_link[i] && streams_on_link[i]->link && streams_on_link[i]->link == link) {
|
if (streams_on_link[i] && streams_on_link[i]->link && streams_on_link[i]->link == link) {
|
||||||
stream_update.stream = streams_on_link[i];
|
stream_update.stream = streams_on_link[i];
|
||||||
stream_update.dpms_off = &dpms_off;
|
stream_update.dpms_off = &dpms_off;
|
||||||
dc_update_planes_and_stream(state->clk_mgr->ctx->dc, NULL, 0, streams_on_link[i], &stream_update);
|
dc_update_planes_and_stream(dc, NULL, 0, streams_on_link[i], &stream_update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,33 @@ static void drm_panic_write_pixel24(void *vaddr, unsigned int offset, u32 color)
|
||||||
*p = color & 0xff;
|
*p = color & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special case if the pixel crosses page boundaries
|
||||||
|
*/
|
||||||
|
static void drm_panic_write_pixel24_xpage(void *vaddr, struct page *next_page,
|
||||||
|
unsigned int offset, u32 color)
|
||||||
|
{
|
||||||
|
u8 *vaddr2;
|
||||||
|
u8 *p = vaddr + offset;
|
||||||
|
|
||||||
|
vaddr2 = kmap_local_page_try_from_panic(next_page);
|
||||||
|
|
||||||
|
*p++ = color & 0xff;
|
||||||
|
color >>= 8;
|
||||||
|
|
||||||
|
if (offset == PAGE_SIZE - 1)
|
||||||
|
p = vaddr2;
|
||||||
|
|
||||||
|
*p++ = color & 0xff;
|
||||||
|
color >>= 8;
|
||||||
|
|
||||||
|
if (offset == PAGE_SIZE - 2)
|
||||||
|
p = vaddr2;
|
||||||
|
|
||||||
|
*p = color & 0xff;
|
||||||
|
kunmap_local(vaddr2);
|
||||||
|
}
|
||||||
|
|
||||||
static void drm_panic_write_pixel32(void *vaddr, unsigned int offset, u32 color)
|
static void drm_panic_write_pixel32(void *vaddr, unsigned int offset, u32 color)
|
||||||
{
|
{
|
||||||
u32 *p = vaddr + offset;
|
u32 *p = vaddr + offset;
|
||||||
|
|
@ -231,7 +258,14 @@ static void drm_panic_blit_page(struct page **pages, unsigned int dpitch,
|
||||||
page = new_page;
|
page = new_page;
|
||||||
vaddr = kmap_local_page_try_from_panic(pages[page]);
|
vaddr = kmap_local_page_try_from_panic(pages[page]);
|
||||||
}
|
}
|
||||||
if (vaddr)
|
if (!vaddr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Special case for 24bit, as a pixel might cross page boundaries
|
||||||
|
if (cpp == 3 && offset + 3 > PAGE_SIZE)
|
||||||
|
drm_panic_write_pixel24_xpage(vaddr, pages[page + 1],
|
||||||
|
offset, fg32);
|
||||||
|
else
|
||||||
drm_panic_write_pixel(vaddr, offset, fg32, cpp);
|
drm_panic_write_pixel(vaddr, offset, fg32, cpp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -321,6 +355,14 @@ static void drm_panic_fill_page(struct page **pages, unsigned int dpitch,
|
||||||
page = new_page;
|
page = new_page;
|
||||||
vaddr = kmap_local_page_try_from_panic(pages[page]);
|
vaddr = kmap_local_page_try_from_panic(pages[page]);
|
||||||
}
|
}
|
||||||
|
if (!vaddr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Special case for 24bit, as a pixel might cross page boundaries
|
||||||
|
if (cpp == 3 && offset + 3 > PAGE_SIZE)
|
||||||
|
drm_panic_write_pixel24_xpage(vaddr, pages[page + 1],
|
||||||
|
offset, color);
|
||||||
|
else
|
||||||
drm_panic_write_pixel(vaddr, offset, color, cpp);
|
drm_panic_write_pixel(vaddr, offset, color, cpp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -429,6 +471,9 @@ static void drm_panic_logo_rect(struct drm_rect *rect, const struct font_desc *f
|
||||||
static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect,
|
static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect,
|
||||||
const struct font_desc *font, u32 fg_color)
|
const struct font_desc *font, u32 fg_color)
|
||||||
{
|
{
|
||||||
|
if (rect->x2 > sb->width || rect->y2 > sb->height)
|
||||||
|
return;
|
||||||
|
|
||||||
if (logo_mono)
|
if (logo_mono)
|
||||||
drm_panic_blit(sb, rect, logo_mono->data,
|
drm_panic_blit(sb, rect, logo_mono->data,
|
||||||
DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color);
|
DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color);
|
||||||
|
|
@ -477,7 +522,7 @@ static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_
|
||||||
struct drm_panic_line *line, int yoffset, u32 fg_color)
|
struct drm_panic_line *line, int yoffset, u32 fg_color)
|
||||||
{
|
{
|
||||||
int chars_per_row = sb->width / font->width;
|
int chars_per_row = sb->width / font->width;
|
||||||
struct drm_rect r_txt = DRM_RECT_INIT(0, yoffset, sb->width, sb->height);
|
struct drm_rect r_txt = DRM_RECT_INIT(0, yoffset, sb->width, font->height);
|
||||||
struct drm_panic_line line_wrap;
|
struct drm_panic_line line_wrap;
|
||||||
|
|
||||||
if (line->len > chars_per_row) {
|
if (line->len > chars_per_row) {
|
||||||
|
|
@ -520,7 +565,7 @@ static void draw_panic_static_kmsg(struct drm_scanout_buffer *sb)
|
||||||
struct drm_panic_line line;
|
struct drm_panic_line line;
|
||||||
int yoffset;
|
int yoffset;
|
||||||
|
|
||||||
if (!font)
|
if (!font || font->width > sb->width)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
yoffset = sb->height - font->height - (sb->height % font->height) / 2;
|
yoffset = sb->height - font->height - (sb->height % font->height) / 2;
|
||||||
|
|
@ -733,7 +778,10 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
|
||||||
pr_debug("QR width %d and scale %d\n", qr_width, scale);
|
pr_debug("QR width %d and scale %d\n", qr_width, scale);
|
||||||
r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale);
|
r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale);
|
||||||
|
|
||||||
v_margin = (sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg)) / 5;
|
v_margin = sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg);
|
||||||
|
if (v_margin < 0)
|
||||||
|
return -ENOSPC;
|
||||||
|
v_margin /= 5;
|
||||||
|
|
||||||
drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin);
|
drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin);
|
||||||
r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale,
|
r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale,
|
||||||
|
|
@ -746,7 +794,7 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
|
||||||
/* Fill with the background color, and draw text on top */
|
/* Fill with the background color, and draw text on top */
|
||||||
drm_panic_fill(sb, &r_screen, bg_color);
|
drm_panic_fill(sb, &r_screen, bg_color);
|
||||||
|
|
||||||
if (!drm_rect_overlap(&r_logo, &r_msg) && !drm_rect_overlap(&r_logo, &r_qr))
|
if (!drm_rect_overlap(&r_logo, &r_msg) && !drm_rect_overlap(&r_logo, &r_qr_canvas))
|
||||||
drm_panic_logo_draw(sb, &r_logo, font, fg_color);
|
drm_panic_logo_draw(sb, &r_logo, font, fg_color);
|
||||||
|
|
||||||
draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color);
|
draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color);
|
||||||
|
|
|
||||||
|
|
@ -2117,6 +2117,7 @@ static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
|
||||||
|
|
||||||
intel_frontbuffer_put(intel_fb->frontbuffer);
|
intel_frontbuffer_put(intel_fb->frontbuffer);
|
||||||
|
|
||||||
|
kfree(intel_fb->panic);
|
||||||
kfree(intel_fb);
|
kfree(intel_fb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2215,16 +2216,22 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||||
struct intel_display *display = to_intel_display(obj->dev);
|
struct intel_display *display = to_intel_display(obj->dev);
|
||||||
struct drm_framebuffer *fb = &intel_fb->base;
|
struct drm_framebuffer *fb = &intel_fb->base;
|
||||||
u32 max_stride;
|
u32 max_stride;
|
||||||
int ret = -EINVAL;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
intel_fb->panic = intel_panic_alloc();
|
||||||
|
if (!intel_fb->panic)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* intel_frontbuffer_get() must be done before
|
* intel_frontbuffer_get() must be done before
|
||||||
* intel_fb_bo_framebuffer_init() to avoid set_tiling vs. addfb race.
|
* intel_fb_bo_framebuffer_init() to avoid set_tiling vs. addfb race.
|
||||||
*/
|
*/
|
||||||
intel_fb->frontbuffer = intel_frontbuffer_get(obj);
|
intel_fb->frontbuffer = intel_frontbuffer_get(obj);
|
||||||
if (!intel_fb->frontbuffer)
|
if (!intel_fb->frontbuffer) {
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto err_free_panic;
|
||||||
|
}
|
||||||
|
|
||||||
ret = intel_fb_bo_framebuffer_init(fb, obj, mode_cmd);
|
ret = intel_fb_bo_framebuffer_init(fb, obj, mode_cmd);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
@ -2323,6 +2330,9 @@ err_bo_framebuffer_fini:
|
||||||
intel_fb_bo_framebuffer_fini(obj);
|
intel_fb_bo_framebuffer_fini(obj);
|
||||||
err_frontbuffer_put:
|
err_frontbuffer_put:
|
||||||
intel_frontbuffer_put(intel_fb->frontbuffer);
|
intel_frontbuffer_put(intel_fb->frontbuffer);
|
||||||
|
err_free_panic:
|
||||||
|
kfree(intel_fb->panic);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2349,20 +2359,11 @@ intel_user_framebuffer_create(struct drm_device *dev,
|
||||||
struct intel_framebuffer *intel_framebuffer_alloc(void)
|
struct intel_framebuffer *intel_framebuffer_alloc(void)
|
||||||
{
|
{
|
||||||
struct intel_framebuffer *intel_fb;
|
struct intel_framebuffer *intel_fb;
|
||||||
struct intel_panic *panic;
|
|
||||||
|
|
||||||
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
|
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
|
||||||
if (!intel_fb)
|
if (!intel_fb)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
panic = intel_panic_alloc();
|
|
||||||
if (!panic) {
|
|
||||||
kfree(intel_fb);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
intel_fb->panic = panic;
|
|
||||||
|
|
||||||
return intel_fb;
|
return intel_fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1175,10 +1175,14 @@ panthor_vm_op_ctx_prealloc_vmas(struct panthor_vm_op_ctx *op_ctx)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP:
|
case DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP:
|
||||||
/* Partial unmaps might trigger a remap with either a prev or a next VA,
|
/* Two VMAs can be needed for an unmap, as an unmap can happen
|
||||||
* but not both.
|
* in the middle of a drm_gpuva, requiring a remap with both
|
||||||
|
* prev & next VA. Or an unmap can span more than one drm_gpuva
|
||||||
|
* where the first and last ones are covered partially, requring
|
||||||
|
* a remap for the first with a prev VA and remap for the last
|
||||||
|
* with a next VA.
|
||||||
*/
|
*/
|
||||||
vma_count = 1;
|
vma_count = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -361,7 +361,7 @@ static void dw_hdmi_rk3228_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
|
||||||
|
|
||||||
regmap_write(hdmi->regmap, RK3228_GRF_SOC_CON2,
|
regmap_write(hdmi->regmap, RK3228_GRF_SOC_CON2,
|
||||||
FIELD_PREP_WM16(RK3228_HDMI_SDAIN_MSK, 1) |
|
FIELD_PREP_WM16(RK3228_HDMI_SDAIN_MSK, 1) |
|
||||||
FIELD_PREP_WM16(RK3328_HDMI_SCLIN_MSK, 1));
|
FIELD_PREP_WM16(RK3228_HDMI_SCLIN_MSK, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum drm_connector_status
|
static enum drm_connector_status
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,9 @@ int xe_ggtt_init_early(struct xe_ggtt *ggtt)
|
||||||
ggtt->pt_ops = &xelp_pt_ops;
|
ggtt->pt_ops = &xelp_pt_ops;
|
||||||
|
|
||||||
ggtt->wq = alloc_workqueue("xe-ggtt-wq", 0, WQ_MEM_RECLAIM);
|
ggtt->wq = alloc_workqueue("xe-ggtt-wq", 0, WQ_MEM_RECLAIM);
|
||||||
|
if (!ggtt->wq)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
__xe_ggtt_init_early(ggtt, xe_wopcm_size(xe));
|
__xe_ggtt_init_early(ggtt, xe_wopcm_size(xe));
|
||||||
|
|
||||||
err = drmm_add_action_or_reset(&xe->drm, ggtt_fini_early, ggtt);
|
err = drmm_add_action_or_reset(&xe->drm, ggtt_fini_early, ggtt);
|
||||||
|
|
|
||||||
|
|
@ -2022,7 +2022,7 @@ static int op_prepare(struct xe_vm *vm,
|
||||||
case DRM_GPUVA_OP_MAP:
|
case DRM_GPUVA_OP_MAP:
|
||||||
if ((!op->map.immediate && xe_vm_in_fault_mode(vm) &&
|
if ((!op->map.immediate && xe_vm_in_fault_mode(vm) &&
|
||||||
!op->map.invalidate_on_bind) ||
|
!op->map.invalidate_on_bind) ||
|
||||||
op->map.is_cpu_addr_mirror)
|
(op->map.vma_flags & XE_VMA_SYSTEM_ALLOCATOR))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
err = bind_op_prepare(vm, tile, pt_update_ops, op->map.vma,
|
err = bind_op_prepare(vm, tile, pt_update_ops, op->map.vma,
|
||||||
|
|
@ -2252,7 +2252,7 @@ static void op_commit(struct xe_vm *vm,
|
||||||
switch (op->base.op) {
|
switch (op->base.op) {
|
||||||
case DRM_GPUVA_OP_MAP:
|
case DRM_GPUVA_OP_MAP:
|
||||||
if ((!op->map.immediate && xe_vm_in_fault_mode(vm)) ||
|
if ((!op->map.immediate && xe_vm_in_fault_mode(vm)) ||
|
||||||
op->map.is_cpu_addr_mirror)
|
(op->map.vma_flags & XE_VMA_SYSTEM_ALLOCATOR))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
bind_op_commit(vm, tile, pt_update_ops, op->map.vma, fence,
|
bind_op_commit(vm, tile, pt_update_ops, op->map.vma, fence,
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,11 @@ static int xe_svm_range_set_default_attr(struct xe_vm *vm, u64 range_start, u64
|
||||||
if (!vma)
|
if (!vma)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!(vma->gpuva.flags & XE_VMA_MADV_AUTORESET)) {
|
||||||
|
drm_dbg(&vm->xe->drm, "Skipping madvise reset for vma.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (xe_vma_has_default_mem_attrs(vma))
|
if (xe_vma_has_default_mem_attrs(vma))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -616,6 +616,13 @@ static void xe_vma_ops_incr_pt_update_ops(struct xe_vma_ops *vops, u8 tile_mask,
|
||||||
vops->pt_update_ops[i].num_ops += inc_val;
|
vops->pt_update_ops[i].num_ops += inc_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define XE_VMA_CREATE_MASK ( \
|
||||||
|
XE_VMA_READ_ONLY | \
|
||||||
|
XE_VMA_DUMPABLE | \
|
||||||
|
XE_VMA_SYSTEM_ALLOCATOR | \
|
||||||
|
DRM_GPUVA_SPARSE | \
|
||||||
|
XE_VMA_MADV_AUTORESET)
|
||||||
|
|
||||||
static void xe_vm_populate_rebind(struct xe_vma_op *op, struct xe_vma *vma,
|
static void xe_vm_populate_rebind(struct xe_vma_op *op, struct xe_vma *vma,
|
||||||
u8 tile_mask)
|
u8 tile_mask)
|
||||||
{
|
{
|
||||||
|
|
@ -628,8 +635,7 @@ static void xe_vm_populate_rebind(struct xe_vma_op *op, struct xe_vma *vma,
|
||||||
op->base.map.gem.offset = vma->gpuva.gem.offset;
|
op->base.map.gem.offset = vma->gpuva.gem.offset;
|
||||||
op->map.vma = vma;
|
op->map.vma = vma;
|
||||||
op->map.immediate = true;
|
op->map.immediate = true;
|
||||||
op->map.dumpable = vma->gpuva.flags & XE_VMA_DUMPABLE;
|
op->map.vma_flags = vma->gpuva.flags & XE_VMA_CREATE_MASK;
|
||||||
op->map.is_null = xe_vma_is_null(vma);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xe_vm_ops_add_rebind(struct xe_vma_ops *vops, struct xe_vma *vma,
|
static int xe_vm_ops_add_rebind(struct xe_vma_ops *vops, struct xe_vma *vma,
|
||||||
|
|
@ -932,11 +938,6 @@ static void xe_vma_free(struct xe_vma *vma)
|
||||||
kfree(vma);
|
kfree(vma);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VMA_CREATE_FLAG_READ_ONLY BIT(0)
|
|
||||||
#define VMA_CREATE_FLAG_IS_NULL BIT(1)
|
|
||||||
#define VMA_CREATE_FLAG_DUMPABLE BIT(2)
|
|
||||||
#define VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR BIT(3)
|
|
||||||
|
|
||||||
static struct xe_vma *xe_vma_create(struct xe_vm *vm,
|
static struct xe_vma *xe_vma_create(struct xe_vm *vm,
|
||||||
struct xe_bo *bo,
|
struct xe_bo *bo,
|
||||||
u64 bo_offset_or_userptr,
|
u64 bo_offset_or_userptr,
|
||||||
|
|
@ -947,11 +948,8 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
|
||||||
struct xe_vma *vma;
|
struct xe_vma *vma;
|
||||||
struct xe_tile *tile;
|
struct xe_tile *tile;
|
||||||
u8 id;
|
u8 id;
|
||||||
bool read_only = (flags & VMA_CREATE_FLAG_READ_ONLY);
|
bool is_null = (flags & DRM_GPUVA_SPARSE);
|
||||||
bool is_null = (flags & VMA_CREATE_FLAG_IS_NULL);
|
bool is_cpu_addr_mirror = (flags & XE_VMA_SYSTEM_ALLOCATOR);
|
||||||
bool dumpable = (flags & VMA_CREATE_FLAG_DUMPABLE);
|
|
||||||
bool is_cpu_addr_mirror =
|
|
||||||
(flags & VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR);
|
|
||||||
|
|
||||||
xe_assert(vm->xe, start < end);
|
xe_assert(vm->xe, start < end);
|
||||||
xe_assert(vm->xe, end < vm->size);
|
xe_assert(vm->xe, end < vm->size);
|
||||||
|
|
@ -972,10 +970,6 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
|
||||||
if (!vma)
|
if (!vma)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
if (is_cpu_addr_mirror)
|
|
||||||
vma->gpuva.flags |= XE_VMA_SYSTEM_ALLOCATOR;
|
|
||||||
if (is_null)
|
|
||||||
vma->gpuva.flags |= DRM_GPUVA_SPARSE;
|
|
||||||
if (bo)
|
if (bo)
|
||||||
vma->gpuva.gem.obj = &bo->ttm.base;
|
vma->gpuva.gem.obj = &bo->ttm.base;
|
||||||
}
|
}
|
||||||
|
|
@ -986,10 +980,7 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
|
||||||
vma->gpuva.vm = &vm->gpuvm;
|
vma->gpuva.vm = &vm->gpuvm;
|
||||||
vma->gpuva.va.addr = start;
|
vma->gpuva.va.addr = start;
|
||||||
vma->gpuva.va.range = end - start + 1;
|
vma->gpuva.va.range = end - start + 1;
|
||||||
if (read_only)
|
vma->gpuva.flags = flags;
|
||||||
vma->gpuva.flags |= XE_VMA_READ_ONLY;
|
|
||||||
if (dumpable)
|
|
||||||
vma->gpuva.flags |= XE_VMA_DUMPABLE;
|
|
||||||
|
|
||||||
for_each_tile(tile, vm->xe, id)
|
for_each_tile(tile, vm->xe, id)
|
||||||
vma->tile_mask |= 0x1 << id;
|
vma->tile_mask |= 0x1 << id;
|
||||||
|
|
@ -2272,12 +2263,16 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_vma_ops *vops,
|
||||||
if (__op->op == DRM_GPUVA_OP_MAP) {
|
if (__op->op == DRM_GPUVA_OP_MAP) {
|
||||||
op->map.immediate =
|
op->map.immediate =
|
||||||
flags & DRM_XE_VM_BIND_FLAG_IMMEDIATE;
|
flags & DRM_XE_VM_BIND_FLAG_IMMEDIATE;
|
||||||
op->map.read_only =
|
if (flags & DRM_XE_VM_BIND_FLAG_READONLY)
|
||||||
flags & DRM_XE_VM_BIND_FLAG_READONLY;
|
op->map.vma_flags |= XE_VMA_READ_ONLY;
|
||||||
op->map.is_null = flags & DRM_XE_VM_BIND_FLAG_NULL;
|
if (flags & DRM_XE_VM_BIND_FLAG_NULL)
|
||||||
op->map.is_cpu_addr_mirror = flags &
|
op->map.vma_flags |= DRM_GPUVA_SPARSE;
|
||||||
DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR;
|
if (flags & DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR)
|
||||||
op->map.dumpable = flags & DRM_XE_VM_BIND_FLAG_DUMPABLE;
|
op->map.vma_flags |= XE_VMA_SYSTEM_ALLOCATOR;
|
||||||
|
if (flags & DRM_XE_VM_BIND_FLAG_DUMPABLE)
|
||||||
|
op->map.vma_flags |= XE_VMA_DUMPABLE;
|
||||||
|
if (flags & DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET)
|
||||||
|
op->map.vma_flags |= XE_VMA_MADV_AUTORESET;
|
||||||
op->map.pat_index = pat_index;
|
op->map.pat_index = pat_index;
|
||||||
op->map.invalidate_on_bind =
|
op->map.invalidate_on_bind =
|
||||||
__xe_vm_needs_clear_scratch_pages(vm, flags);
|
__xe_vm_needs_clear_scratch_pages(vm, flags);
|
||||||
|
|
@ -2590,14 +2585,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
|
||||||
.pat_index = op->map.pat_index,
|
.pat_index = op->map.pat_index,
|
||||||
};
|
};
|
||||||
|
|
||||||
flags |= op->map.read_only ?
|
flags |= op->map.vma_flags & XE_VMA_CREATE_MASK;
|
||||||
VMA_CREATE_FLAG_READ_ONLY : 0;
|
|
||||||
flags |= op->map.is_null ?
|
|
||||||
VMA_CREATE_FLAG_IS_NULL : 0;
|
|
||||||
flags |= op->map.dumpable ?
|
|
||||||
VMA_CREATE_FLAG_DUMPABLE : 0;
|
|
||||||
flags |= op->map.is_cpu_addr_mirror ?
|
|
||||||
VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR : 0;
|
|
||||||
|
|
||||||
vma = new_vma(vm, &op->base.map, &default_attr,
|
vma = new_vma(vm, &op->base.map, &default_attr,
|
||||||
flags);
|
flags);
|
||||||
|
|
@ -2606,7 +2594,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
|
||||||
|
|
||||||
op->map.vma = vma;
|
op->map.vma = vma;
|
||||||
if (((op->map.immediate || !xe_vm_in_fault_mode(vm)) &&
|
if (((op->map.immediate || !xe_vm_in_fault_mode(vm)) &&
|
||||||
!op->map.is_cpu_addr_mirror) ||
|
!(op->map.vma_flags & XE_VMA_SYSTEM_ALLOCATOR)) ||
|
||||||
op->map.invalidate_on_bind)
|
op->map.invalidate_on_bind)
|
||||||
xe_vma_ops_incr_pt_update_ops(vops,
|
xe_vma_ops_incr_pt_update_ops(vops,
|
||||||
op->tile_mask, 1);
|
op->tile_mask, 1);
|
||||||
|
|
@ -2637,18 +2625,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
|
||||||
op->remap.start = xe_vma_start(old);
|
op->remap.start = xe_vma_start(old);
|
||||||
op->remap.range = xe_vma_size(old);
|
op->remap.range = xe_vma_size(old);
|
||||||
|
|
||||||
flags |= op->base.remap.unmap->va->flags &
|
flags |= op->base.remap.unmap->va->flags & XE_VMA_CREATE_MASK;
|
||||||
XE_VMA_READ_ONLY ?
|
|
||||||
VMA_CREATE_FLAG_READ_ONLY : 0;
|
|
||||||
flags |= op->base.remap.unmap->va->flags &
|
|
||||||
DRM_GPUVA_SPARSE ?
|
|
||||||
VMA_CREATE_FLAG_IS_NULL : 0;
|
|
||||||
flags |= op->base.remap.unmap->va->flags &
|
|
||||||
XE_VMA_DUMPABLE ?
|
|
||||||
VMA_CREATE_FLAG_DUMPABLE : 0;
|
|
||||||
flags |= xe_vma_is_cpu_addr_mirror(old) ?
|
|
||||||
VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR : 0;
|
|
||||||
|
|
||||||
if (op->base.remap.prev) {
|
if (op->base.remap.prev) {
|
||||||
vma = new_vma(vm, op->base.remap.prev,
|
vma = new_vma(vm, op->base.remap.prev,
|
||||||
&old->attr, flags);
|
&old->attr, flags);
|
||||||
|
|
@ -3279,7 +3256,8 @@ ALLOW_ERROR_INJECTION(vm_bind_ioctl_ops_execute, ERRNO);
|
||||||
DRM_XE_VM_BIND_FLAG_NULL | \
|
DRM_XE_VM_BIND_FLAG_NULL | \
|
||||||
DRM_XE_VM_BIND_FLAG_DUMPABLE | \
|
DRM_XE_VM_BIND_FLAG_DUMPABLE | \
|
||||||
DRM_XE_VM_BIND_FLAG_CHECK_PXP | \
|
DRM_XE_VM_BIND_FLAG_CHECK_PXP | \
|
||||||
DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR)
|
DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR | \
|
||||||
|
DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET)
|
||||||
|
|
||||||
#ifdef TEST_VM_OPS_ERROR
|
#ifdef TEST_VM_OPS_ERROR
|
||||||
#define SUPPORTED_FLAGS (SUPPORTED_FLAGS_STUB | FORCE_OP_ERROR)
|
#define SUPPORTED_FLAGS (SUPPORTED_FLAGS_STUB | FORCE_OP_ERROR)
|
||||||
|
|
@ -3394,7 +3372,9 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
|
||||||
XE_IOCTL_DBG(xe, (prefetch_region != DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC &&
|
XE_IOCTL_DBG(xe, (prefetch_region != DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC &&
|
||||||
!(BIT(prefetch_region) & xe->info.mem_region_mask))) ||
|
!(BIT(prefetch_region) & xe->info.mem_region_mask))) ||
|
||||||
XE_IOCTL_DBG(xe, obj &&
|
XE_IOCTL_DBG(xe, obj &&
|
||||||
op == DRM_XE_VM_BIND_OP_UNMAP)) {
|
op == DRM_XE_VM_BIND_OP_UNMAP) ||
|
||||||
|
XE_IOCTL_DBG(xe, (flags & DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET) &&
|
||||||
|
(!is_cpu_addr_mirror || op != DRM_XE_VM_BIND_OP_MAP))) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto free_bind_ops;
|
goto free_bind_ops;
|
||||||
}
|
}
|
||||||
|
|
@ -4212,7 +4192,7 @@ static int xe_vm_alloc_vma(struct xe_vm *vm,
|
||||||
struct xe_vma_ops vops;
|
struct xe_vma_ops vops;
|
||||||
struct drm_gpuva_ops *ops = NULL;
|
struct drm_gpuva_ops *ops = NULL;
|
||||||
struct drm_gpuva_op *__op;
|
struct drm_gpuva_op *__op;
|
||||||
bool is_cpu_addr_mirror = false;
|
unsigned int vma_flags = 0;
|
||||||
bool remap_op = false;
|
bool remap_op = false;
|
||||||
struct xe_vma_mem_attr tmp_attr;
|
struct xe_vma_mem_attr tmp_attr;
|
||||||
u16 default_pat;
|
u16 default_pat;
|
||||||
|
|
@ -4242,15 +4222,17 @@ static int xe_vm_alloc_vma(struct xe_vm *vm,
|
||||||
vma = gpuva_to_vma(op->base.unmap.va);
|
vma = gpuva_to_vma(op->base.unmap.va);
|
||||||
XE_WARN_ON(!xe_vma_has_default_mem_attrs(vma));
|
XE_WARN_ON(!xe_vma_has_default_mem_attrs(vma));
|
||||||
default_pat = vma->attr.default_pat_index;
|
default_pat = vma->attr.default_pat_index;
|
||||||
|
vma_flags = vma->gpuva.flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__op->op == DRM_GPUVA_OP_REMAP) {
|
if (__op->op == DRM_GPUVA_OP_REMAP) {
|
||||||
vma = gpuva_to_vma(op->base.remap.unmap->va);
|
vma = gpuva_to_vma(op->base.remap.unmap->va);
|
||||||
default_pat = vma->attr.default_pat_index;
|
default_pat = vma->attr.default_pat_index;
|
||||||
|
vma_flags = vma->gpuva.flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__op->op == DRM_GPUVA_OP_MAP) {
|
if (__op->op == DRM_GPUVA_OP_MAP) {
|
||||||
op->map.is_cpu_addr_mirror = true;
|
op->map.vma_flags |= vma_flags & XE_VMA_CREATE_MASK;
|
||||||
op->map.pat_index = default_pat;
|
op->map.pat_index = default_pat;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -4259,11 +4241,7 @@ static int xe_vm_alloc_vma(struct xe_vm *vm,
|
||||||
xe_assert(vm->xe, !remap_op);
|
xe_assert(vm->xe, !remap_op);
|
||||||
xe_assert(vm->xe, xe_vma_has_no_bo(vma));
|
xe_assert(vm->xe, xe_vma_has_no_bo(vma));
|
||||||
remap_op = true;
|
remap_op = true;
|
||||||
|
vma_flags = vma->gpuva.flags;
|
||||||
if (xe_vma_is_cpu_addr_mirror(vma))
|
|
||||||
is_cpu_addr_mirror = true;
|
|
||||||
else
|
|
||||||
is_cpu_addr_mirror = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__op->op == DRM_GPUVA_OP_MAP) {
|
if (__op->op == DRM_GPUVA_OP_MAP) {
|
||||||
|
|
@ -4272,10 +4250,10 @@ static int xe_vm_alloc_vma(struct xe_vm *vm,
|
||||||
/*
|
/*
|
||||||
* In case of madvise ops DRM_GPUVA_OP_MAP is
|
* In case of madvise ops DRM_GPUVA_OP_MAP is
|
||||||
* always after DRM_GPUVA_OP_REMAP, so ensure
|
* always after DRM_GPUVA_OP_REMAP, so ensure
|
||||||
* we assign op->map.is_cpu_addr_mirror true
|
* to propagate the flags from the vma we're
|
||||||
* if REMAP is for xe_vma_is_cpu_addr_mirror vma
|
* unmapping.
|
||||||
*/
|
*/
|
||||||
op->map.is_cpu_addr_mirror = is_cpu_addr_mirror;
|
op->map.vma_flags |= vma_flags & XE_VMA_CREATE_MASK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print_op(vm->xe, __op);
|
print_op(vm->xe, __op);
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ struct xe_vm_pgtable_update_op;
|
||||||
#define XE_VMA_PTE_COMPACT (DRM_GPUVA_USERBITS << 7)
|
#define XE_VMA_PTE_COMPACT (DRM_GPUVA_USERBITS << 7)
|
||||||
#define XE_VMA_DUMPABLE (DRM_GPUVA_USERBITS << 8)
|
#define XE_VMA_DUMPABLE (DRM_GPUVA_USERBITS << 8)
|
||||||
#define XE_VMA_SYSTEM_ALLOCATOR (DRM_GPUVA_USERBITS << 9)
|
#define XE_VMA_SYSTEM_ALLOCATOR (DRM_GPUVA_USERBITS << 9)
|
||||||
|
#define XE_VMA_MADV_AUTORESET (DRM_GPUVA_USERBITS << 10)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct xe_vma_mem_attr - memory attributes associated with vma
|
* struct xe_vma_mem_attr - memory attributes associated with vma
|
||||||
|
|
@ -345,17 +346,10 @@ struct xe_vm {
|
||||||
struct xe_vma_op_map {
|
struct xe_vma_op_map {
|
||||||
/** @vma: VMA to map */
|
/** @vma: VMA to map */
|
||||||
struct xe_vma *vma;
|
struct xe_vma *vma;
|
||||||
|
unsigned int vma_flags;
|
||||||
/** @immediate: Immediate bind */
|
/** @immediate: Immediate bind */
|
||||||
bool immediate;
|
bool immediate;
|
||||||
/** @read_only: Read only */
|
/** @read_only: Read only */
|
||||||
bool read_only;
|
|
||||||
/** @is_null: is NULL binding */
|
|
||||||
bool is_null;
|
|
||||||
/** @is_cpu_addr_mirror: is CPU address mirror binding */
|
|
||||||
bool is_cpu_addr_mirror;
|
|
||||||
/** @dumpable: whether BO is dumped on GPU hang */
|
|
||||||
bool dumpable;
|
|
||||||
/** @invalidate: invalidate the VMA before bind */
|
|
||||||
bool invalidate_on_bind;
|
bool invalidate_on_bind;
|
||||||
/** @pat_index: The pat index to use for this operation. */
|
/** @pat_index: The pat index to use for this operation. */
|
||||||
u16 pat_index;
|
u16 pat_index;
|
||||||
|
|
|
||||||
|
|
@ -1013,6 +1013,20 @@ struct drm_xe_vm_destroy {
|
||||||
* valid on VMs with DRM_XE_VM_CREATE_FLAG_FAULT_MODE set. The CPU address
|
* valid on VMs with DRM_XE_VM_CREATE_FLAG_FAULT_MODE set. The CPU address
|
||||||
* mirror flag are only valid for DRM_XE_VM_BIND_OP_MAP operations, the BO
|
* mirror flag are only valid for DRM_XE_VM_BIND_OP_MAP operations, the BO
|
||||||
* handle MBZ, and the BO offset MBZ.
|
* handle MBZ, and the BO offset MBZ.
|
||||||
|
* - %DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET - Can be used in combination with
|
||||||
|
* %DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR to reset madvises when the underlying
|
||||||
|
* CPU address space range is unmapped (typically with munmap(2) or brk(2)).
|
||||||
|
* The madvise values set with &DRM_IOCTL_XE_MADVISE are reset to the values
|
||||||
|
* that were present immediately after the &DRM_IOCTL_XE_VM_BIND.
|
||||||
|
* The reset GPU virtual address range is the intersection of the range bound
|
||||||
|
* using &DRM_IOCTL_XE_VM_BIND and the virtual CPU address space range
|
||||||
|
* unmapped.
|
||||||
|
* This functionality is present to mimic the behaviour of CPU address space
|
||||||
|
* madvises set using madvise(2), which are typically reset on unmap.
|
||||||
|
* Note: free(3) may or may not call munmap(2) and/or brk(2), and may thus
|
||||||
|
* not invoke autoreset. Neither will stack variables going out of scope.
|
||||||
|
* Therefore it's recommended to always explicitly reset the madvises when
|
||||||
|
* freeing the memory backing a region used in a &DRM_IOCTL_XE_MADVISE call.
|
||||||
*
|
*
|
||||||
* The @prefetch_mem_region_instance for %DRM_XE_VM_BIND_OP_PREFETCH can also be:
|
* The @prefetch_mem_region_instance for %DRM_XE_VM_BIND_OP_PREFETCH can also be:
|
||||||
* - %DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC, which ensures prefetching occurs in
|
* - %DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC, which ensures prefetching occurs in
|
||||||
|
|
@ -1119,6 +1133,7 @@ struct drm_xe_vm_bind_op {
|
||||||
#define DRM_XE_VM_BIND_FLAG_DUMPABLE (1 << 3)
|
#define DRM_XE_VM_BIND_FLAG_DUMPABLE (1 << 3)
|
||||||
#define DRM_XE_VM_BIND_FLAG_CHECK_PXP (1 << 4)
|
#define DRM_XE_VM_BIND_FLAG_CHECK_PXP (1 << 4)
|
||||||
#define DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR (1 << 5)
|
#define DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR (1 << 5)
|
||||||
|
#define DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET (1 << 6)
|
||||||
/** @flags: Bind flags */
|
/** @flags: Bind flags */
|
||||||
__u32 flags;
|
__u32 flags;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue