diff mbox series

accel/ivpu: Fix NOC firewall interrupt handling

Message ID 20241017144958.79327-1-jacek.lawrynowicz@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series accel/ivpu: Fix NOC firewall interrupt handling | expand

Commit Message

Jacek Lawrynowicz Oct. 17, 2024, 2:49 p.m. UTC
From: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com>

The NOC firewall interrupt means that the HW prevented
unauthorized access to a protected resource, so there
is no need to trigger device reset in such case.

To facilitate security testing add firewall_irq_counter
debugfs file that tracks firewall interrupts.

Fixes: 8a27ad81f7d3 ("accel/ivpu: Split IP and buttress code")
Cc: <stable@vger.kernel.org> # v6.11+
Signed-off-by: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com>
Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
---
 drivers/accel/ivpu/ivpu_debugfs.c | 9 +++++++++
 drivers/accel/ivpu/ivpu_hw.c      | 1 +
 drivers/accel/ivpu/ivpu_hw.h      | 1 +
 drivers/accel/ivpu/ivpu_hw_ip.c   | 5 ++++-
 4 files changed, 15 insertions(+), 1 deletion(-)

Comments

Jeffrey Hugo Oct. 18, 2024, 8:44 p.m. UTC | #1
On 10/17/2024 8:49 AM, Jacek Lawrynowicz wrote:
> From: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com>
> 
> The NOC firewall interrupt means that the HW prevented
> unauthorized access to a protected resource, so there
> is no need to trigger device reset in such case.
> 
> To facilitate security testing add firewall_irq_counter
> debugfs file that tracks firewall interrupts.
> 
> Fixes: 8a27ad81f7d3 ("accel/ivpu: Split IP and buttress code")
> Cc: <stable@vger.kernel.org> # v6.11+
> Signed-off-by: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com>
> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
> ---
>   drivers/accel/ivpu/ivpu_debugfs.c | 9 +++++++++
>   drivers/accel/ivpu/ivpu_hw.c      | 1 +
>   drivers/accel/ivpu/ivpu_hw.h      | 1 +
>   drivers/accel/ivpu/ivpu_hw_ip.c   | 5 ++++-
>   4 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c
> index 8958145c49adb..8180b95ed69dc 100644
> --- a/drivers/accel/ivpu/ivpu_debugfs.c
> +++ b/drivers/accel/ivpu/ivpu_debugfs.c
> @@ -116,6 +116,14 @@ static int reset_pending_show(struct seq_file *s, void *v)
>   	return 0;
>   }
>   
> +static int firewall_irq_counter_show(struct seq_file *s, void *v)
> +{
> +	struct ivpu_device *vdev = seq_to_ivpu(s);
> +
> +	seq_printf(s, "%d\n", atomic_read(&vdev->hw->firewall_irq_counter));
> +	return 0;
> +}
> +
>   static const struct drm_debugfs_info vdev_debugfs_list[] = {
>   	{"bo_list", bo_list_show, 0},
>   	{"fw_name", fw_name_show, 0},
> @@ -125,6 +133,7 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = {
>   	{"last_bootmode", last_bootmode_show, 0},
>   	{"reset_counter", reset_counter_show, 0},
>   	{"reset_pending", reset_pending_show, 0},
> +	{"firewall_irq_counter", firewall_irq_counter_show, 0},
>   };
>   
>   static int dvfs_mode_get(void *data, u64 *dvfs_mode)
> diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c
> index 09ada8b500b99..4e1054f3466e8 100644
> --- a/drivers/accel/ivpu/ivpu_hw.c
> +++ b/drivers/accel/ivpu/ivpu_hw.c
> @@ -252,6 +252,7 @@ int ivpu_hw_init(struct ivpu_device *vdev)
>   	platform_init(vdev);
>   	wa_init(vdev);
>   	timeouts_init(vdev);
> +	atomic_set(&vdev->hw->firewall_irq_counter, 0);
>   
>   	return 0;
>   }
> diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h
> index dc5518248c405..fc4dbfc980c81 100644
> --- a/drivers/accel/ivpu/ivpu_hw.h
> +++ b/drivers/accel/ivpu/ivpu_hw.h
> @@ -51,6 +51,7 @@ struct ivpu_hw_info {
>   	int dma_bits;
>   	ktime_t d0i3_entry_host_ts;
>   	u64 d0i3_entry_vpu_ts;
> +	atomic_t firewall_irq_counter;

Why atomic?

>   };
>   
>   int ivpu_hw_init(struct ivpu_device *vdev);
> diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c
> index b9b16f4041434..029dd065614b2 100644
> --- a/drivers/accel/ivpu/ivpu_hw_ip.c
> +++ b/drivers/accel/ivpu/ivpu_hw_ip.c
> @@ -1073,7 +1073,10 @@ static void irq_wdt_mss_handler(struct ivpu_device *vdev)
>   
>   static void irq_noc_firewall_handler(struct ivpu_device *vdev)
>   {
> -	ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ");
> +	atomic_inc(&vdev->hw->firewall_irq_counter);
> +
> +	ivpu_dbg(vdev, IRQ, "NOC Firewall interrupt detected, counter %d\n",
> +		 atomic_read(&vdev->hw->firewall_irq_counter));
>   }
>   
>   /* Handler for IRQs from NPU core */
Jacek Lawrynowicz Oct. 25, 2024, 11:44 a.m. UTC | #2
Hi,

On 10/18/2024 10:44 PM, Jeffrey Hugo wrote:
> On 10/17/2024 8:49 AM, Jacek Lawrynowicz wrote:
>> From: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com>
>>
>> The NOC firewall interrupt means that the HW prevented
>> unauthorized access to a protected resource, so there
>> is no need to trigger device reset in such case.
>>
>> To facilitate security testing add firewall_irq_counter
>> debugfs file that tracks firewall interrupts.
>>
>> Fixes: 8a27ad81f7d3 ("accel/ivpu: Split IP and buttress code")
>> Cc: <stable@vger.kernel.org> # v6.11+
>> Signed-off-by: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com>
>> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
>> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
>> ---
>>   drivers/accel/ivpu/ivpu_debugfs.c | 9 +++++++++
>>   drivers/accel/ivpu/ivpu_hw.c      | 1 +
>>   drivers/accel/ivpu/ivpu_hw.h      | 1 +
>>   drivers/accel/ivpu/ivpu_hw_ip.c   | 5 ++++-
>>   4 files changed, 15 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c
>> index 8958145c49adb..8180b95ed69dc 100644
>> --- a/drivers/accel/ivpu/ivpu_debugfs.c
>> +++ b/drivers/accel/ivpu/ivpu_debugfs.c
>> @@ -116,6 +116,14 @@ static int reset_pending_show(struct seq_file *s, void *v)
>>       return 0;
>>   }
>>   +static int firewall_irq_counter_show(struct seq_file *s, void *v)
>> +{
>> +    struct ivpu_device *vdev = seq_to_ivpu(s);
>> +
>> +    seq_printf(s, "%d\n", atomic_read(&vdev->hw->firewall_irq_counter));
>> +    return 0;
>> +}
>> +
>>   static const struct drm_debugfs_info vdev_debugfs_list[] = {
>>       {"bo_list", bo_list_show, 0},
>>       {"fw_name", fw_name_show, 0},
>> @@ -125,6 +133,7 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = {
>>       {"last_bootmode", last_bootmode_show, 0},
>>       {"reset_counter", reset_counter_show, 0},
>>       {"reset_pending", reset_pending_show, 0},
>> +    {"firewall_irq_counter", firewall_irq_counter_show, 0},
>>   };
>>     static int dvfs_mode_get(void *data, u64 *dvfs_mode)
>> diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c
>> index 09ada8b500b99..4e1054f3466e8 100644
>> --- a/drivers/accel/ivpu/ivpu_hw.c
>> +++ b/drivers/accel/ivpu/ivpu_hw.c
>> @@ -252,6 +252,7 @@ int ivpu_hw_init(struct ivpu_device *vdev)
>>       platform_init(vdev);
>>       wa_init(vdev);
>>       timeouts_init(vdev);
>> +    atomic_set(&vdev->hw->firewall_irq_counter, 0);
>>         return 0;
>>   }
>> diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h
>> index dc5518248c405..fc4dbfc980c81 100644
>> --- a/drivers/accel/ivpu/ivpu_hw.h
>> +++ b/drivers/accel/ivpu/ivpu_hw.h
>> @@ -51,6 +51,7 @@ struct ivpu_hw_info {
>>       int dma_bits;
>>       ktime_t d0i3_entry_host_ts;
>>       u64 d0i3_entry_vpu_ts;
>> +    atomic_t firewall_irq_counter;
> 
> Why atomic?
 
So we don't have to worry about synchronization and barriers.
Jeffrey Hugo Oct. 29, 2024, 10:16 p.m. UTC | #3
On 10/17/2024 8:49 AM, Jacek Lawrynowicz wrote:
> From: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com>
> 
> The NOC firewall interrupt means that the HW prevented
> unauthorized access to a protected resource, so there
> is no need to trigger device reset in such case.
> 
> To facilitate security testing add firewall_irq_counter
> debugfs file that tracks firewall interrupts.
> 
> Fixes: 8a27ad81f7d3 ("accel/ivpu: Split IP and buttress code")
> Cc: <stable@vger.kernel.org> # v6.11+
> Signed-off-by: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com>
> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>

Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
Jacek Lawrynowicz Oct. 30, 2024, 9:20 a.m. UTC | #4
Applied to drm-misc-fixes

On 10/17/2024 4:49 PM, Jacek Lawrynowicz wrote:
> From: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com>
> 
> The NOC firewall interrupt means that the HW prevented
> unauthorized access to a protected resource, so there
> is no need to trigger device reset in such case.
> 
> To facilitate security testing add firewall_irq_counter
> debugfs file that tracks firewall interrupts.
> 
> Fixes: 8a27ad81f7d3 ("accel/ivpu: Split IP and buttress code")
> Cc: <stable@vger.kernel.org> # v6.11+
> Signed-off-by: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com>
> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
> ---
>  drivers/accel/ivpu/ivpu_debugfs.c | 9 +++++++++
>  drivers/accel/ivpu/ivpu_hw.c      | 1 +
>  drivers/accel/ivpu/ivpu_hw.h      | 1 +
>  drivers/accel/ivpu/ivpu_hw_ip.c   | 5 ++++-
>  4 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c
> index 8958145c49adb..8180b95ed69dc 100644
> --- a/drivers/accel/ivpu/ivpu_debugfs.c
> +++ b/drivers/accel/ivpu/ivpu_debugfs.c
> @@ -116,6 +116,14 @@ static int reset_pending_show(struct seq_file *s, void *v)
>  	return 0;
>  }
>  
> +static int firewall_irq_counter_show(struct seq_file *s, void *v)
> +{
> +	struct ivpu_device *vdev = seq_to_ivpu(s);
> +
> +	seq_printf(s, "%d\n", atomic_read(&vdev->hw->firewall_irq_counter));
> +	return 0;
> +}
> +
>  static const struct drm_debugfs_info vdev_debugfs_list[] = {
>  	{"bo_list", bo_list_show, 0},
>  	{"fw_name", fw_name_show, 0},
> @@ -125,6 +133,7 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = {
>  	{"last_bootmode", last_bootmode_show, 0},
>  	{"reset_counter", reset_counter_show, 0},
>  	{"reset_pending", reset_pending_show, 0},
> +	{"firewall_irq_counter", firewall_irq_counter_show, 0},
>  };
>  
>  static int dvfs_mode_get(void *data, u64 *dvfs_mode)
> diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c
> index 09ada8b500b99..4e1054f3466e8 100644
> --- a/drivers/accel/ivpu/ivpu_hw.c
> +++ b/drivers/accel/ivpu/ivpu_hw.c
> @@ -252,6 +252,7 @@ int ivpu_hw_init(struct ivpu_device *vdev)
>  	platform_init(vdev);
>  	wa_init(vdev);
>  	timeouts_init(vdev);
> +	atomic_set(&vdev->hw->firewall_irq_counter, 0);
>  
>  	return 0;
>  }
> diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h
> index dc5518248c405..fc4dbfc980c81 100644
> --- a/drivers/accel/ivpu/ivpu_hw.h
> +++ b/drivers/accel/ivpu/ivpu_hw.h
> @@ -51,6 +51,7 @@ struct ivpu_hw_info {
>  	int dma_bits;
>  	ktime_t d0i3_entry_host_ts;
>  	u64 d0i3_entry_vpu_ts;
> +	atomic_t firewall_irq_counter;
>  };
>  
>  int ivpu_hw_init(struct ivpu_device *vdev);
> diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c
> index b9b16f4041434..029dd065614b2 100644
> --- a/drivers/accel/ivpu/ivpu_hw_ip.c
> +++ b/drivers/accel/ivpu/ivpu_hw_ip.c
> @@ -1073,7 +1073,10 @@ static void irq_wdt_mss_handler(struct ivpu_device *vdev)
>  
>  static void irq_noc_firewall_handler(struct ivpu_device *vdev)
>  {
> -	ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ");
> +	atomic_inc(&vdev->hw->firewall_irq_counter);
> +
> +	ivpu_dbg(vdev, IRQ, "NOC Firewall interrupt detected, counter %d\n",
> +		 atomic_read(&vdev->hw->firewall_irq_counter));
>  }
>  
>  /* Handler for IRQs from NPU core */
diff mbox series

Patch

diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c
index 8958145c49adb..8180b95ed69dc 100644
--- a/drivers/accel/ivpu/ivpu_debugfs.c
+++ b/drivers/accel/ivpu/ivpu_debugfs.c
@@ -116,6 +116,14 @@  static int reset_pending_show(struct seq_file *s, void *v)
 	return 0;
 }
 
+static int firewall_irq_counter_show(struct seq_file *s, void *v)
+{
+	struct ivpu_device *vdev = seq_to_ivpu(s);
+
+	seq_printf(s, "%d\n", atomic_read(&vdev->hw->firewall_irq_counter));
+	return 0;
+}
+
 static const struct drm_debugfs_info vdev_debugfs_list[] = {
 	{"bo_list", bo_list_show, 0},
 	{"fw_name", fw_name_show, 0},
@@ -125,6 +133,7 @@  static const struct drm_debugfs_info vdev_debugfs_list[] = {
 	{"last_bootmode", last_bootmode_show, 0},
 	{"reset_counter", reset_counter_show, 0},
 	{"reset_pending", reset_pending_show, 0},
+	{"firewall_irq_counter", firewall_irq_counter_show, 0},
 };
 
 static int dvfs_mode_get(void *data, u64 *dvfs_mode)
diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c
index 09ada8b500b99..4e1054f3466e8 100644
--- a/drivers/accel/ivpu/ivpu_hw.c
+++ b/drivers/accel/ivpu/ivpu_hw.c
@@ -252,6 +252,7 @@  int ivpu_hw_init(struct ivpu_device *vdev)
 	platform_init(vdev);
 	wa_init(vdev);
 	timeouts_init(vdev);
+	atomic_set(&vdev->hw->firewall_irq_counter, 0);
 
 	return 0;
 }
diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h
index dc5518248c405..fc4dbfc980c81 100644
--- a/drivers/accel/ivpu/ivpu_hw.h
+++ b/drivers/accel/ivpu/ivpu_hw.h
@@ -51,6 +51,7 @@  struct ivpu_hw_info {
 	int dma_bits;
 	ktime_t d0i3_entry_host_ts;
 	u64 d0i3_entry_vpu_ts;
+	atomic_t firewall_irq_counter;
 };
 
 int ivpu_hw_init(struct ivpu_device *vdev);
diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c
index b9b16f4041434..029dd065614b2 100644
--- a/drivers/accel/ivpu/ivpu_hw_ip.c
+++ b/drivers/accel/ivpu/ivpu_hw_ip.c
@@ -1073,7 +1073,10 @@  static void irq_wdt_mss_handler(struct ivpu_device *vdev)
 
 static void irq_noc_firewall_handler(struct ivpu_device *vdev)
 {
-	ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ");
+	atomic_inc(&vdev->hw->firewall_irq_counter);
+
+	ivpu_dbg(vdev, IRQ, "NOC Firewall interrupt detected, counter %d\n",
+		 atomic_read(&vdev->hw->firewall_irq_counter));
 }
 
 /* Handler for IRQs from NPU core */