lkml.org 
[lkml]   [2021]   [Jul]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH Part2 RFC v4 11/40] crypto:ccp: Define the SEV-SNP commands
    Date
    AMD introduced the next generation of SEV called SEV-SNP (Secure Nested
    Paging). SEV-SNP builds upon existing SEV and SEV-ES functionality
    while adding new hardware security protection.

    Define the commands and structures used to communicate with the AMD-SP
    when creating and managing the SEV-SNP guests. The SEV-SNP firmware spec
    is available at developer.amd.com/sev.

    Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
    ---
    drivers/crypto/ccp/sev-dev.c | 16 ++-
    include/linux/psp-sev.h | 222 +++++++++++++++++++++++++++++++++++
    include/uapi/linux/psp-sev.h | 43 +++++++
    3 files changed, 280 insertions(+), 1 deletion(-)

    diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
    index 3506b2050fb8..32884d2bf4e5 100644
    --- a/drivers/crypto/ccp/sev-dev.c
    +++ b/drivers/crypto/ccp/sev-dev.c
    @@ -130,7 +130,21 @@ static int sev_cmd_buffer_len(int cmd)
    case SEV_CMD_DOWNLOAD_FIRMWARE: return sizeof(struct sev_data_download_firmware);
    case SEV_CMD_GET_ID: return sizeof(struct sev_data_get_id);
    case SEV_CMD_ATTESTATION_REPORT: return sizeof(struct sev_data_attestation_report);
    - case SEV_CMD_SEND_CANCEL: return sizeof(struct sev_data_send_cancel);
    + case SEV_CMD_SEND_CANCEL: return sizeof(struct sev_data_send_cancel);
    + case SEV_CMD_SNP_GCTX_CREATE: return sizeof(struct sev_data_snp_gctx_create);
    + case SEV_CMD_SNP_LAUNCH_START: return sizeof(struct sev_data_snp_launch_start);
    + case SEV_CMD_SNP_LAUNCH_UPDATE: return sizeof(struct sev_data_snp_launch_update);
    + case SEV_CMD_SNP_ACTIVATE: return sizeof(struct sev_data_snp_activate);
    + case SEV_CMD_SNP_DECOMMISSION: return sizeof(struct sev_data_snp_decommission);
    + case SEV_CMD_SNP_PAGE_RECLAIM: return sizeof(struct sev_data_snp_page_reclaim);
    + case SEV_CMD_SNP_GUEST_STATUS: return sizeof(struct sev_data_snp_guest_status);
    + case SEV_CMD_SNP_LAUNCH_FINISH: return sizeof(struct sev_data_snp_launch_finish);
    + case SEV_CMD_SNP_DBG_DECRYPT: return sizeof(struct sev_data_snp_dbg);
    + case SEV_CMD_SNP_DBG_ENCRYPT: return sizeof(struct sev_data_snp_dbg);
    + case SEV_CMD_SNP_PAGE_UNSMASH: return sizeof(struct sev_data_snp_page_unsmash);
    + case SEV_CMD_SNP_PLATFORM_STATUS: return sizeof(struct sev_data_snp_platform_status_buf);
    + case SEV_CMD_SNP_GUEST_REQUEST: return sizeof(struct sev_data_snp_guest_request);
    + case SEV_CMD_SNP_CONFIG: return sizeof(struct sev_user_data_snp_config);
    default: return 0;
    }

    diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
    index d48a7192e881..c3755099ab55 100644
    --- a/include/linux/psp-sev.h
    +++ b/include/linux/psp-sev.h
    @@ -85,6 +85,34 @@ enum sev_cmd {
    SEV_CMD_DBG_DECRYPT = 0x060,
    SEV_CMD_DBG_ENCRYPT = 0x061,

    + /* SNP specific commands */
    + SEV_CMD_SNP_INIT = 0x81,
    + SEV_CMD_SNP_SHUTDOWN = 0x82,
    + SEV_CMD_SNP_PLATFORM_STATUS = 0x83,
    + SEV_CMD_SNP_DF_FLUSH = 0x84,
    + SEV_CMD_SNP_INIT_EX = 0x85,
    + SEV_CMD_SNP_DECOMMISSION = 0x90,
    + SEV_CMD_SNP_ACTIVATE = 0x91,
    + SEV_CMD_SNP_GUEST_STATUS = 0x92,
    + SEV_CMD_SNP_GCTX_CREATE = 0x93,
    + SEV_CMD_SNP_GUEST_REQUEST = 0x94,
    + SEV_CMD_SNP_ACTIVATE_EX = 0x95,
    + SEV_CMD_SNP_LAUNCH_START = 0xA0,
    + SEV_CMD_SNP_LAUNCH_UPDATE = 0xA1,
    + SEV_CMD_SNP_LAUNCH_FINISH = 0xA2,
    + SEV_CMD_SNP_DBG_DECRYPT = 0xB0,
    + SEV_CMD_SNP_DBG_ENCRYPT = 0xB1,
    + SEV_CMD_SNP_PAGE_SWAP_OUT = 0xC0,
    + SEV_CMD_SNP_PAGE_SWAP_IN = 0xC1,
    + SEV_CMD_SNP_PAGE_MOVE = 0xC2,
    + SEV_CMD_SNP_PAGE_MD_INIT = 0xC3,
    + SEV_CMD_SNP_PAGE_MD_RECLAIM = 0xC4,
    + SEV_CMD_SNP_PAGE_RO_RECLAIM = 0xC5,
    + SEV_CMD_SNP_PAGE_RO_RESTORE = 0xC6,
    + SEV_CMD_SNP_PAGE_RECLAIM = 0xC7,
    + SEV_CMD_SNP_PAGE_UNSMASH = 0xC8,
    + SEV_CMD_SNP_CONFIG = 0xC9,
    +
    SEV_CMD_MAX,
    };

    @@ -510,6 +538,200 @@ struct sev_data_attestation_report {
    u32 len; /* In/Out */
    } __packed;

    +/**
    + * struct sev_data_snp_platform_status_buf - SNP_PLATFORM_STATUS command params
    + *
    + * @address: physical address where the status should be copied
    + */
    +struct sev_data_snp_platform_status_buf {
    + u64 status_paddr; /* In */
    +} __packed;
    +
    +/**
    + * struct sev_data_snp_download_firmware - SNP_DOWNLOAD_FIRMWARE command params
    + *
    + * @address: physical address of firmware image
    + * @len: len of the firmware image
    + */
    +struct sev_data_snp_download_firmware {
    + u64 address; /* In */
    + u32 len; /* In */
    +} __packed;
    +
    +/**
    + * struct sev_data_snp_gctx_create - SNP_GCTX_CREATE command params
    + *
    + * @gctx_paddr: system physical address of the page donated to firmware by
    + * the hypervisor to contain the guest context.
    + */
    +struct sev_data_snp_gctx_create {
    + u64 gctx_paddr; /* In */
    +} __packed;
    +
    +/**
    + * struct sev_data_snp_activate - SNP_ACTIVATE command params
    + *
    + * @gctx_paddr: system physical address guest context page
    + * @asid: ASID to bind to the guest
    + */
    +struct sev_data_snp_activate {
    + u64 gctx_paddr; /* In */
    + u32 asid; /* In */
    +} __packed;
    +
    +/**
    + * struct sev_data_snp_decommission - SNP_DECOMMISSION command params
    + *
    + * @address: system physical address guest context page
    + */
    +struct sev_data_snp_decommission {
    + u64 gctx_paddr; /* In */
    +} __packed;
    +
    +/**
    + * struct sev_data_snp_launch_start - SNP_LAUNCH_START command params
    + *
    + * @gctx_addr: system physical address of guest context page
    + * @policy: guest policy
    + * @ma_gctx_addr: system physical address of migration agent
    + * @imi_en: launch flow is launching an IMI for the purpose of
    + * guest-assisted migration.
    + * @ma_en: the guest is associated with a migration agent
    + */
    +struct sev_data_snp_launch_start {
    + u64 gctx_paddr; /* In */
    + u64 policy; /* In */
    + u64 ma_gctx_paddr; /* In */
    + u32 ma_en:1; /* In */
    + u32 imi_en:1; /* In */
    + u32 rsvd:30;
    + u8 gosvw[16]; /* In */
    +} __packed;
    +
    +/* SNP support page type */
    +enum {
    + SNP_PAGE_TYPE_NORMAL = 0x1,
    + SNP_PAGE_TYPE_VMSA = 0x2,
    + SNP_PAGE_TYPE_ZERO = 0x3,
    + SNP_PAGE_TYPE_UNMEASURED = 0x4,
    + SNP_PAGE_TYPE_SECRET = 0x5,
    + SNP_PAGE_TYPE_CPUID = 0x6,
    +
    + SNP_PAGE_TYPE_MAX
    +};
    +
    +/**
    + * struct sev_data_snp_launch_update - SNP_LAUNCH_UPDATE command params
    + *
    + * @gctx_addr: system physical address of guest context page
    + * @imi_page: indicates that this page is part of the IMI of the guest
    + * @page_type: encoded page type
    + * @page_size: page size 0 indicates 4K and 1 indicates 2MB page
    + * @address: system physical address of destination page to encrypt
    + * @vmpl3_perms: VMPL permission mask for VMPL3
    + * @vmpl2_perms: VMPL permission mask for VMPL2
    + * @vmpl1_perms: VMPL permission mask for VMPL1
    + */
    +struct sev_data_snp_launch_update {
    + u64 gctx_paddr; /* In */
    + u32 page_size:1; /* In */
    + u32 page_type:3; /* In */
    + u32 imi_page:1; /* In */
    + u32 rsvd:27;
    + u32 rsvd2;
    + u64 address; /* In */
    + u32 rsvd3:8;
    + u32 vmpl3_perms:8; /* In */
    + u32 vmpl2_perms:8; /* In */
    + u32 vmpl1_perms:8; /* In */
    + u32 rsvd4;
    +} __packed;
    +
    +/**
    + * struct sev_data_snp_launch_finish - SNP_LAUNCH_FINISH command params
    + *
    + * @gctx_addr: system pphysical address of guest context page
    + */
    +struct sev_data_snp_launch_finish {
    + u64 gctx_paddr;
    + u64 id_block_paddr;
    + u64 id_auth_paddr;
    + u8 id_block_en:1;
    + u8 auth_key_en:1;
    + u64 rsvd:62;
    + u8 host_data[32];
    +} __packed;
    +
    +/**
    + * struct sev_data_snp_guest_status - SNP_GUEST_STATUS command params
    + *
    + * @gctx_paddr: system physical address of guest context page
    + * @address: system physical address of guest status page
    + */
    +struct sev_data_snp_guest_status {
    + u64 gctx_paddr;
    + u64 address;
    +} __packed;
    +
    +/**
    + * struct sev_data_snp_page_reclaim - SNP_PAGE_RECLAIM command params
    + *
    + * @paddr: system physical address of page to be claimed. The BIT0 indicate
    + * the page size. 0h indicates 4 kB and 1h indicates 2 MB page.
    + */
    +struct sev_data_snp_page_reclaim {
    + u64 paddr;
    +} __packed;
    +
    +/**
    + * struct sev_data_snp_page_unsmash - SNP_PAGE_UNMASH command params
    + *
    + * @paddr: system physical address of page to be unmashed. The BIT0 indicate
    + * the page size. 0h indicates 4 kB and 1h indicates 2 MB page.
    + */
    +struct sev_data_snp_page_unsmash {
    + u64 paddr;
    +} __packed;
    +
    +/**
    + * struct sev_data_dbg - DBG_ENCRYPT/DBG_DECRYPT command parameters
    + *
    + * @handle: handle of the VM to perform debug operation
    + * @src_addr: source address of data to operate on
    + * @dst_addr: destination address of data to operate on
    + * @len: len of data to operate on
    + */
    +struct sev_data_snp_dbg {
    + u64 gctx_paddr; /* In */
    + u64 src_addr; /* In */
    + u64 dst_addr; /* In */
    + u32 len; /* In */
    +} __packed;
    +
    +/**
    + * struct sev_snp_guest_request - SNP_GUEST_REQUEST command params
    + *
    + * @gctx_paddr: system physical address of guest context page
    + * @req_paddr: system physical address of request page
    + * @res_paddr: system physical address of response page
    + */
    +struct sev_data_snp_guest_request {
    + u64 gctx_paddr; /* In */
    + u64 req_paddr; /* In */
    + u64 res_paddr; /* In */
    +} __packed;
    +
    +/**
    + * struuct sev_data_snp_init - SNP_INIT_EX structure
    + *
    + * @init_rmp: indicate that the RMP should be initialized.
    + */
    +struct sev_data_snp_init_ex {
    + u32 init_rmp:1;
    + u32 rsvd:31;
    + u8 rsvd1[60];
    +} __packed;
    +
    #ifdef CONFIG_CRYPTO_DEV_SP_PSP

    /**
    diff --git a/include/uapi/linux/psp-sev.h b/include/uapi/linux/psp-sev.h
    index 91b4c63d5cbf..226de6330a18 100644
    --- a/include/uapi/linux/psp-sev.h
    +++ b/include/uapi/linux/psp-sev.h
    @@ -61,6 +61,13 @@ typedef enum {
    SEV_RET_INVALID_PARAM,
    SEV_RET_RESOURCE_LIMIT,
    SEV_RET_SECURE_DATA_INVALID,
    + SEV_RET_INVALID_PAGE_SIZE,
    + SEV_RET_INVALID_PAGE_STATE,
    + SEV_RET_INVALID_MDATA_ENTRY,
    + SEV_RET_INVALID_PAGE_OWNER,
    + SEV_RET_INVALID_PAGE_AEAD_OFLOW,
    + SEV_RET_RMP_INIT_REQUIRED,
    +
    SEV_RET_MAX,
    } sev_ret_code;

    @@ -147,6 +154,42 @@ struct sev_user_data_get_id2 {
    __u32 length; /* In/Out */
    } __packed;

    +/**
    + * struct sev_user_data_snp_status - SNP status
    + *
    + * @major: API major version
    + * @minor: API minor version
    + * @state: current platform state
    + * @build: firmware build id for the API version
    + * @guest_count: the number of guest currently managed by the firmware
    + * @tcb_version: current TCB version
    + */
    +struct sev_user_data_snp_status {
    + __u8 api_major; /* Out */
    + __u8 api_minor; /* Out */
    + __u8 state; /* Out */
    + __u8 rsvd;
    + __u32 build_id; /* Out */
    + __u32 rsvd1;
    + __u32 guest_count; /* Out */
    + __u64 tcb_version; /* Out */
    + __u64 rsvd2;
    +} __packed;
    +
    +/*
    + * struct sev_user_data_snp_config - system wide configuration value for SNP.
    + *
    + * @reported_tcb: The TCB version to report in the guest attestation report.
    + * @mask_chip_id: Indicates that the CHID_ID field in the attestation report
    + * will always be zero.
    + */
    +struct sev_user_data_snp_config {
    + __u64 reported_tcb; /* In */
    + __u32 mask_chip_id; /* In */
    + __u8 rsvd[52];
    +} __packed;
    +
    +
    /**
    * struct sev_issue_cmd - SEV ioctl parameters
    *
    --
    2.17.1
    \
     
     \ /
      Last update: 2021-07-07 20:39    [W:4.218 / U:0.092 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site