Commit ec037ac2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'drm-fixes-2019-08-16' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
 "Nothing too crazy this week, one amdgpu fix to use vmalloc for a
  struct that grew in size, and another MST fix for nouveau, and some
  other misc fixes:

  i915:
   - single GVT use after free fix

  scheduler:
   - entity destruction race fix

  amdgpu:
   - struct allocation fix
   - gfx9 soft recovery fix

  nouveau:
   - followup MST fix

  ast:
   - vga register race fix"

* tag 'drm-fixes-2019-08-16' of git://anongit.freedesktop.org/drm/drm:
  drm/nouveau: Only recalculate PBN/VCPI on mode/connector changes
  drm/ast: Fixed reboot test may cause system hanged
  drm/scheduler: use job count instead of peek
  drm/amd/display: use kvmalloc for dc_state (v2)
  drm/amdgpu: fix gfx9 soft recovery
  drm/i915: Use after free in error path in intel_vgpu_create_workload()
parents a69e9051 a85abd5d
...@@ -4869,7 +4869,7 @@ static void gfx_v9_0_ring_soft_recovery(struct amdgpu_ring *ring, unsigned vmid) ...@@ -4869,7 +4869,7 @@ static void gfx_v9_0_ring_soft_recovery(struct amdgpu_ring *ring, unsigned vmid)
value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01); value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1); value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid); value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid);
WREG32(mmSQ_CMD, value); WREG32_SOC15(GC, 0, mmSQ_CMD, value);
} }
static void gfx_v9_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev, static void gfx_v9_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
*/ */
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mm.h>
#include "dm_services.h" #include "dm_services.h"
...@@ -1171,8 +1172,8 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) ...@@ -1171,8 +1172,8 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
struct dc_state *dc_create_state(struct dc *dc) struct dc_state *dc_create_state(struct dc *dc)
{ {
struct dc_state *context = kzalloc(sizeof(struct dc_state), struct dc_state *context = kvzalloc(sizeof(struct dc_state),
GFP_KERNEL); GFP_KERNEL);
if (!context) if (!context)
return NULL; return NULL;
...@@ -1192,11 +1193,11 @@ struct dc_state *dc_create_state(struct dc *dc) ...@@ -1192,11 +1193,11 @@ struct dc_state *dc_create_state(struct dc *dc)
struct dc_state *dc_copy_state(struct dc_state *src_ctx) struct dc_state *dc_copy_state(struct dc_state *src_ctx)
{ {
int i, j; int i, j;
struct dc_state *new_ctx = kmemdup(src_ctx, struct dc_state *new_ctx = kvmalloc(sizeof(struct dc_state), GFP_KERNEL);
sizeof(struct dc_state), GFP_KERNEL);
if (!new_ctx) if (!new_ctx)
return NULL; return NULL;
memcpy(new_ctx, src_ctx, sizeof(struct dc_state));
for (i = 0; i < MAX_PIPES; i++) { for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *cur_pipe = &new_ctx->res_ctx.pipe_ctx[i]; struct pipe_ctx *cur_pipe = &new_ctx->res_ctx.pipe_ctx[i];
...@@ -1230,7 +1231,7 @@ static void dc_state_free(struct kref *kref) ...@@ -1230,7 +1231,7 @@ static void dc_state_free(struct kref *kref)
{ {
struct dc_state *context = container_of(kref, struct dc_state, refcount); struct dc_state *context = container_of(kref, struct dc_state, refcount);
dc_resource_state_destruct(context); dc_resource_state_destruct(context);
kfree(context); kvfree(context);
} }
void dc_release_state(struct dc_state *context) void dc_release_state(struct dc_state *context)
......
...@@ -131,8 +131,8 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) ...@@ -131,8 +131,8 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
/* Enable extended register access */ /* Enable extended register access */
ast_enable_mmio(dev);
ast_open_key(ast); ast_open_key(ast);
ast_enable_mmio(dev);
/* Find out whether P2A works or whether to use device-tree */ /* Find out whether P2A works or whether to use device-tree */
ast_detect_config_mode(dev, &scu_rev); ast_detect_config_mode(dev, &scu_rev);
...@@ -576,6 +576,9 @@ void ast_driver_unload(struct drm_device *dev) ...@@ -576,6 +576,9 @@ void ast_driver_unload(struct drm_device *dev)
{ {
struct ast_private *ast = dev->dev_private; struct ast_private *ast = dev->dev_private;
/* enable standard VGA decode */
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04);
ast_release_firmware(dev); ast_release_firmware(dev);
kfree(ast->dp501_fw_addr); kfree(ast->dp501_fw_addr);
ast_mode_fini(dev); ast_mode_fini(dev);
......
...@@ -604,7 +604,7 @@ static int ast_crtc_mode_set(struct drm_crtc *crtc, ...@@ -604,7 +604,7 @@ static int ast_crtc_mode_set(struct drm_crtc *crtc,
return -EINVAL; return -EINVAL;
ast_open_key(ast); ast_open_key(ast);
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x04); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
ast_set_std_reg(crtc, adjusted_mode, &vbios_mode); ast_set_std_reg(crtc, adjusted_mode, &vbios_mode);
ast_set_crtc_reg(crtc, adjusted_mode, &vbios_mode); ast_set_crtc_reg(crtc, adjusted_mode, &vbios_mode);
......
...@@ -46,7 +46,7 @@ void ast_enable_mmio(struct drm_device *dev) ...@@ -46,7 +46,7 @@ void ast_enable_mmio(struct drm_device *dev)
{ {
struct ast_private *ast = dev->dev_private; struct ast_private *ast = dev->dev_private;
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x04); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
} }
......
...@@ -1528,9 +1528,9 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, ...@@ -1528,9 +1528,9 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
if (!intel_gvt_ggtt_validate_range(vgpu, if (!intel_gvt_ggtt_validate_range(vgpu,
workload->wa_ctx.indirect_ctx.guest_gma, workload->wa_ctx.indirect_ctx.guest_gma,
workload->wa_ctx.indirect_ctx.size)) { workload->wa_ctx.indirect_ctx.size)) {
kmem_cache_free(s->workloads, workload);
gvt_vgpu_err("invalid wa_ctx at: 0x%lx\n", gvt_vgpu_err("invalid wa_ctx at: 0x%lx\n",
workload->wa_ctx.indirect_ctx.guest_gma); workload->wa_ctx.indirect_ctx.guest_gma);
kmem_cache_free(s->workloads, workload);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
} }
...@@ -1542,9 +1542,9 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, ...@@ -1542,9 +1542,9 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
if (!intel_gvt_ggtt_validate_range(vgpu, if (!intel_gvt_ggtt_validate_range(vgpu,
workload->wa_ctx.per_ctx.guest_gma, workload->wa_ctx.per_ctx.guest_gma,
CACHELINE_BYTES)) { CACHELINE_BYTES)) {
kmem_cache_free(s->workloads, workload);
gvt_vgpu_err("invalid per_ctx at: 0x%lx\n", gvt_vgpu_err("invalid per_ctx at: 0x%lx\n",
workload->wa_ctx.per_ctx.guest_gma); workload->wa_ctx.per_ctx.guest_gma);
kmem_cache_free(s->workloads, workload);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
} }
......
...@@ -771,16 +771,20 @@ nv50_msto_atomic_check(struct drm_encoder *encoder, ...@@ -771,16 +771,20 @@ nv50_msto_atomic_check(struct drm_encoder *encoder,
struct nv50_head_atom *asyh = nv50_head_atom(crtc_state); struct nv50_head_atom *asyh = nv50_head_atom(crtc_state);
int slots; int slots;
/* When restoring duplicated states, we need to make sure that the if (crtc_state->mode_changed || crtc_state->connectors_changed) {
* bw remains the same and avoid recalculating it, as the connector's /*
* bpc may have changed after the state was duplicated * When restoring duplicated states, we need to make sure that
*/ * the bw remains the same and avoid recalculating it, as the
if (!state->duplicated) * connector's bpc may have changed after the state was
asyh->dp.pbn = * duplicated
drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock, */
connector->display_info.bpc * 3); if (!state->duplicated) {
const int bpp = connector->display_info.bpc * 3;
const int clock = crtc_state->adjusted_mode.clock;
asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, bpp);
}
if (crtc_state->mode_changed) {
slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr, slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr,
mstc->port, mstc->port,
asyh->dp.pbn); asyh->dp.pbn);
......
...@@ -95,7 +95,7 @@ static bool drm_sched_entity_is_idle(struct drm_sched_entity *entity) ...@@ -95,7 +95,7 @@ static bool drm_sched_entity_is_idle(struct drm_sched_entity *entity)
rmb(); /* for list_empty to work without lock */ rmb(); /* for list_empty to work without lock */
if (list_empty(&entity->list) || if (list_empty(&entity->list) ||
spsc_queue_peek(&entity->job_queue) == NULL) spsc_queue_count(&entity->job_queue) == 0)
return true; return true;
return false; return false;
...@@ -281,7 +281,7 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity) ...@@ -281,7 +281,7 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity)
/* Consumption of existing IBs wasn't completed. Forcefully /* Consumption of existing IBs wasn't completed. Forcefully
* remove them here. * remove them here.
*/ */
if (spsc_queue_peek(&entity->job_queue)) { if (spsc_queue_count(&entity->job_queue)) {
if (sched) { if (sched) {
/* Park the kernel for a moment to make sure it isn't processing /* Park the kernel for a moment to make sure it isn't processing
* our enity. * our enity.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment