Path: blob/master/arch/powerpc/platforms/pseries/papr-hvpipe.c
52110 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 __free(kfree) = NULL;482483spin_lock(&hvpipe_src_list_lock);484/*485* Do not allow more than one process communicates with486* each source.487*/488src_info = hvpipe_find_source(srcID);489if (src_info) {490spin_unlock(&hvpipe_src_list_lock);491pr_err("pid(%d) is already using the source(%d)\n",492src_info->tsk->pid, srcID);493return -EALREADY;494}495spin_unlock(&hvpipe_src_list_lock);496497src_info = kzalloc(sizeof(*src_info), GFP_KERNEL_ACCOUNT);498if (!src_info)499return -ENOMEM;500501src_info->srcID = srcID;502src_info->tsk = current;503init_waitqueue_head(&src_info->recv_wqh);504505FD_PREPARE(fdf, O_RDONLY | O_CLOEXEC,506anon_inode_getfile("[papr-hvpipe]", &papr_hvpipe_handle_ops,507(void *)src_info, O_RDWR));508if (fdf.err)509return fdf.err;510511retain_and_null_ptr(src_info);512spin_lock(&hvpipe_src_list_lock);513/*514* If two processes are executing ioctl() for the same515* source ID concurrently, prevent the second process to516* acquire FD.517*/518if (hvpipe_find_source(srcID)) {519spin_unlock(&hvpipe_src_list_lock);520return -EALREADY;521}522list_add(&src_info->list, &hvpipe_src_list);523spin_unlock(&hvpipe_src_list_lock);524return fd_publish(fdf);525}526527/*528* Top-level ioctl handler for /dev/papr_hvpipe529*530* Use separate FD for each source (exa :HMC). So ioctl is called531* with source ID which returns FD.532*/533static long papr_hvpipe_dev_ioctl(struct file *filp, unsigned int ioctl,534unsigned long arg)535{536u32 __user *argp = (void __user *)arg;537u32 srcID;538long ret;539540/*541* Return -ENXIO during migration542*/543if (!hvpipe_feature)544return -ENXIO;545546if (get_user(srcID, argp))547return -EFAULT;548549/*550* Support only HMC source right now551*/552if (!(srcID & HVPIPE_HMC_ID_MASK))553return -EINVAL;554555switch (ioctl) {556case PAPR_HVPIPE_IOC_CREATE_HANDLE:557ret = papr_hvpipe_dev_create_handle(srcID);558break;559default:560ret = -ENOIOCTLCMD;561break;562}563564return ret;565}566567/*568* papr_hvpipe_work_fn - called to issue recv HVPIPE RTAS for569* sources that are not monitored by user space so that pipe570* will not be blocked.571*/572static void papr_hvpipe_work_fn(struct work_struct *work)573{574hvpipe_rtas_recv_msg(NULL, 0);575}576577/*578* HVPIPE event message IRQ handler.579* The hypervisor sends event IRQ if the partition has payload580* and generates another event only after payload is read with581* recv HVPIPE RTAS.582*/583static irqreturn_t hvpipe_event_interrupt(int irq, void *dev_id)584{585struct hvpipe_event_buf *hvpipe_event;586struct pseries_errorlog *pseries_log;587struct hvpipe_source_info *src_info;588struct rtas_error_log *elog;589int rc;590591rc = rtas_call(hvpipe_check_exception_token, 6, 1, NULL,592RTAS_VECTOR_EXTERNAL_INTERRUPT, virq_to_hw(irq),593RTAS_HVPIPE_MSG_EVENTS, 1, __pa(&hvpipe_ras_buf),594rtas_get_error_log_max());595596if (rc != 0) {597pr_err_ratelimited("unexpected hvpipe-event-notification failed %d\n", rc);598return IRQ_HANDLED;599}600601elog = (struct rtas_error_log *)hvpipe_ras_buf;602if (unlikely(rtas_error_type(elog) != RTAS_TYPE_HVPIPE)) {603pr_warn_ratelimited("Unexpected event type %d\n",604rtas_error_type(elog));605return IRQ_HANDLED;606}607608pseries_log = get_pseries_errorlog(elog,609PSERIES_ELOG_SECT_ID_HVPIPE_EVENT);610hvpipe_event = (struct hvpipe_event_buf *)pseries_log->data;611612/*613* The hypervisor notifies partition when the payload is614* available to read with recv HVPIPE RTAS and it will not615* notify another event for any source until the previous616* payload is read. Means the pipe is blocked in the617* hypervisor until the payload is read.618*619* If the source is ready to accept payload and wakeup the620* corresponding FD. Hold lock and update hvpipe_status621* and this lock is needed in case the user space process622* is in release FD instead of poll() so that release()623* reads the payload to unblock pipe before closing FD.624*625* otherwise (means no other user process waiting for the626* payload, issue recv HVPIPE RTAS (papr_hvpipe_work_fn())627* to unblock pipe.628*/629spin_lock(&hvpipe_src_list_lock);630src_info = hvpipe_find_source(be32_to_cpu(hvpipe_event->srcID));631if (src_info) {632u32 flags = 0;633634if (hvpipe_event->event_type & HVPIPE_LOST_CONNECTION)635flags = HVPIPE_LOST_CONNECTION;636else if (hvpipe_event->event_type & HVPIPE_MSG_AVAILABLE)637flags = HVPIPE_MSG_AVAILABLE;638639src_info->hvpipe_status |= flags;640wake_up(&src_info->recv_wqh);641spin_unlock(&hvpipe_src_list_lock);642} else {643spin_unlock(&hvpipe_src_list_lock);644/*645* user space is not waiting on this source. So646* execute receive pipe RTAS so that pipe will not647* be blocked.648*/649if (hvpipe_event->event_type & HVPIPE_MSG_AVAILABLE)650queue_work(papr_hvpipe_wq, papr_hvpipe_work);651}652653return IRQ_HANDLED;654}655656/*657* Enable hvpipe by system parameter set with parameter658* token = 64 and with 1 byte buffer data:659* 0 = hvpipe not in use/disable660* 1 = hvpipe in use/enable661*/662static int set_hvpipe_sys_param(u8 val)663{664struct papr_sysparm_buf *buf;665int ret;666667buf = papr_sysparm_buf_alloc();668if (!buf)669return -ENOMEM;670671buf->len = cpu_to_be16(1);672buf->val[0] = val;673ret = papr_sysparm_set(PAPR_SYSPARM_HVPIPE_ENABLE, buf);674if (ret)675pr_err("Can not enable hvpipe %d\n", ret);676677papr_sysparm_buf_free(buf);678679return ret;680}681682static int __init enable_hvpipe_IRQ(void)683{684struct device_node *np;685686hvpipe_check_exception_token = rtas_function_token(RTAS_FN_CHECK_EXCEPTION);687if (hvpipe_check_exception_token == RTAS_UNKNOWN_SERVICE)688return -ENODEV;689690/* hvpipe events */691np = of_find_node_by_path("/event-sources/ibm,hvpipe-msg-events");692if (np != NULL) {693request_event_sources_irqs(np, hvpipe_event_interrupt,694"HPIPE_EVENT");695of_node_put(np);696} else {697pr_err("Can not enable hvpipe event IRQ\n");698return -ENODEV;699}700701return 0;702}703704void hvpipe_migration_handler(int action)705{706pr_info("hvpipe migration event %d\n", action);707708/*709* HVPIPE is not used (Failed to create /dev/papr-hvpipe).710* So nothing to do for migration.711*/712if (!papr_hvpipe_work)713return;714715switch (action) {716case HVPIPE_SUSPEND:717if (hvpipe_feature) {718/*719* Disable hvpipe_feature to the user space.720* It will be enabled with RESUME event.721*/722hvpipe_feature = false;723/*724* set system parameter hvpipe 'disable'725*/726set_hvpipe_sys_param(0);727}728break;729case HVPIPE_RESUME:730/*731* set system parameter hvpipe 'enable'732*/733if (!set_hvpipe_sys_param(1))734hvpipe_feature = true;735else736pr_err("hvpipe is not enabled after migration\n");737738break;739}740}741742static const struct file_operations papr_hvpipe_ops = {743.unlocked_ioctl = papr_hvpipe_dev_ioctl,744};745746static struct miscdevice papr_hvpipe_dev = {747.minor = MISC_DYNAMIC_MINOR,748.name = "papr-hvpipe",749.fops = &papr_hvpipe_ops,750};751752static int __init papr_hvpipe_init(void)753{754int ret;755756if (!of_find_property(rtas.dev, "ibm,hypervisor-pipe-capable",757NULL))758return -ENODEV;759760if (!rtas_function_implemented(RTAS_FN_IBM_SEND_HVPIPE_MSG) ||761!rtas_function_implemented(RTAS_FN_IBM_RECEIVE_HVPIPE_MSG))762return -ENODEV;763764papr_hvpipe_work = kzalloc(sizeof(struct work_struct), GFP_ATOMIC);765if (!papr_hvpipe_work)766return -ENOMEM;767768INIT_WORK(papr_hvpipe_work, papr_hvpipe_work_fn);769770papr_hvpipe_wq = alloc_ordered_workqueue("papr hvpipe workqueue", 0);771if (!papr_hvpipe_wq) {772ret = -ENOMEM;773goto out;774}775776ret = enable_hvpipe_IRQ();777if (!ret) {778ret = set_hvpipe_sys_param(1);779if (!ret)780ret = misc_register(&papr_hvpipe_dev);781}782783if (!ret) {784pr_info("hvpipe feature is enabled\n");785hvpipe_feature = true;786return 0;787}788789pr_err("hvpipe feature is not enabled %d\n", ret);790destroy_workqueue(papr_hvpipe_wq);791out:792kfree(papr_hvpipe_work);793papr_hvpipe_work = NULL;794return ret;795}796machine_device_initcall(pseries, papr_hvpipe_init);797798799