Re: [PATCH V2] block: sed-opal: Set MBRDone on S3 resume path if TPER is MBREnabled

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Looks good

Acked-by Jon Derrick: <jonathan.derrick@xxxxxxxxx>


On 09/01/2017 08:53 AM, Scott Bauer wrote:
> Users who are booting off their Opal enabled drives are having
> issues when they have a shadow MBR set up after s3/resume cycle.
> When the Drive has a shadow MBR setup the MBRDone flag is set to
> false upon power loss (S3/S4/S5). When the MBRDone flag is false
> I/O to LBA 0 -> LBA_END_MBR are remapped to the shadow mbr
> of the drive. If the drive contains useful data in the 0 -> end_mbr
> range upon s3 resume the user can never get to that data as the
> drive will keep remapping it to the MBR. To fix this when we unlock
> on S3 resume, we need to tell the drive that we're done with the
> shadow mbr (even though we didnt use it) by setting true to MBRDone.
> This way the drive will stop the remapping and the user can access
> their data.
> 
> Signed-off-by: Scott Bauer <scott.bauer@xxxxxxxxx>
> ---
>  block/opal_proto.h |  1 +
>  block/sed-opal.c   | 32 ++++++++++++++++++++++++++++++++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/block/opal_proto.h b/block/opal_proto.h
> index f40c9acf8895..e20be8258854 100644
> --- a/block/opal_proto.h
> +++ b/block/opal_proto.h
> @@ -46,6 +46,7 @@ enum opal_response_token {
>  #define GENERIC_HOST_SESSION_NUM 0x41
>  
>  #define TPER_SYNC_SUPPORTED 0x01
> +#define MBR_ENABLED_MASK 0x10
>  
>  #define TINY_ATOM_DATA_MASK 0x3F
>  #define TINY_ATOM_SIGNED 0x40
> diff --git a/block/sed-opal.c b/block/sed-opal.c
> index 9b30ae5ab843..9ed51d0c6b1d 100644
> --- a/block/sed-opal.c
> +++ b/block/sed-opal.c
> @@ -80,6 +80,7 @@ struct parsed_resp {
>  
>  struct opal_dev {
>  	bool supported;
> +	bool mbr_enabled;
>  
>  	void *data;
>  	sec_send_recv *send_recv;
> @@ -283,6 +284,14 @@ static bool check_tper(const void *data)
>  	return true;
>  }
>  
> +static bool check_mbrenabled(const void *data)
> +{
> +	const struct d0_locking_features *lfeat = data;
> +	u8 sup_feat = lfeat->supported_features;
> +
> +	return !!(sup_feat & MBR_ENABLED_MASK);
> +}
> +
>  static bool check_sum(const void *data)
>  {
>  	const struct d0_single_user_mode *sum = data;
> @@ -417,6 +426,7 @@ static int opal_discovery0_end(struct opal_dev *dev)
>  	u32 hlen = be32_to_cpu(hdr->length);
>  
>  	print_buffer(dev->resp, hlen);
> +	dev->mbr_enabled = false;
>  
>  	if (hlen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
>  		pr_debug("Discovery length overflows buffer (%zu+%u)/%u\n",
> @@ -442,6 +452,8 @@ static int opal_discovery0_end(struct opal_dev *dev)
>  			check_geometry(dev, body);
>  			break;
>  		case FC_LOCKING:
> +			dev->mbr_enabled = check_mbrenabled(body->features);
> +			break;
>  		case FC_ENTERPRISE:
>  		case FC_DATASTORE:
>  			/* some ignored properties */
> @@ -2190,6 +2202,21 @@ static int __opal_lock_unlock(struct opal_dev *dev,
>  	return next(dev);
>  }
>  
> +static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key)
> +{
> +	u8 mbr_done_tf = 1;
> +	const struct opal_step mbrdone_step [] = {
> +		{ opal_discovery0, },
> +		{ start_admin1LSP_opal_session, key },
> +		{ set_mbr_done, &mbr_done_tf },
> +		{ end_opal_session, },
> +		{ NULL, }
> +	};
> +
> +	dev->steps = mbrdone_step;
> +	return next(dev);
> +}
> +
>  static int opal_lock_unlock(struct opal_dev *dev,
>  			    struct opal_lock_unlock *lk_unlk)
>  {
> @@ -2345,6 +2372,11 @@ bool opal_unlock_from_suspend(struct opal_dev *dev)
>  				 suspend->unlk.session.sum);
>  			was_failure = true;
>  		}
> +		if (dev->mbr_enabled) {
> +			ret = __opal_set_mbr_done(dev, &suspend->unlk.session.opal_key);
> +			if (ret)
> +				pr_debug("Failed to set MBR Done in S3 resume\n");
> +		}
>  	}
>  	mutex_unlock(&dev->dev_lock);
>  	return was_failure;
> 




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux