All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jean Delvare <jdelvare@suse.de>
To: Guenter Roeck <linux@roeck-us.net>
Cc: Hardware Monitoring <linux-hwmon@vger.kernel.org>,
	Naveen Krishna Chatradhi <nchatrad@amd.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: Re: [PATCH v2 2/2] hwmon: (amd_energy) Restore visibility of energy counters
Date: Mon, 12 Apr 2021 14:27:44 +0200	[thread overview]
Message-ID: <20210412142744.54c55d06@endymion> (raw)
In-Reply-To: <20210409174852.4585-2-linux@roeck-us.net>

On Fri,  9 Apr 2021 10:48:52 -0700, Guenter Roeck wrote:
> Commit 60268b0e8258 ("hwmon: (amd_energy) modify the visibility of
> the counters") restricted visibility of AMD energy counters to work
> around a side-channel attack using energy data to determine which
> instructions are executed. The attack is described in 'PLATYPUS:
> Software-based Power Side-Channel Attacks on x86'. It relies on quick
> and accurate energy readings.
> 
> Limiting energy readings to privileged users is annoying. A much better
> solution is to make energy readings unusable for attacks by randomizing
> the time between updates. We can do that by caching energy values for
> a short and randomized period of time.
> 
> Cc: Naveen Krishna Chatradhi <nchatrad@amd.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
> v2: Simplified code by using unified function to accumulate energy data
> 
>  drivers/hwmon/amd_energy.c | 29 +++++++++++++++++++++--------
>  1 file changed, 21 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/hwmon/amd_energy.c b/drivers/hwmon/amd_energy.c
> index 93bad64039f1..1bf0afc2740c 100644
> --- a/drivers/hwmon/amd_energy.c
> +++ b/drivers/hwmon/amd_energy.c
> @@ -18,6 +18,7 @@
>  #include <linux/mutex.h>
>  #include <linux/processor.h>
>  #include <linux/platform_device.h>
> +#include <linux/random.h>
>  #include <linux/sched.h>
>  #include <linux/slab.h>
>  #include <linux/topology.h>
> @@ -35,6 +36,7 @@
>  struct sensor_accumulator {
>  	u64 energy_ctr;
>  	u64 prev_value;
> +	unsigned long cache_timeout;
>  };
>  
>  struct amd_energy_data {
> @@ -74,17 +76,14 @@ static void get_energy_units(struct amd_energy_data *data)
>  	data->energy_units = (rapl_units & AMD_ENERGY_UNIT_MASK) >> 8;
>  }
>  

Add a comment stating that this function must be called with accum's
&data->lock held?

> -static void accumulate_delta(struct amd_energy_data *data,
> -			     int channel, int cpu, u32 reg)
> +static void __accumulate_delta(struct sensor_accumulator *accum,
> +			       int cpu, u32 reg)
>  {
> -	struct sensor_accumulator *accum;
>  	u64 input;
>  
> -	mutex_lock(&data->lock);
>  	rdmsrl_safe_on_cpu(cpu, reg, &input);
>  	input &= AMD_ENERGY_MASK;
>  
> -	accum = &data->accums[channel];
>  	if (input >= accum->prev_value)
>  		accum->energy_ctr +=
>  			input - accum->prev_value;
> @@ -93,6 +92,14 @@ static void accumulate_delta(struct amd_energy_data *data,
>  			accum->prev_value + input;
>  
>  	accum->prev_value = input;
> +	accum->cache_timeout = jiffies + HZ + get_random_int() % HZ;

Needs #include <linux/jiffies.h> maybe?

> +}
> +
> +static void accumulate_delta(struct amd_energy_data *data,
> +			     int channel, int cpu, u32 reg)
> +{
> +	mutex_lock(&data->lock);
> +	__accumulate_delta(&data->accums[channel], cpu, reg);
>  	mutex_unlock(&data->lock);
>  }
>  
> @@ -124,6 +131,7 @@ static int amd_energy_read(struct device *dev,
>  {
>  	struct amd_energy_data *data = dev_get_drvdata(dev);
>  	struct sensor_accumulator *accum;
> +	u64 energy;
>  	u32 reg;
>  	int cpu;
>  
> @@ -140,10 +148,15 @@ static int amd_energy_read(struct device *dev,
>  		reg = ENERGY_CORE_MSR;
>  	}
>  
> -	accumulate_delta(data, channel, cpu, reg);
>  	accum = &data->accums[channel];
>  
> -	*val = div64_ul(accum->energy_ctr * 1000000UL, BIT(data->energy_units));
> +	mutex_lock(&data->lock);
> +	if (!accum->energy_ctr || time_after(jiffies, accum->cache_timeout))
> +		__accumulate_delta(accum, cpu, reg);
> +	energy = accum->energy_ctr;
> +	mutex_unlock(&data->lock);
> +
> +	*val = div64_ul(energy * 1000000UL, BIT(data->energy_units));
>  
>  	return 0;
>  }
> @@ -152,7 +165,7 @@ static umode_t amd_energy_is_visible(const void *_data,
>  				     enum hwmon_sensor_types type,
>  				     u32 attr, int channel)
>  {
> -	return 0440;
> +	return 0444;
>  }
>  
>  static int energy_accumulator(void *p)

Very nice. This will make the driver useful again :-)

Reviewed-by: Jean Delvare <jdelvare@suse.de>

-- 
Jean Delvare
SUSE L3 Support

  reply	other threads:[~2021-04-12 12:27 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-09 17:48 [PATCH v2 1/2] hwmon: (amd_energy) Use unified function to read energy data Guenter Roeck
2021-04-09 17:48 ` [PATCH v2 2/2] hwmon: (amd_energy) Restore visibility of energy counters Guenter Roeck
2021-04-12 12:27   ` Jean Delvare [this message]
2021-04-12 14:25     ` Guenter Roeck
2021-04-19 16:29       ` Chatradhi, Naveen Krishna
2021-04-19 17:41         ` Guenter Roeck
2021-04-12 12:14 ` [PATCH v2 1/2] hwmon: (amd_energy) Use unified function to read energy data Jean Delvare
2021-04-12 14:17   ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210412142744.54c55d06@endymion \
    --to=jdelvare@suse.de \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=nchatrad@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.