Skip to content

Commit

Permalink
Merge tag 'drm-intel-next-fixes-2023-11-08' of git://anongit.freedesk…
Browse files Browse the repository at this point in the history
…top.org/drm/drm-intel into drm-next

drm/i915 fixes for v6.7-rc1:
- Fix null dereference when perf interface is not available
- Fix a -Wstringop-overflow warning
- Fix a -Wformat-truncation warning in intel_tc_port_init
- Flush WC GGTT only on required platforms
- Fix MTL HBR3 rate support on C10 phy and eDP
- Fix MTL notify_guc for multi-GT
- Bump GLK CDCLK frequency when driving multiple pipes
- Fix potential spectre vulnerability

Signed-off-by: Daniel Vetter <[email protected]>
From: Jani Nikula <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
  • Loading branch information
danvet committed Nov 10, 2023
2 parents 9ccde17 + 9506fba commit 0b336ec
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 36 deletions.
12 changes: 12 additions & 0 deletions drivers/gpu/drm/i915/display/intel_cdclk.c
Original file line number Diff line number Diff line change
Expand Up @@ -2750,6 +2750,18 @@ static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
for_each_pipe(dev_priv, pipe)
min_cdclk = max(cdclk_state->min_cdclk[pipe], min_cdclk);

/*
* Avoid glk_force_audio_cdclk() causing excessive screen
* blinking when multiple pipes are active by making sure
* CDCLK frequency is always high enough for audio. With a
* single active pipe we can always change CDCLK frequency
* by changing the cd2x divider (see glk_cdclk_table[]) and
* thus a full modeset won't be needed then.
*/
if (IS_GEMINILAKE(dev_priv) && cdclk_state->active_pipes &&
!is_power_of_2(cdclk_state->active_pipes))
min_cdclk = max(2 * 96000, min_cdclk);

if (min_cdclk > dev_priv->display.cdclk.max_cdclk_freq) {
drm_dbg_kms(&dev_priv->drm,
"required cdclk (%d kHz) exceeds max (%d kHz)\n",
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/display/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ static int mtl_max_source_rate(struct intel_dp *intel_dp)
enum phy phy = intel_port_to_phy(i915, dig_port->base.port);

if (intel_is_c10phy(i915, phy))
return intel_dp_is_edp(intel_dp) ? 675000 : 810000;
return 810000;

return 2000000;
}
Expand Down
11 changes: 8 additions & 3 deletions drivers/gpu/drm/i915/display/intel_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ struct intel_tc_port {
struct delayed_work link_reset_work;
int link_refcount;
bool legacy_port:1;
char port_name[8];
const char *port_name;
enum tc_port_mode mode;
enum tc_port_mode init_mode;
enum phy_fia phy_fia;
Expand Down Expand Up @@ -1875,8 +1875,12 @@ int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy)
else
tc->phy_ops = &icl_tc_phy_ops;

snprintf(tc->port_name, sizeof(tc->port_name),
"%c/TC#%d", port_name(port), tc_port + 1);
tc->port_name = kasprintf(GFP_KERNEL, "%c/TC#%d", port_name(port),
tc_port + 1);
if (!tc->port_name) {
kfree(tc);
return -ENOMEM;
}

mutex_init(&tc->lock);
/* TODO: Combine the two works */
Expand All @@ -1897,6 +1901,7 @@ void intel_tc_port_cleanup(struct intel_digital_port *dig_port)
{
intel_tc_port_suspend(dig_port);

kfree(dig_port->tc->port_name);
kfree(dig_port->tc);
dig_port->tc = NULL;
}
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/gem/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,7 @@ static int set_proto_ctx_sseu(struct drm_i915_file_private *fpriv,
if (idx >= pc->num_user_engines)
return -EINVAL;

idx = array_index_nospec(idx, pc->num_user_engines);
pe = &pc->user_engines[idx];

/* Only render engine supports RPCS configuration. */
Expand Down
35 changes: 24 additions & 11 deletions drivers/gpu/drm/i915/gt/intel_ggtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,15 +195,34 @@ void gen6_ggtt_invalidate(struct i915_ggtt *ggtt)
spin_unlock_irq(&uncore->lock);
}

static bool needs_wc_ggtt_mapping(struct drm_i915_private *i915)
{
/*
* On BXT+/ICL+ writes larger than 64 bit to the GTT pagetable range
* will be dropped. For WC mappings in general we have 64 byte burst
* writes when the WC buffer is flushed, so we can't use it, but have to
* resort to an uncached mapping. The WC issue is easily caught by the
* readback check when writing GTT PTE entries.
*/
if (!IS_GEN9_LP(i915) && GRAPHICS_VER(i915) < 11)
return true;

return false;
}

static void gen8_ggtt_invalidate(struct i915_ggtt *ggtt)
{
struct intel_uncore *uncore = ggtt->vm.gt->uncore;

/*
* Note that as an uncached mmio write, this will flush the
* WCB of the writes into the GGTT before it triggers the invalidate.
*
* Only perform this when GGTT is mapped as WC, see ggtt_probe_common().
*/
intel_uncore_write_fw(uncore, GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
if (needs_wc_ggtt_mapping(ggtt->vm.i915))
intel_uncore_write_fw(uncore, GFX_FLSH_CNTL_GEN6,
GFX_FLSH_CNTL_EN);
}

static void guc_ggtt_ct_invalidate(struct intel_gt *gt)
Expand Down Expand Up @@ -1140,17 +1159,11 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
GEM_WARN_ON(pci_resource_len(pdev, GEN4_GTTMMADR_BAR) != gen6_gttmmadr_size(i915));
phys_addr = pci_resource_start(pdev, GEN4_GTTMMADR_BAR) + gen6_gttadr_offset(i915);

/*
* On BXT+/ICL+ writes larger than 64 bit to the GTT pagetable range
* will be dropped. For WC mappings in general we have 64 byte burst
* writes when the WC buffer is flushed, so we can't use it, but have to
* resort to an uncached mapping. The WC issue is easily caught by the
* readback check when writing GTT PTE entries.
*/
if (IS_GEN9_LP(i915) || GRAPHICS_VER(i915) >= 11)
ggtt->gsm = ioremap(phys_addr, size);
else
if (needs_wc_ggtt_mapping(i915))
ggtt->gsm = ioremap_wc(phys_addr, size);
else
ggtt->gsm = ioremap(phys_addr, size);

if (!ggtt->gsm) {
drm_err(&i915->drm, "Failed to map the ggtt page table\n");
return -ENOMEM;
Expand Down
16 changes: 10 additions & 6 deletions drivers/gpu/drm/i915/gt/intel_rc6.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,19 +581,23 @@ static void __intel_rc6_disable(struct intel_rc6 *rc6)

static void rc6_res_reg_init(struct intel_rc6 *rc6)
{
memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg));
i915_reg_t res_reg[INTEL_RC6_RES_MAX] = {
[0 ... INTEL_RC6_RES_MAX - 1] = INVALID_MMIO_REG,
};

switch (rc6_to_gt(rc6)->type) {
case GT_MEDIA:
rc6->res_reg[INTEL_RC6_RES_RC6] = MTL_MEDIA_MC6;
res_reg[INTEL_RC6_RES_RC6] = MTL_MEDIA_MC6;
break;
default:
rc6->res_reg[INTEL_RC6_RES_RC6_LOCKED] = GEN6_GT_GFX_RC6_LOCKED;
rc6->res_reg[INTEL_RC6_RES_RC6] = GEN6_GT_GFX_RC6;
rc6->res_reg[INTEL_RC6_RES_RC6p] = GEN6_GT_GFX_RC6p;
rc6->res_reg[INTEL_RC6_RES_RC6pp] = GEN6_GT_GFX_RC6pp;
res_reg[INTEL_RC6_RES_RC6_LOCKED] = GEN6_GT_GFX_RC6_LOCKED;
res_reg[INTEL_RC6_RES_RC6] = GEN6_GT_GFX_RC6;
res_reg[INTEL_RC6_RES_RC6p] = GEN6_GT_GFX_RC6p;
res_reg[INTEL_RC6_RES_RC6pp] = GEN6_GT_GFX_RC6pp;
break;
}

memcpy(rc6->res_reg, res_reg, sizeof(res_reg));
}

void intel_rc6_init(struct intel_rc6 *rc6)
Expand Down
9 changes: 6 additions & 3 deletions drivers/gpu/drm/i915/i915_debugfs_params.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ static int i915_param_int_open(struct inode *inode, struct file *file)

static int notify_guc(struct drm_i915_private *i915)
{
int ret = 0;
struct intel_gt *gt;
int i, ret = 0;

if (intel_uc_uses_guc_submission(&to_gt(i915)->uc))
ret = intel_guc_global_policies_update(&to_gt(i915)->uc.guc);
for_each_gt(gt, i915, i) {
if (intel_uc_uses_guc_submission(&gt->uc))
ret = intel_guc_global_policies_update(&gt->uc.guc);
}

return ret;
}
Expand Down
15 changes: 3 additions & 12 deletions drivers/gpu/drm/i915/i915_perf.c
Original file line number Diff line number Diff line change
Expand Up @@ -4227,11 +4227,8 @@ int i915_perf_open_ioctl(struct drm_device *dev, void *data,
u32 known_open_flags;
int ret;

if (!perf->i915) {
drm_dbg(&perf->i915->drm,
"i915 perf interface not available for this system\n");
if (!perf->i915)
return -ENOTSUPP;
}

known_open_flags = I915_PERF_FLAG_FD_CLOEXEC |
I915_PERF_FLAG_FD_NONBLOCK |
Expand Down Expand Up @@ -4607,11 +4604,8 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
struct i915_oa_reg *regs;
int err, id;

if (!perf->i915) {
drm_dbg(&perf->i915->drm,
"i915 perf interface not available for this system\n");
if (!perf->i915)
return -ENOTSUPP;
}

if (!perf->metrics_kobj) {
drm_dbg(&perf->i915->drm,
Expand Down Expand Up @@ -4773,11 +4767,8 @@ int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data,
struct i915_oa_config *oa_config;
int ret;

if (!perf->i915) {
drm_dbg(&perf->i915->drm,
"i915 perf interface not available for this system\n");
if (!perf->i915)
return -ENOTSUPP;
}

if (i915_perf_stream_paranoid && !perfmon_capable()) {
drm_dbg(&perf->i915->drm,
Expand Down

0 comments on commit 0b336ec

Please sign in to comment.