public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: "Stephen M. Cameron" <scameron@beardog.cce.hp.com>
To: jbottomley@parallels.com
Cc: stephenmcameron@gmail.com, mikem@beardog.cce.hp.com,
	matthew.gates@hp.com, linux-scsi@vger.kernel.org,
	scott.teel@hp.com
Subject: [PATCH 35/41] hpsa: add controller base data-at-rest encryption compatibility ioaccel2
Date: Wed, 15 Jan 2014 16:39:23 -0600	[thread overview]
Message-ID: <20140115223923.5061.34124.stgit@beardog.cce.hp.com> (raw)
In-Reply-To: <20140115223354.5061.50276.stgit@beardog.cce.hp.com>

From: Scott Teel <scott.teel@hp.com>

Add controller-based data-at-rest encryption compatibility
to ioaccel2 path (HP SSD Smart Path).

Encryption feature requires driver to supply additional fields
for encryption enable, tweak index, and data encryption key index
in the ioaccel2 request structure.

Encryption enable flag and data encryption key index come from
raid_map data structure from raid offload command.

During ioaccel2 submission, check device structure's raid map to see if
encryption is enabled for the device. If so, call new function below.

Add function set_encrypt_ioaccel2 to set encryption flag, data encryption key
index, and calculate tweak value from request's logical block address.

Signed-off-by: Scott Teel <scott.teel@hp.com>
Acked-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
---
 drivers/scsi/hpsa.c     |  179 +++++++++++++++++++++++++++++++++++++++++++++--
 drivers/scsi/hpsa_cmd.h |   19 ++++-
 2 files changed, 184 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 5278cf0..7764e5c 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2026,6 +2026,14 @@ static void hpsa_debug_map_buff(struct ctlr_info *h, int rc,
 			le16_to_cpu(map_buff->row_cnt));
 	dev_info(&h->pdev->dev, "layout_map_count = %u\n",
 			le16_to_cpu(map_buff->layout_map_count));
+	dev_info(&h->pdev->dev, "flags = %u\n",
+			le16_to_cpu(map_buff->flags));
+	if (map_buff->flags & RAID_MAP_FLAG_ENCRYPT_ON)
+		dev_info(&h->pdev->dev, "encrypytion = ON\n");
+	else
+		dev_info(&h->pdev->dev, "encrypytion = OFF\n");
+	dev_info(&h->pdev->dev, "dekindex = %u\n",
+			le16_to_cpu(map_buff->dekindex));
 
 	map_cnt = le16_to_cpu(map_buff->layout_map_count);
 	for (map = 0; map < map_cnt; map++) {
@@ -2973,6 +2981,128 @@ static int hpsa_scsi_ioaccel_direct_map(struct ctlr_info *h,
 		cmd->cmnd, cmd->cmd_len, dev->scsi3addr);
 }
 
+/*
+ * Set encryption parameters for the ioaccel2 request
+ */
+static void set_encrypt_ioaccel2(struct ctlr_info *h,
+	struct CommandList *c, struct io_accel2_cmd *cp)
+{
+	struct scsi_cmnd *cmd = c->scsi_cmd;
+	struct hpsa_scsi_dev_t *dev = cmd->device->hostdata;
+	struct raid_map_data *map = &dev->raid_map;
+	u64 first_block;
+
+	BUG_ON(!(dev->offload_config && dev->offload_enabled));
+
+	/* Are we doing encryption on this device */
+	if (!(map->flags & RAID_MAP_FLAG_ENCRYPT_ON))
+		return;
+	/* Set the data encryption key index. */
+	cp->dekindex = map->dekindex;
+
+	/* Set the encryption enable flag, encoded into direction field. */
+	cp->direction |= IOACCEL2_DIRECTION_ENCRYPT_MASK;
+
+	/* Set encryption tweak values based on logical block address
+	 * If block size is 512, tweak value is LBA.
+	 * For other block sizes, tweak is (LBA * block size)/ 512)
+	 */
+	switch (cmd->cmnd[0]) {
+	/* Required? 6-byte cdbs eliminated by fixup_ioaccel_cdb */
+	case WRITE_6:
+	case READ_6:
+		if (map->volume_blk_size == 512) {
+			cp->tweak_lower =
+				(((u32) cmd->cmnd[2]) << 8) |
+					cmd->cmnd[3];
+			cp->tweak_upper = 0;
+		} else {
+			first_block =
+				(((u64) cmd->cmnd[2]) << 8) |
+					cmd->cmnd[3];
+			first_block = (first_block * map->volume_blk_size)/512;
+			cp->tweak_lower = (u32)first_block;
+			cp->tweak_upper = (u32)(first_block >> 32);
+		}
+		break;
+	case WRITE_10:
+	case READ_10:
+		if (map->volume_blk_size == 512) {
+			cp->tweak_lower =
+				(((u32) cmd->cmnd[2]) << 24) |
+				(((u32) cmd->cmnd[3]) << 16) |
+				(((u32) cmd->cmnd[4]) << 8) |
+					cmd->cmnd[5];
+			cp->tweak_upper = 0;
+		} else {
+			first_block =
+				(((u64) cmd->cmnd[2]) << 24) |
+				(((u64) cmd->cmnd[3]) << 16) |
+				(((u64) cmd->cmnd[4]) << 8) |
+					cmd->cmnd[5];
+			first_block = (first_block * map->volume_blk_size)/512;
+			cp->tweak_lower = (u32)first_block;
+			cp->tweak_upper = (u32)(first_block >> 32);
+		}
+		break;
+	/* Required? 12-byte cdbs eliminated by fixup_ioaccel_cdb */
+	case WRITE_12:
+	case READ_12:
+		if (map->volume_blk_size == 512) {
+			cp->tweak_lower =
+				(((u32) cmd->cmnd[2]) << 24) |
+				(((u32) cmd->cmnd[3]) << 16) |
+				(((u32) cmd->cmnd[4]) << 8) |
+					cmd->cmnd[5];
+			cp->tweak_upper = 0;
+		} else {
+			first_block =
+				(((u64) cmd->cmnd[2]) << 24) |
+				(((u64) cmd->cmnd[3]) << 16) |
+				(((u64) cmd->cmnd[4]) << 8) |
+					cmd->cmnd[5];
+			first_block = (first_block * map->volume_blk_size)/512;
+			cp->tweak_lower = (u32)first_block;
+			cp->tweak_upper = (u32)(first_block >> 32);
+		}
+		break;
+	case WRITE_16:
+	case READ_16:
+		if (map->volume_blk_size == 512) {
+			cp->tweak_lower =
+				(((u32) cmd->cmnd[6]) << 24) |
+				(((u32) cmd->cmnd[7]) << 16) |
+				(((u32) cmd->cmnd[8]) << 8) |
+					cmd->cmnd[9];
+			cp->tweak_upper =
+				(((u32) cmd->cmnd[2]) << 24) |
+				(((u32) cmd->cmnd[3]) << 16) |
+				(((u32) cmd->cmnd[4]) << 8) |
+					cmd->cmnd[5];
+		} else {
+			first_block =
+				(((u64) cmd->cmnd[2]) << 56) |
+				(((u64) cmd->cmnd[3]) << 48) |
+				(((u64) cmd->cmnd[4]) << 40) |
+				(((u64) cmd->cmnd[5]) << 32) |
+				(((u64) cmd->cmnd[6]) << 24) |
+				(((u64) cmd->cmnd[7]) << 16) |
+				(((u64) cmd->cmnd[8]) << 8) |
+					cmd->cmnd[9];
+			first_block = (first_block * map->volume_blk_size)/512;
+			cp->tweak_lower = (u32)first_block;
+			cp->tweak_upper = (u32)(first_block >> 32);
+		}
+		break;
+	default:
+		dev_err(&h->pdev->dev,
+			"ERROR: %s: IOACCEL request CDB size not supported for encryption\n",
+			__func__);
+		BUG();
+		break;
+	}
+}
+
 static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
 	struct CommandList *c, u32 ioaccel_handle, u8 *cdb, int cdb_len,
 	u8 *scsi3addr)
@@ -3022,13 +3152,16 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
 
 		switch (cmd->sc_data_direction) {
 		case DMA_TO_DEVICE:
-			cp->direction = IOACCEL2_DIR_DATA_OUT;
+			cp->direction &= ~IOACCEL2_DIRECTION_MASK;
+			cp->direction |= IOACCEL2_DIR_DATA_OUT;
 			break;
 		case DMA_FROM_DEVICE:
-			cp->direction = IOACCEL2_DIR_DATA_IN;
+			cp->direction &= ~IOACCEL2_DIRECTION_MASK;
+			cp->direction |= IOACCEL2_DIR_DATA_IN;
 			break;
 		case DMA_NONE:
-			cp->direction = IOACCEL2_DIR_NO_DATA;
+			cp->direction &= ~IOACCEL2_DIRECTION_MASK;
+			cp->direction |= IOACCEL2_DIR_NO_DATA;
 			break;
 		default:
 			dev_err(&h->pdev->dev, "unknown data direction: %d\n",
@@ -3037,10 +3170,15 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
 			break;
 		}
 	} else {
-		cp->direction = IOACCEL2_DIR_NO_DATA;
+		cp->direction &= ~IOACCEL2_DIRECTION_MASK;
+		cp->direction |= IOACCEL2_DIR_NO_DATA;
 	}
+
+	/* Set encryption parameters, if necessary */
+	set_encrypt_ioaccel2(h, c, cp);
+
 	cp->scsi_nexus = ioaccel_handle;
-	cp->Tag.lower = (c->cmdindex << DIRECT_LOOKUP_SHIFT) |
+	cp->Tag = (c->cmdindex << DIRECT_LOOKUP_SHIFT) |
 				DIRECT_LOOKUP_BIT;
 	memcpy(cp->cdb, cdb, sizeof(cp->cdb));
 	memset(cp->cciss_lun, 0, sizeof(cp->cciss_lun));
@@ -3798,8 +3936,9 @@ static void hpsa_get_tag(struct ctlr_info *h,
 	if (c->cmd_type == CMD_IOACCEL2) {
 		struct io_accel2_cmd *cm2 = (struct io_accel2_cmd *)
 			&h->ioaccel2_cmd_pool[c->cmdindex];
-		*tagupper = cm2->Tag.upper;
-		*taglower = cm2->Tag.lower;
+		/* upper tag not used in ioaccel2 mode */
+		memset(tagupper, 0, sizeof(*tagupper));
+		*taglower = cm2->Tag;
 		return;
 	}
 	*tagupper = c->Header.Tag.upper;
@@ -3847,8 +3986,8 @@ static int hpsa_send_abort(struct ctlr_info *h, unsigned char *scsi3addr,
 		break;
 	}
 	cmd_special_free(h, c);
-	dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: Finished.\n", __func__,
-		abort->Header.Tag.upper, abort->Header.Tag.lower);
+	dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: Finished.\n",
+		__func__, tagupper, taglower);
 	return rc;
 }
 
@@ -6977,6 +7116,28 @@ static void __exit hpsa_cleanup(void)
 static void __attribute__((unused)) verify_offsets(void)
 {
 #define VERIFY_OFFSET(member, offset) \
+	BUILD_BUG_ON(offsetof(struct raid_map_data, member) != offset)
+
+	VERIFY_OFFSET(structure_size, 0);
+	VERIFY_OFFSET(volume_blk_size, 4);
+	VERIFY_OFFSET(volume_blk_cnt, 8);
+	VERIFY_OFFSET(phys_blk_shift, 16);
+	VERIFY_OFFSET(parity_rotation_shift, 17);
+	VERIFY_OFFSET(strip_size, 18);
+	VERIFY_OFFSET(disk_starting_blk, 20);
+	VERIFY_OFFSET(disk_blk_cnt, 28);
+	VERIFY_OFFSET(data_disks_per_row, 36);
+	VERIFY_OFFSET(metadata_disks_per_row, 38);
+	VERIFY_OFFSET(row_cnt, 40);
+	VERIFY_OFFSET(layout_map_count, 42);
+	VERIFY_OFFSET(flags, 44);
+	VERIFY_OFFSET(dekindex, 46);
+	/* VERIFY_OFFSET(reserved, 48 */
+	VERIFY_OFFSET(data, 64);
+
+#undef VERIFY_OFFSET
+
+#define VERIFY_OFFSET(member, offset) \
 	BUILD_BUG_ON(offsetof(struct io_accel2_cmd, member) != offset)
 
 	VERIFY_OFFSET(IU_type, 0);
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 7768092..eaa7fda 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -209,7 +209,10 @@ struct raid_map_data {
 	u16   row_cnt;			/* rows in each layout map */
 	u16   layout_map_count;		/* layout maps (1 map per mirror/parity
 					 * group) */
-	u8    reserved[20];
+	u16   flags;			/* Bit 0 set if encryption enabled */
+#define RAID_MAP_FLAG_ENCRYPT_ON  0x01
+	u16   dekindex;			/* Data encryption key index. */
+	u8    reserved[16];
 	struct raid_map_disk_data data[RAID_MAP_MAX_ENTRIES];
 };
 
@@ -502,11 +505,17 @@ struct io_accel2_scsi_response {
  */
 struct io_accel2_cmd {
 	u8  IU_type;			/* IU Type */
-	u8  direction;                  /* Transfer direction, 2 bits */
+	u8  direction;			/* direction, memtype, and encryption */
+#define IOACCEL2_DIRECTION_MASK		0x03 /* bits 0,1: direction  */
+#define IOACCEL2_DIRECTION_MEMTYPE_MASK	0x04 /* bit 2: memtype source/dest */
+					     /*     0b=PCIe, 1b=DDR */
+#define IOACCEL2_DIRECTION_ENCRYPT_MASK	0x08 /* bit 3: encryption flag */
+					     /*     0=off, 1=on */
 	u8  reply_queue;		/* Reply Queue ID */
 	u8  reserved1;			/* Reserved */
 	u32 scsi_nexus;			/* Device Handle */
-	struct vals32 Tag;		/* cciss tag */
+	u32 Tag;			/* cciss tag, lower 4 bytes only */
+	u32 tweak_lower;		/* Encryption tweak, lower 4 bytes */
 	u8  cdb[16];			/* SCSI Command Descriptor Block */
 	u8  cciss_lun[8];		/* 8 byte SCSI address */
 	u32 data_len;			/* Total bytes to transfer */
@@ -514,10 +523,10 @@ struct io_accel2_cmd {
 #define IOACCEL2_PRIORITY_MASK 0x78
 #define IOACCEL2_ATTR_MASK 0x07
 	u8  sg_count;			/* Number of sg elements */
-	u8  reserved3[2];		/* Reserved */
+	u16 dekindex;			/* Data encryption key index */
 	u64 err_ptr;			/* Error Pointer */
 	u32 err_len;			/* Error Length*/
-	u8 reserved4[4];		/* Reserved */
+	u32 tweak_upper;		/* Encryption tweak, upper 4 bytes */
 	struct ioaccel2_sg_element sg[IOACCEL2_MAXSGENTRIES];
 	struct io_accel2_scsi_response error_data;
 	u8 pad[IOACCEL2_PAD];


  parent reply	other threads:[~2014-01-15 21:40 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-15 22:36 [PATCH 00/41] hpsa January 2014 driver updates Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 01/41] hpsa: revert bring logical drives online when format completes Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 02/41] hpsa: revert hide logical drives with format in progress from linux Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 03/41] hpsa: use workqueue instead of kernel thread for lockup detection Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 04/41] hpsa: rename scsi prefetch field Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 05/41] hpsa: enable unit attention reporting Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 06/41] hpsa: do not require board "not ready" status after hard reset Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 07/41] hpsa: allow SCSI mid layer to handle unit attention Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 08/41] hpsa: use extended report luns command for HP SSD SmartPath Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 09/41] hpsa: mark last scatter gather element as the last Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 10/41] hpsa: add support for 'fastpath' i/o Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 11/41] hpsa: only allow REQ_TYPE_FS to use fast path Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 12/41] hpsa: fix task management for mode-1 ioaccell path Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 13/41] hpsa: add ioaccell mode 1 RAID offload support Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 14/41] hpsa: update raid offload status on device rescan Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 15/41] hpsa: poll controller to detect device change event Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 16/41] hpsa: do not rescan controllers known to be locked up Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 17/41] hpsa: add hp_ssd_smart_path_enabled sysfs attribute Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 18/41] hpsa: complain if physical or logical aborts are not supported Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 19/41] hpsa: add ioaccel mode 2 structure definitions Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 20/41] hpsa: Acknowledge controller events in ioaccell mode 2 as well as mode 1 Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 21/41] hpsa: do ioaccel mode 2 resource allocations Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 22/41] hpsa: get physical device handles for io accel mode 2 as well as mode 1 Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 23/41] hpsa: initialize controller to perform io accelerator mode 2 Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 24/41] hpsa: get ioaccel mode 2 i/o working Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 25/41] hpsa: teach hpsa_device_reset to do either target or lun reset Stephen M. Cameron
2014-01-16  8:36   ` Hannes Reinecke
2014-01-16 13:33     ` Gates, Matt
2014-01-15 22:38 ` [PATCH 26/41] hpsa: add task management for ioaccel mode 2 Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 27/41] hpsa: make device update copy the raid map also Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 28/41] hpsa: complete the ioaccel raidmap code Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 29/41] hpsa: allow user to disable accelerated i/o path Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 30/41] hpsa: rescan devices on ioaccel2 error Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 31/41] hpsa: allow VPD page zero to be queried Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 32/41] hpsa: do not inquire for unsupported ioaccel status vpd page Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 33/41] hpsa: retry certain ioaccel error cases on the RAID path Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 34/41] hpsa: update source file copyrights Stephen M. Cameron
2014-01-15 22:39 ` Stephen M. Cameron [this message]
2014-01-15 22:39 ` [PATCH 36/41] hpsa: when switching out of accel mode await only accel command completions Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 37/41] hpsa: only do device rescan for certain events Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 38/41] hpsa: improve error messages for driver initiated commands Stephen M. Cameron
2014-01-16  8:42   ` Hannes Reinecke
2014-01-16 16:14     ` scameron
2014-01-15 22:39 ` [PATCH 39/41] hpsa add sysfs debug switch for raid map debugging messages Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 40/41] pci: add HP/3PAR vendor id to pci_ids.h Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 41/41] hpsa: Add support for a few HP Storage controllers Stephen M. Cameron

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=20140115223923.5061.34124.stgit@beardog.cce.hp.com \
    --to=scameron@beardog.cce.hp.com \
    --cc=jbottomley@parallels.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=matthew.gates@hp.com \
    --cc=mikem@beardog.cce.hp.com \
    --cc=scott.teel@hp.com \
    --cc=stephenmcameron@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox