drm/i915: Handle msr read failure gracefully
authorGabriel Krisman Bertazi <krisman@collabora.co.uk>
Wed, 26 Jul 2017 05:30:16 +0000 (02:30 -0300)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 27 Jul 2017 07:39:00 +0000 (09:39 +0200)
When reading the i915_energy_uJ debugfs file, it tries to fetch
MSR_RAPL_POWER_UNIT, which might not be available, like in a vm
environment, causing the exception shown below.

We can easily prevent it by doing a rdmsrl_safe read instead, which will
handle the exception, allowing us to abort the debugfs file read.

This was caught by the new igt@debugfs_test@read_all_entries testcase in
the CI.

  unchecked MSR access error: RDMSR from 0x606 at rIP:0xffffffffa0078f66
    (i915_energy_uJ+0x36/0xb0 [i915])
  Call Trace:
   seq_read+0xdc/0x3a0
   full_proxy_read+0x4f/0x70
   __vfs_read+0x23/0x120
   ? putname+0x4f/0x60
   ? rcu_read_lock_sched_held+0x75/0x80
   ? entry_SYSCALL_64_fastpath+0x5/0xb1
   vfs_read+0xa0/0x150
   SyS_read+0x44/0xb0
   entry_SYSCALL_64_fastpath+0x1c/0xb1
  RIP: 0033:0x7f1f5e9f4500
  RSP: 002b:00007ffc77e65cf8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
  RAX: ffffffffffffffda RBX: ffffffff8146e003 RCX: 00007f1f5e9f4500
  RDX: 0000000000000200 RSI: 00007ffc77e65d10 RDI: 0000000000000006
  RBP: ffffc900007abf88 R08: 0000000001eaff20 R09: 0000000000000000
  R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
  R13: 0000000000000006 R14: 0000000000000005 R15: 0000000001eb94db
   ? __this_cpu_preempt_check+0x13/0x20

v2:
 - Drop unsigned long long cast and improve calculation (Chris)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101901
Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/87o9s7zrx3.fsf@dilma.collabora.co.uk
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_debugfs.c

index ea50c4a1efae488575d1605ac91c25305d09ab1a..6480897bcaf438881b707a788b61956468785970 100644 (file)
@@ -2783,7 +2783,7 @@ out:
 static int i915_energy_uJ(struct seq_file *m, void *data)
 {
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
-       u64 power;
+       unsigned long long power;
        u32 units;
 
        if (INTEL_GEN(dev_priv) < 6)
@@ -2791,15 +2791,18 @@ static int i915_energy_uJ(struct seq_file *m, void *data)
 
        intel_runtime_pm_get(dev_priv);
 
-       rdmsrl(MSR_RAPL_POWER_UNIT, power);
-       power = (power & 0x1f00) >> 8;
-       units = 1000000 / (1 << power); /* convert to uJ */
+       if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &power)) {
+               intel_runtime_pm_put(dev_priv);
+               return -ENODEV;
+       }
+
+       units = (power & 0x1f00) >> 8;
        power = I915_READ(MCH_SECP_NRG_STTS);
-       power *= units;
+       power = (1000000 * power) >> units; /* convert to uJ */
 
        intel_runtime_pm_put(dev_priv);
 
-       seq_printf(m, "%llu", (long long unsigned)power);
+       seq_printf(m, "%llu", power);
 
        return 0;
 }