/** * struct rtas_phy_attest_params - Parameters (in and out) for * ibm,physical-attestation. * * @cmd: In: Caller-provided attestation command buffer. Must be * RTAS-addressable. * @work_area: In: Caller-provided work area buffer for attestation * command structure * Out: Caller-provided work area buffer for the response * @cmd_len: In: Caller-provided attestation command structure * length * @sequence: In: Sequence number. Out: Next sequence number. * @written: Out: Bytes written by ibm,physical-attestation to * @work_area. * @status: Out: RTAS call status.
*/ struct rtas_phy_attest_params { struct papr_phy_attest_io_block cmd; struct rtas_work_area *work_area;
u32 cmd_len;
u32 sequence;
u32 written;
s32 status;
};
/** * rtas_physical_attestation() - Call ibm,physical-attestation to * fill a work area buffer. * @params: See &struct rtas_phy_attest_params. * * Calls ibm,physical-attestation until it errors or successfully * deposits data into the supplied work area. Handles RTAS retry * statuses. Maps RTAS error statuses to reasonable errno values. * * The caller is expected to invoke rtas_physical_attestation() * multiple times to retrieve all the data for the provided * attestation command. Only one sequence should be in progress at * any time; starting a new sequence will disrupt any sequence * already in progress. Serialization of attestation retrieval * sequences is the responsibility of the caller. * * The caller should inspect @params.status to determine whether more * calls are needed to complete the sequence. * * Context: May sleep. * Return: -ve on error, 0 otherwise.
*/ staticint rtas_physical_attestation(struct rtas_phy_attest_params *params)
{ struct rtas_work_area *work_area;
s32 fwrc, token;
u32 rets[2]; int ret;
do {
fwrc = rtas_call(token, 3, 3, rets,
rtas_work_area_phys(work_area),
params->cmd_len,
params->sequence);
} while (rtas_busy_delay(fwrc));
switch (fwrc) { case RTAS_HARDWARE_ERROR:
ret = -EIO; break; case RTAS_INVALID_PARAMETER:
ret = -EINVAL; break; case RTAS_SEQ_MORE_DATA:
params->sequence = rets[0];
fallthrough; case RTAS_SEQ_COMPLETE:
params->written = rets[1]; /* * Kernel or firmware bug, do not continue.
*/ if (WARN(params->written > rtas_work_area_size(work_area), "possible write beyond end of work area"))
ret = -EFAULT; else
ret = 0; break; default:
ret = -EIO;
pr_err_ratelimited("unexpected ibm,get-phy_attest status %d\n", fwrc); break;
}
params->status = fwrc; return ret;
}
/* * Internal physical-attestation sequence APIs. A physical-attestation * sequence is a series of calls to get ibm,physical-attestation * for a given attestation command. The sequence ends when an error * is encountered or all data for the attestation command has been * returned.
*/
/** * phy_attest_sequence_begin() - Begin a response data for attestation * command retrieval sequence. * @seq: user specified parameters for RTAS call from seq struct. * * Context: May sleep.
*/ staticvoid phy_attest_sequence_begin(struct papr_rtas_sequence *seq)
{ struct rtas_phy_attest_params *param;
/* * We could allocate the work area before acquiring the * function lock, but that would allow concurrent requests to * exhaust the limited work area pool for no benefit. So * allocate the work area under the lock.
*/
mutex_lock(&rtas_ibm_physical_attestation_lock);
param = (struct rtas_phy_attest_params *)seq->params;
param->work_area = rtas_work_area_alloc(SZ_4K);
memcpy(rtas_work_area_raw_buf(param->work_area), ¶m->cmd,
param->cmd_len);
param->sequence = 1;
param->status = 0;
}
/** * papr_phy_attest_create_handle() - Create a fd-based handle for * reading the response for the given attestation command. * @ulc: Attestation command in user memory; defines the scope of * data for the attestation command to retrieve. * * Handler for PAPR_PHYSICAL_ATTESTATION_IOC_CREATE_HANDLE ioctl * command. Validates @ulc and instantiates an immutable response * "blob" for attestation command. The blob is attached to a file * descriptor for reading by user space. The memory backing the blob * is freed when the file is released. * * The entire requested response buffer for the attestation command * retrieved by this call and all necessary RTAS interactions are * performed before returning the fd to user space. This keeps the * read handler simple and ensures that kernel can prevent * interleaving ibm,physical-attestation call sequences. * * Return: The installed fd number if successful, -ve errno otherwise.
*/ staticlong papr_phy_attest_create_handle(struct papr_phy_attest_io_block __user *ulc)
{ struct rtas_phy_attest_params *params; struct papr_rtas_sequence seq = {}; int fd;
/* * Freed in phy_attest_sequence_end().
*/
params = kzalloc(sizeof(*params), GFP_KERNEL_ACCOUNT); if (!params) return -ENOMEM;
if (copy_from_user(¶ms->cmd, ulc, sizeof(struct papr_phy_attest_io_block))) return -EFAULT;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.