Path: blob/master/arch/powerpc/platforms/pseries/papr-hvpipe.c
29274 views
// SPDX-License-Identifier: GPL-2.0-only12#define pr_fmt(fmt) "papr-hvpipe: " fmt34#include <linux/module.h>5#include <linux/kernel.h>6#include <linux/types.h>7#include <linux/delay.h>8#include <linux/anon_inodes.h>9#include <linux/miscdevice.h>10#include <linux/file.h>11#include <linux/fs.h>12#include <linux/poll.h>13#include <linux/of.h>14#include <asm/machdep.h>15#include <asm/rtas.h>16#include <asm/rtas-work-area.h>17#include <asm/papr-sysparm.h>18#include <uapi/asm/papr-hvpipe.h>19#include "pseries.h"20#include "papr-hvpipe.h"2122static DEFINE_SPINLOCK(hvpipe_src_list_lock);23static LIST_HEAD(hvpipe_src_list);2425static unsigned char hvpipe_ras_buf[RTAS_ERROR_LOG_MAX];26static struct workqueue_struct *papr_hvpipe_wq;27static struct work_struct *papr_hvpipe_work;28static int hvpipe_check_exception_token;29static bool hvpipe_feature;3031/*32* New PowerPC FW provides support for partitions and various33* sources (Ex: remote hardware management console (HMC)) to34* exchange information through an inband hypervisor channel35* called HVPIPE. Only HMCs are supported right now and36* partitions can communicate with multiple HMCs and each37* source represented by source ID.38*39* FW introduces send HVPIPE and recv HVPIPE RTAS calls for40* partitions to send and receive payloads respectively.41*42* These RTAS functions have the following certain requirements43* / limitations:44* - One hvpipe per partition for all sources.45* - Assume the return status of send HVPIPE as delivered to source46* - Assume the return status of recv HVPIPE as ACK to source47* - Generates HVPIPE event message when the payload is ready48* for the partition. The hypervisor will not deliver another49* event until the partition read the previous payload which50* means the pipe is blocked for any sources.51*52* Linux implementation:53* Follow the similar interfaces that the OS has for other RTAS calls.54* ex: /dev/papr-indices, /dev/papr-vpd, etc.55* - /dev/papr-hvpipe is available for the user space.56* - devfd = open("/dev/papr-hvpipe", ..)57* - fd = ioctl(fd,HVPIPE_IOC_CREATE_HANDLE,&srcID)-for each source58* - write(fd, buf, size) --> Issue send HVPIPE RTAS call and59* returns size for success or the corresponding error for RTAS60* return code for failure.61* - poll(fd,..) -> wakeup FD if the payload is available to read.62* HVPIPE event message handler wakeup FD based on source ID in63* the event message64* - read(fd, buf, size) --> Issue recv HVPIPE RTAS call and65* returns size for success or the corresponding error for RTAS66* return code for failure.67*/6869/*70* ibm,receive-hvpipe-msg RTAS call.71* @area: Caller-provided work area buffer for results.72* @srcID: Source ID returned by the RTAS call.73* @bytesw: Bytes written by RTAS call to @area.74*/75static int rtas_ibm_receive_hvpipe_msg(struct rtas_work_area *area,76u32 *srcID, u32 *bytesw)77{78const s32 token = rtas_function_token(RTAS_FN_IBM_RECEIVE_HVPIPE_MSG);79u32 rets[2];80s32 fwrc;81int ret;8283if (token == RTAS_UNKNOWN_SERVICE)84return -ENOENT;8586do {87fwrc = rtas_call(token, 2, 3, rets,88rtas_work_area_phys(area),89rtas_work_area_size(area));9091} while (rtas_busy_delay(fwrc));9293switch (fwrc) {94case RTAS_SUCCESS:95*srcID = rets[0];96*bytesw = rets[1];97ret = 0;98break;99case RTAS_HARDWARE_ERROR:100ret = -EIO;101break;102case RTAS_INVALID_PARAMETER:103ret = -EINVAL;104break;105case RTAS_FUNC_NOT_SUPPORTED:106ret = -EOPNOTSUPP;107break;108default:109ret = -EIO;110pr_err_ratelimited("unexpected ibm,receive-hvpipe-msg status %d\n", fwrc);111break;112}113114return ret;115}116117/*118* ibm,send-hvpipe-msg RTAS call119* @area: Caller-provided work area buffer to send.120* @srcID: Target source for the send pipe message.121*/122static int rtas_ibm_send_hvpipe_msg(struct rtas_work_area *area, u32 srcID)123{124const s32 token = rtas_function_token(RTAS_FN_IBM_SEND_HVPIPE_MSG);125s32 fwrc;126int ret;127128if (token == RTAS_UNKNOWN_SERVICE)129return -ENOENT;130131do {132fwrc = rtas_call(token, 2, 1, NULL, srcID,133rtas_work_area_phys(area));134135} while (rtas_busy_delay(fwrc));136137switch (fwrc) {138case RTAS_SUCCESS:139ret = 0;140break;141case RTAS_HARDWARE_ERROR:142ret = -EIO;143break;144case RTAS_INVALID_PARAMETER:145ret = -EINVAL;146break;147case RTAS_HVPIPE_CLOSED:148ret = -EPIPE;149break;150case RTAS_FUNC_NOT_SUPPORTED:151ret = -EOPNOTSUPP;152break;153default:154ret = -EIO;155pr_err_ratelimited("unexpected ibm,receive-hvpipe-msg status %d\n", fwrc);156break;157}158159return ret;160}161162static struct hvpipe_source_info *hvpipe_find_source(u32 srcID)163{164struct hvpipe_source_info *src_info;165166list_for_each_entry(src_info, &hvpipe_src_list, list)167if (src_info->srcID == srcID)168return src_info;169170return NULL;171}172173/*174* This work function collects receive buffer with recv HVPIPE175* RTAS call. Called from read()176* @buf: User specified buffer to copy the payload that returned177* from recv HVPIPE RTAS.178* @size: Size of buffer user passed.179*/180static int hvpipe_rtas_recv_msg(char __user *buf, int size)181{182struct rtas_work_area *work_area;183u32 srcID, bytes_written;184int ret;185186work_area = rtas_work_area_alloc(SZ_4K);187if (!work_area) {188pr_err("Could not allocate RTAS buffer for recv pipe\n");189return -ENOMEM;190}191192ret = rtas_ibm_receive_hvpipe_msg(work_area, &srcID,193&bytes_written);194if (!ret) {195/*196* Recv HVPIPE RTAS is successful.197* When releasing FD or no one is waiting on the198* specific source, issue recv HVPIPE RTAS call199* so that pipe is not blocked - this func is called200* with NULL buf.201*/202if (buf) {203if (size < bytes_written) {204pr_err("Received the payload size = %d, but the buffer size = %d\n",205bytes_written, size);206bytes_written = size;207}208ret = copy_to_user(buf,209rtas_work_area_raw_buf(work_area),210bytes_written);211if (!ret)212ret = bytes_written;213}214} else {215pr_err("ibm,receive-hvpipe-msg failed with %d\n",216ret);217}218219rtas_work_area_free(work_area);220return ret;221}222223/*224* papr_hvpipe_handle_write - Issue send HVPIPE RTAS and return225* the size (payload + HVPIPE_HDR_LEN) for RTAS success.226* Otherwise returns the status of RTAS to the user space227*/228static ssize_t papr_hvpipe_handle_write(struct file *file,229const char __user *buf, size_t size, loff_t *off)230{231struct hvpipe_source_info *src_info = file->private_data;232struct rtas_work_area *work_area, *work_buf;233unsigned long ret, len;234__be64 *area_be;235236/*237* Return -ENXIO during migration238*/239if (!hvpipe_feature)240return -ENXIO;241242if (!src_info)243return -EIO;244245/*246* Send HVPIPE RTAS is used to send payload to the specific247* source with the input parameters source ID and the payload248* as buffer list. Each entry in the buffer list contains249* address/length pair of the buffer.250*251* The buffer list format is as follows:252*253* Header (length of address/length pairs and the header length)254* Address of 4K buffer 1255* Length of 4K buffer 1 used256* ...257* Address of 4K buffer n258* Length of 4K buffer n used259*260* See PAPR 7.3.32.2 ibm,send-hvpipe-msg261*262* Even though can support max 1MB payload, the hypervisor263* supports only 4048 bytes payload at present and also264* just one address/length entry.265*266* writev() interface can be added in future when the267* hypervisor supports multiple buffer list entries.268*/269/* HVPIPE_MAX_WRITE_BUFFER_SIZE = 4048 bytes */270if ((size > (HVPIPE_HDR_LEN + HVPIPE_MAX_WRITE_BUFFER_SIZE)) ||271(size <= HVPIPE_HDR_LEN))272return -EINVAL;273274/*275* The length of (address + length) pair + the length of header276*/277len = (2 * sizeof(u64)) + sizeof(u64);278size -= HVPIPE_HDR_LEN;279buf += HVPIPE_HDR_LEN;280mutex_lock(&rtas_ibm_send_hvpipe_msg_lock);281work_area = rtas_work_area_alloc(SZ_4K);282if (!work_area) {283ret = -ENOMEM;284goto out;285}286area_be = (__be64 *)rtas_work_area_raw_buf(work_area);287/* header */288area_be[0] = cpu_to_be64(len);289290work_buf = rtas_work_area_alloc(SZ_4K);291if (!work_buf) {292ret = -ENOMEM;293goto out_work;294}295/* First buffer address */296area_be[1] = cpu_to_be64(rtas_work_area_phys(work_buf));297/* First buffer address length */298area_be[2] = cpu_to_be64(size);299300if (!copy_from_user(rtas_work_area_raw_buf(work_buf), buf, size)) {301ret = rtas_ibm_send_hvpipe_msg(work_area, src_info->srcID);302if (!ret)303ret = size + HVPIPE_HDR_LEN;304} else305ret = -EPERM;306307rtas_work_area_free(work_buf);308out_work:309rtas_work_area_free(work_area);310out:311mutex_unlock(&rtas_ibm_send_hvpipe_msg_lock);312return ret;313}314315/*316* papr_hvpipe_handle_read - If the payload for the specific317* source is pending in the hypervisor, issue recv HVPIPE RTAS318* and return the payload to the user space.319*320* When the payload is available for the partition, the321* hypervisor notifies HVPIPE event with the source ID322* and the event handler wakeup FD(s) that are waiting.323*/324static ssize_t papr_hvpipe_handle_read(struct file *file,325char __user *buf, size_t size, loff_t *off)326{327328struct hvpipe_source_info *src_info = file->private_data;329struct papr_hvpipe_hdr hdr;330long ret;331332/*333* Return -ENXIO during migration334*/335if (!hvpipe_feature)336return -ENXIO;337338if (!src_info)339return -EIO;340341/*342* Max payload is 4048 (HVPIPE_MAX_WRITE_BUFFER_SIZE)343*/344if ((size > (HVPIPE_HDR_LEN + HVPIPE_MAX_WRITE_BUFFER_SIZE)) ||345(size < HVPIPE_HDR_LEN))346return -EINVAL;347348/*349* Payload is not available to receive or source pipe350* is not closed.351*/352if (!src_info->hvpipe_status)353return 0;354355hdr.version = 0;356hdr.flags = 0;357358/*359* In case if the hvpipe has payload and also the360* hypervisor closed the pipe to the source, retrieve361* the payload and return to the user space first and362* then notify the userspace about the hvpipe close in363* next read().364*/365if (src_info->hvpipe_status & HVPIPE_MSG_AVAILABLE)366hdr.flags = HVPIPE_MSG_AVAILABLE;367else if (src_info->hvpipe_status & HVPIPE_LOST_CONNECTION)368hdr.flags = HVPIPE_LOST_CONNECTION;369else370/*371* Should not be here without one of the above372* flags set373*/374return -EIO;375376ret = copy_to_user(buf, &hdr, HVPIPE_HDR_LEN);377if (ret)378return ret;379380/*381* Message event has payload, so get the payload with382* recv HVPIPE RTAS.383*/384if (hdr.flags & HVPIPE_MSG_AVAILABLE) {385ret = hvpipe_rtas_recv_msg(buf + HVPIPE_HDR_LEN,386size - HVPIPE_HDR_LEN);387if (ret > 0) {388src_info->hvpipe_status &= ~HVPIPE_MSG_AVAILABLE;389ret += HVPIPE_HDR_LEN;390}391} else if (hdr.flags & HVPIPE_LOST_CONNECTION) {392/*393* Hypervisor is closing the pipe for the specific394* source. So notify user space.395*/396src_info->hvpipe_status &= ~HVPIPE_LOST_CONNECTION;397ret = HVPIPE_HDR_LEN;398}399400return ret;401}402403/*404* The user space waits for the payload to receive.405* The hypervisor sends HVPIPE event message to the partition406* when the payload is available. The event handler wakeup FD407* depends on the source ID in the message event.408*/409static __poll_t papr_hvpipe_handle_poll(struct file *filp,410struct poll_table_struct *wait)411{412struct hvpipe_source_info *src_info = filp->private_data;413414/*415* HVPIPE is disabled during SUSPEND and enabled after migration.416* So return POLLRDHUP during migration417*/418if (!hvpipe_feature)419return POLLRDHUP;420421if (!src_info)422return POLLNVAL;423424/*425* If hvpipe already has pending payload, return so that426* the user space can issue read().427*/428if (src_info->hvpipe_status)429return POLLIN | POLLRDNORM;430431/*432* Wait for the message event433* hvpipe_event_interrupt() wakes up this wait_queue434*/435poll_wait(filp, &src_info->recv_wqh, wait);436if (src_info->hvpipe_status)437return POLLIN | POLLRDNORM;438439return 0;440}441442static int papr_hvpipe_handle_release(struct inode *inode,443struct file *file)444{445struct hvpipe_source_info *src_info;446447/*448* Hold the lock, remove source from src_list, reset the449* hvpipe status and release the lock to prevent any race450* with message event IRQ.451*/452spin_lock(&hvpipe_src_list_lock);453src_info = file->private_data;454list_del(&src_info->list);455file->private_data = NULL;456/*457* If the pipe for this specific source has any pending458* payload, issue recv HVPIPE RTAS so that pipe will not459* be blocked.460*/461if (src_info->hvpipe_status & HVPIPE_MSG_AVAILABLE) {462src_info->hvpipe_status = 0;463spin_unlock(&hvpipe_src_list_lock);464hvpipe_rtas_recv_msg(NULL, 0);465} else466spin_unlock(&hvpipe_src_list_lock);467468kfree(src_info);469return 0;470}471472static const struct file_operations papr_hvpipe_handle_ops = {473.read = papr_hvpipe_handle_read,474.write = papr_hvpipe_handle_write,475.release = papr_hvpipe_handle_release,476.poll = papr_hvpipe_handle_poll,477};478479static int papr_hvpipe_dev_create_handle(u32 srcID)480{481struct hvpipe_source_info *src_info;482struct file *file;483long err;484int fd;485486spin_lock(&hvpipe_src_list_lock);487/*488* Do not allow more than one process communicates with489* each source.490*/491src_info = hvpipe_find_source(srcID);492if (src_info) {493spin_unlock(&hvpipe_src_list_lock);494pr_err("pid(%d) is already using the source(%d)\n",495src_info->tsk->pid, srcID);496return -EALREADY;497}498spin_unlock(&hvpipe_src_list_lock);499500src_info = kzalloc(sizeof(*src_info), GFP_KERNEL_ACCOUNT);501if (!src_info)502return -ENOMEM;503504src_info->srcID = srcID;505src_info->tsk = current;506init_waitqueue_head(&src_info->recv_wqh);507508fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);509if (fd < 0) {510err = fd;511goto free_buf;512}513514file = anon_inode_getfile("[papr-hvpipe]",515&papr_hvpipe_handle_ops, (void *)src_info,516O_RDWR);517if (IS_ERR(file)) {518err = PTR_ERR(file);519goto free_fd;520}521522spin_lock(&hvpipe_src_list_lock);523/*524* If two processes are executing ioctl() for the same525* source ID concurrently, prevent the second process to526* acquire FD.527*/528if (hvpipe_find_source(srcID)) {529spin_unlock(&hvpipe_src_list_lock);530err = -EALREADY;531goto free_file;532}533list_add(&src_info->list, &hvpipe_src_list);534spin_unlock(&hvpipe_src_list_lock);535536fd_install(fd, file);537return fd;538539free_file:540fput(file);541free_fd:542put_unused_fd(fd);543free_buf:544kfree(src_info);545return err;546}547548/*549* Top-level ioctl handler for /dev/papr_hvpipe550*551* Use separate FD for each source (exa :HMC). So ioctl is called552* with source ID which returns FD.553*/554static long papr_hvpipe_dev_ioctl(struct file *filp, unsigned int ioctl,555unsigned long arg)556{557u32 __user *argp = (void __user *)arg;558u32 srcID;559long ret;560561/*562* Return -ENXIO during migration563*/564if (!hvpipe_feature)565return -ENXIO;566567if (get_user(srcID, argp))568return -EFAULT;569570/*571* Support only HMC source right now572*/573if (!(srcID & HVPIPE_HMC_ID_MASK))574return -EINVAL;575576switch (ioctl) {577case PAPR_HVPIPE_IOC_CREATE_HANDLE:578ret = papr_hvpipe_dev_create_handle(srcID);579break;580default:581ret = -ENOIOCTLCMD;582break;583}584585return ret;586}587588/*589* papr_hvpipe_work_fn - called to issue recv HVPIPE RTAS for590* sources that are not monitored by user space so that pipe591* will not be blocked.592*/593static void papr_hvpipe_work_fn(struct work_struct *work)594{595hvpipe_rtas_recv_msg(NULL, 0);596}597598/*599* HVPIPE event message IRQ handler.600* The hypervisor sends event IRQ if the partition has payload601* and generates another event only after payload is read with602* recv HVPIPE RTAS.603*/604static irqreturn_t hvpipe_event_interrupt(int irq, void *dev_id)605{606struct hvpipe_event_buf *hvpipe_event;607struct pseries_errorlog *pseries_log;608struct hvpipe_source_info *src_info;609struct rtas_error_log *elog;610int rc;611612rc = rtas_call(hvpipe_check_exception_token, 6, 1, NULL,613RTAS_VECTOR_EXTERNAL_INTERRUPT, virq_to_hw(irq),614RTAS_HVPIPE_MSG_EVENTS, 1, __pa(&hvpipe_ras_buf),615rtas_get_error_log_max());616617if (rc != 0) {618pr_err_ratelimited("unexpected hvpipe-event-notification failed %d\n", rc);619return IRQ_HANDLED;620}621622elog = (struct rtas_error_log *)hvpipe_ras_buf;623if (unlikely(rtas_error_type(elog) != RTAS_TYPE_HVPIPE)) {624pr_warn_ratelimited("Unexpected event type %d\n",625rtas_error_type(elog));626return IRQ_HANDLED;627}628629pseries_log = get_pseries_errorlog(elog,630PSERIES_ELOG_SECT_ID_HVPIPE_EVENT);631hvpipe_event = (struct hvpipe_event_buf *)pseries_log->data;632633/*634* The hypervisor notifies partition when the payload is635* available to read with recv HVPIPE RTAS and it will not636* notify another event for any source until the previous637* payload is read. Means the pipe is blocked in the638* hypervisor until the payload is read.639*640* If the source is ready to accept payload and wakeup the641* corresponding FD. Hold lock and update hvpipe_status642* and this lock is needed in case the user space process643* is in release FD instead of poll() so that release()644* reads the payload to unblock pipe before closing FD.645*646* otherwise (means no other user process waiting for the647* payload, issue recv HVPIPE RTAS (papr_hvpipe_work_fn())648* to unblock pipe.649*/650spin_lock(&hvpipe_src_list_lock);651src_info = hvpipe_find_source(be32_to_cpu(hvpipe_event->srcID));652if (src_info) {653u32 flags = 0;654655if (hvpipe_event->event_type & HVPIPE_LOST_CONNECTION)656flags = HVPIPE_LOST_CONNECTION;657else if (hvpipe_event->event_type & HVPIPE_MSG_AVAILABLE)658flags = HVPIPE_MSG_AVAILABLE;659660src_info->hvpipe_status |= flags;661wake_up(&src_info->recv_wqh);662spin_unlock(&hvpipe_src_list_lock);663} else {664spin_unlock(&hvpipe_src_list_lock);665/*666* user space is not waiting on this source. So667* execute receive pipe RTAS so that pipe will not668* be blocked.669*/670if (hvpipe_event->event_type & HVPIPE_MSG_AVAILABLE)671queue_work(papr_hvpipe_wq, papr_hvpipe_work);672}673674return IRQ_HANDLED;675}676677/*678* Enable hvpipe by system parameter set with parameter679* token = 64 and with 1 byte buffer data:680* 0 = hvpipe not in use/disable681* 1 = hvpipe in use/enable682*/683static int set_hvpipe_sys_param(u8 val)684{685struct papr_sysparm_buf *buf;686int ret;687688buf = papr_sysparm_buf_alloc();689if (!buf)690return -ENOMEM;691692buf->len = cpu_to_be16(1);693buf->val[0] = val;694ret = papr_sysparm_set(PAPR_SYSPARM_HVPIPE_ENABLE, buf);695if (ret)696pr_err("Can not enable hvpipe %d\n", ret);697698papr_sysparm_buf_free(buf);699700return ret;701}702703static int __init enable_hvpipe_IRQ(void)704{705struct device_node *np;706707hvpipe_check_exception_token = rtas_function_token(RTAS_FN_CHECK_EXCEPTION);708if (hvpipe_check_exception_token == RTAS_UNKNOWN_SERVICE)709return -ENODEV;710711/* hvpipe events */712np = of_find_node_by_path("/event-sources/ibm,hvpipe-msg-events");713if (np != NULL) {714request_event_sources_irqs(np, hvpipe_event_interrupt,715"HPIPE_EVENT");716of_node_put(np);717} else {718pr_err("Can not enable hvpipe event IRQ\n");719return -ENODEV;720}721722return 0;723}724725void hvpipe_migration_handler(int action)726{727pr_info("hvpipe migration event %d\n", action);728729/*730* HVPIPE is not used (Failed to create /dev/papr-hvpipe).731* So nothing to do for migration.732*/733if (!papr_hvpipe_work)734return;735736switch (action) {737case HVPIPE_SUSPEND:738if (hvpipe_feature) {739/*740* Disable hvpipe_feature to the user space.741* It will be enabled with RESUME event.742*/743hvpipe_feature = false;744/*745* set system parameter hvpipe 'disable'746*/747set_hvpipe_sys_param(0);748}749break;750case HVPIPE_RESUME:751/*752* set system parameter hvpipe 'enable'753*/754if (!set_hvpipe_sys_param(1))755hvpipe_feature = true;756else757pr_err("hvpipe is not enabled after migration\n");758759break;760}761}762763static const struct file_operations papr_hvpipe_ops = {764.unlocked_ioctl = papr_hvpipe_dev_ioctl,765};766767static struct miscdevice papr_hvpipe_dev = {768.minor = MISC_DYNAMIC_MINOR,769.name = "papr-hvpipe",770.fops = &papr_hvpipe_ops,771};772773static int __init papr_hvpipe_init(void)774{775int ret;776777if (!of_find_property(rtas.dev, "ibm,hypervisor-pipe-capable",778NULL))779return -ENODEV;780781if (!rtas_function_implemented(RTAS_FN_IBM_SEND_HVPIPE_MSG) ||782!rtas_function_implemented(RTAS_FN_IBM_RECEIVE_HVPIPE_MSG))783return -ENODEV;784785papr_hvpipe_work = kzalloc(sizeof(struct work_struct), GFP_ATOMIC);786if (!papr_hvpipe_work)787return -ENOMEM;788789INIT_WORK(papr_hvpipe_work, papr_hvpipe_work_fn);790791papr_hvpipe_wq = alloc_ordered_workqueue("papr hvpipe workqueue", 0);792if (!papr_hvpipe_wq) {793ret = -ENOMEM;794goto out;795}796797ret = enable_hvpipe_IRQ();798if (!ret) {799ret = set_hvpipe_sys_param(1);800if (!ret)801ret = misc_register(&papr_hvpipe_dev);802}803804if (!ret) {805pr_info("hvpipe feature is enabled\n");806hvpipe_feature = true;807return 0;808}809810pr_err("hvpipe feature is not enabled %d\n", ret);811destroy_workqueue(papr_hvpipe_wq);812out:813kfree(papr_hvpipe_work);814papr_hvpipe_work = NULL;815return ret;816}817machine_device_initcall(pseries, papr_hvpipe_init);818819820