lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <fcd0621b-dd68-4e0d-96e1-15c16a3278d0@os.amperecomputing.com>
Date: Wed, 5 Jun 2024 14:33:22 -0700
From: Daniel Ferguson <danielf@...amperecomputing.com>
To: shiju.jose@...wei.com
Cc: linux-edac@...r.kernel.org, linux-kernel@...r.kernel.org,
 david@...hat.com, Vilas.Sridharan@....com, leo.duran@....com,
 Yazen.Ghannam@....com, rientjes@...gle.com, jiaqiyan@...gle.com,
 tony.luck@...el.com, Jon.Grimm@....com, dave.hansen@...ux.intel.com,
 rafael@...nel.org, lenb@...nel.org, naoya.horiguchi@....com,
 james.morse@....com, jthoughton@...gle.com, somasundaram.a@....com,
 erdemaktas@...gle.com, pgonda@...gle.com, duenwen@...gle.com,
 mike.malvestuto@...el.com, gthelen@...gle.com,
 wschwartz@...erecomputing.com, dferguson@...erecomputing.com,
 wbs@...amperecomputing.com, nifan.cxl@...il.com, tanxiaofei@...wei.com,
 prime.zeng@...ilicon.com, kangkang.shen@...urewei.com,
 wanghuiqiang@...wei.com, linuxarm@...wei.com, ira.weiny@...el.com,
 vishal.l.verma@...el.com, alison.schofield@...el.com, dave.jiang@...el.com,
 jonathan.cameron@...wei.com, dave@...olabs.net, dan.j.williams@...el.com,
 linux-mm@...ck.org, linux-acpi@...r.kernel.org, linux-cxl@...r.kernel.org
Subject: Re: [RFC PATCH v8 10/10] ras: scrub: ACPI RAS2: Add memory ACPI RAS2
 driver

> +/* Context - lock must be held */
> +static int ras2_get_patrol_scrub_running(struct ras2_scrub_ctx *ras2_ctx,
> +					 bool *running)
> +{
> +	struct acpi_ras2_ps_shared_mem __iomem *ps_sm = (void *)
> +					ras2_ctx->pcc_subspace->pcc_comm_addr;
> +	int ret;
> +
> +	if (ras2_ctx->bg)
> +		*running = true;
> +
> +	ps_sm->common.set_capabilities[0] = RAS2_SUPPORT_HW_PARTOL_SCRUB;
> +	ps_sm->params.patrol_scrub_command = RAS2_GET_PATROL_PARAMETERS;

Need to reset the address range (base and size). A user may have previously
called "Enable Background" where the code zeros out these parameters.
	ps_sm->params.requested_address_range[0] = ras2_ctx->base;
	ps_sm->params.requested_address_range[1] = ras2_ctx->size;


> +
> +	ret = ras2_send_pcc_cmd(ras2_ctx, RAS2_PCC_CMD_EXEC);
> +	if (ret) {
> +		dev_err(ras2_ctx->dev, "failed to read parameters\n");
> +		return ret;
> +	}
> +
> +	*running = ps_sm->params.flags & RAS2_PATROL_SCRUB_FLAG_SCRUBBER_RUNNING;
> +
> +	return 0;
> +}
> +
> +static int ras2_hw_scrub_write_rate(struct device *dev, u64 rate)
> +{
> +	struct ras2_scrub_ctx *ras2_ctx = dev_get_drvdata(dev);
> +	bool running;
> +	int ret;
> +
> +	guard(mutex)(&ras2_ctx->lock);
> +	ret = ras2_get_patrol_scrub_running(ras2_ctx, &running);
> +	if (ret)
> +		return ret;
> +
> +	if (running)
> +		return -EBUSY;


I suggest we do not check if the patrol scrub is running when we are merely
updating cached values. More importantly, if we had
previously wrote an invalid value (that is only invalidated by firmware
after
executing a command), then when we try to write a correct value,
this "ras2_get_patrol_scrub_running" check will always fail, therefore
preventing us from correcting our error.

> +
> +	if (rate < ras2_ctx->rate_min || rate > ras2_ctx->rate_max)
> +		return -EINVAL;
> +
> +	ras2_ctx->rate = rate;
> +
> +	return 0;
> +}
> +
> +static int ras2_hw_scrub_read_rate(struct device *dev, u64 *rate)
> +{
> +	struct ras2_scrub_ctx *ras2_ctx = dev_get_drvdata(dev);
> +
> +	*rate = ras2_ctx->rate;
> +
> +	return 0;
> +}
> +
> +static int ras2_hw_scrub_read_rate_avail(struct device *dev, u64 *min, u64 *max)
> +{
> +	struct ras2_scrub_ctx *ras2_ctx = dev_get_drvdata(dev);
> +
> +	*min = ras2_ctx->rate_min;
> +	*max = ras2_ctx->rate_max;
> +
> +	return 0;
> +}
> +
> +static int ras2_hw_scrub_read_range(struct device *dev, u64 *base, u64 *size)
> +{
> +	struct ras2_scrub_ctx *ras2_ctx = dev_get_drvdata(dev);
> +
> +	*base = ras2_ctx->base;
> +	*size = ras2_ctx->size;
> +
> +	return 0;
> +}
> +
> +static int ras2_hw_scrub_write_range(struct device *dev, u64 base, u64 size)
> +{
> +	struct ras2_scrub_ctx *ras2_ctx = dev_get_drvdata(dev);
> +	bool running;
> +	int ret;
> +
> +	guard(mutex)(&ras2_ctx->lock);
> +	ret = ras2_get_patrol_scrub_running(ras2_ctx, &running);
> +	if (ret)
> +		return ret;
> +
> +	if (running)
> +		return -EBUSY;

I suggest we do not check if the patrol scrub is running. See previous
comment above.

> +
> +	ras2_ctx->base = base;
> +	ras2_ctx->size = size;
> +
> +	return 0;
> +}
> +
> +static int ras2_hw_scrub_set_enabled_bg(struct device *dev, bool enable)
> +{
> +	struct ras2_scrub_ctx *ras2_ctx = dev_get_drvdata(dev);
> +	struct acpi_ras2_ps_shared_mem __iomem *ps_sm = (void *)
> +					ras2_ctx->pcc_subspace->pcc_comm_addr;
> +	int ret;
> +
> +	guard(mutex)(&ras2_ctx->lock);
> +	ps_sm->common.set_capabilities[0] = RAS2_SUPPORT_HW_PARTOL_SCRUB;
> +	if (enable) {
> +		ps_sm->params.requested_address_range[0] = 0;
> +		ps_sm->params.requested_address_range[1] = 0;
> +		ps_sm->params.scrub_params_in &= ~RAS2_PATROL_SCRUB_RATE_IN_MASK;
> +		ps_sm->params.scrub_params_in |= FIELD_PREP(RAS2_PATROL_SCRUB_RATE_IN_MASK,
> +							    ras2_ctx->rate);
> +		ps_sm->params.patrol_scrub_command = RAS2_START_PATROL_SCRUBBER;
> +	} else {
> +		ps_sm->params.patrol_scrub_command = RAS2_STOP_PATROL_SCRUBBER;
> +	}
> +	ps_sm->params.scrub_params_in &= ~RAS2_PATROL_SCRUB_EN_BACKGROUND;
> +	ps_sm->params.scrub_params_in |= FIELD_PREP(RAS2_PATROL_SCRUB_EN_BACKGROUND,
> +						    enable);
> +
> +	ret = ras2_send_pcc_cmd(ras2_ctx, RAS2_PCC_CMD_EXEC);
> +	if (ret) {
> +		dev_err(ras2_ctx->dev, "%s: failed to enable(%d) background scrubbing\n",
> +			__func__, enable);
> +		return ret;
> +	}
> +	ras2_ctx->bg = true;
> +
> +	/* Update the cache to account for rounding of supplied parameters and similar */
> +	return ras2_update_patrol_scrub_params_cache(ras2_ctx);
> +}
> +
> +static int ras2_hw_scrub_get_enabled_bg(struct device *dev, bool *enabled)
> +{
> +	struct ras2_scrub_ctx *ras2_ctx = dev_get_drvdata(dev);
> +
> +	*enabled = ras2_ctx->bg;
> +
> +	return 0;
> +}
> +
> +static int ras2_hw_scrub_set_enabled_od(struct device *dev, bool enable)
> +{
> +	struct ras2_scrub_ctx *ras2_ctx = dev_get_drvdata(dev);
> +	struct acpi_ras2_ps_shared_mem __iomem *ps_sm = (void *)
> +					ras2_ctx->pcc_subspace->pcc_comm_addr;
> +	bool enabled;
> +	int ret;
> +
> +	guard(mutex)(&ras2_ctx->lock);
> +	ps_sm->common.set_capabilities[0] = RAS2_SUPPORT_HW_PARTOL_SCRUB;
> +	if (enable) {
> +		if (!ras2_ctx->size) {
> +			dev_warn(ras2_ctx->dev,
> +				 "%s: Invalid requested address range, requested_address_range[0]=0x%llx "
> +				 "requested_address_range[1]=0x%llx\n", __func__,
> +				 ps_sm->params.requested_address_range[0],
> +				 ps_sm->params.requested_address_range[1]);
> +			return -ERANGE;
> +		}
> +		ret = ras2_get_patrol_scrub_running(ras2_ctx, &enabled);
> +		if (ret)
> +			return ret;
> +
> +		if (enabled)
> +			return 0;
> +
> +		ps_sm->params.scrub_params_in &= ~RAS2_PATROL_SCRUB_RATE_IN_MASK;
> +		ps_sm->params.scrub_params_in |= FIELD_PREP(RAS2_PATROL_SCRUB_RATE_IN_MASK,
> +							    ras2_ctx->rate);
> +		ps_sm->params.requested_address_range[0] = ras2_ctx->base;
> +		ps_sm->params.requested_address_range[1] = ras2_ctx->size;


We need to clear the RAS2_PATROL_SCRUB_EN_BACKGROUND bit in the input
parameters.
This is in case "Enable Background" was previously called, and this bit
was set.

		ps_sm->params.scrub_params_in &= ~RAS2_PATROL_SCRUB_EN_BACKGROUND;


> +		ps_sm->params.patrol_scrub_command = RAS2_START_PATROL_SCRUBBER;
> +	} else {
> +		ps_sm->params.patrol_scrub_command = RAS2_STOP_PATROL_SCRUBBER;
> +	}
> +
> +	ret = ras2_send_pcc_cmd(ras2_ctx, RAS2_PCC_CMD_EXEC);
> +	if (ret) {
> +		dev_err(ras2_ctx->dev, "failed to enable(%d) the demand scrubbing\n", enable);
> +		return ret;
> +	}
> +	ras2_ctx->bg = false;
> +
> +	return ras2_update_patrol_scrub_params_cache(ras2_ctx);
> +}




Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ