On 2025-08-12 15:57:07 Tue, Haren Myneni wrote:
> The hypervisor provides ibm,send-hvpipe-msg and
> ibm,receive-hvpipe-msg RTAS calls which can be used by the
> partition to communicate through an inband hypervisor channel with
> different external sources such as Hardware Management Console
> (HMC). The information exchanged, whether it be messages, raw or
> formatted data, etc., is only known to between applications in the
> OS and the source (HMC). This patch adds papr-hvpipe character
> driver and provides the standard interfaces such as open / ioctl/
> read / write to user space for exchanging information with HMC
> using send/recevive HVPIPE RTAS functions.
> 
> PAPR (7.3.32 Hypervisor Pipe Information Exchange) defines the
> HVPIPE usage:
> - The hypervisor has one HVPIPE per partition for all sources.
> - OS can determine this feature’s availability by detecting the
>   “ibm,hypervisor-pipe-capable” property in the /rtas node of the
>   device tree.
> - Each source is represented by the source ID which is used in
>   send / recv HVPIPE RTAS. (Ex: source ID is the target for the
>   payload in send RTAS).
> - Return status of ibm,send-hvpipe-msg can be considered as
>   delivered the payload.
> - Return status of ibm,receive-hvpipe-msg can be considered as
>   ACK to source.
> - The hypervisor generates hvpipe message event interrupt when
>   the partition has the payload to receive.
> 
> Provide the interfaces to the user space with /dev/papr-hvpipe
> character device using the following programming model:
> 
> int devfd = open("/dev/papr-hvpipe")
> int fd = ioctl(devfd, PAPR_HVPIPE_IOC_CREATE_HANDLE, &srcID);
> - Restrict the user space to use the same source ID and do not
>   expect more than one process access with the same source.
> char *buf = malloc(size);
> - SIZE should be 4K and the buffer contains header and the
>   payload.
> length = write(fd, buf, size);
> - OS issues ibm,send-hvpipe-msg RTAS and returns the RTAS status
>   to the user space.
> ret = poll(fd,...)
> - The HVPIPE event message IRQ wakes up for any waiting FDs.
> length = read(fd, buf, size);
> - OS issues ibm,receive-hvpipe-msg to receive payload from the
>   hypervisor.
> release(fd);
> - OS issues ibm,receive-hvpipe-msg if any payload is pending so
>   that pipe is not blocked.
> 
> The actual implementation of these calls are added in the
> next patches.
> 
> Signed-off-by: Haren Myneni <ha...@linux.ibm.com>
> ---
>  arch/powerpc/platforms/pseries/Makefile      |   1 +
>  arch/powerpc/platforms/pseries/papr-hvpipe.c | 274 +++++++++++++++++++
>  arch/powerpc/platforms/pseries/papr-hvpipe.h |  14 +
>  3 files changed, 289 insertions(+)
>  create mode 100644 arch/powerpc/platforms/pseries/papr-hvpipe.c
>  create mode 100644 arch/powerpc/platforms/pseries/papr-hvpipe.h
> 
[...]
> +static int papr_hvpipe_dev_create_handle(u32 srcID)
> +{
> +     struct hvpipe_source_info *src_info;
> +     struct file *file;
> +     long err;
> +     int fd;
> +
> +     spin_lock(&hvpipe_src_list_lock);
> +     /*
> +      * Do not allow more than one process communicates with
> +      * each source.
> +      */
> +     src_info = hvpipe_find_source(srcID);
> +     if (src_info) {
> +             spin_unlock(&hvpipe_src_list_lock);
> +             pr_err("pid(%d) is already using the source(%d)\n",
> +                             src_info->tsk->pid, srcID);
> +             return -EALREADY;
> +     }
> +     spin_unlock(&hvpipe_src_list_lock);

What if two process simulteneously try to get handle ? The new src_info
node being allocated below isn't yet on the list. Which means as soon as
we unlock, there is a chance another process can still come here
requesting for same srcID and eventually we will see duplicate or more
entries for same srcID added to the list from different processes.

> +
> +     src_info = kzalloc(sizeof(*src_info), GFP_KERNEL_ACCOUNT);
> +     if (!src_info)
> +             return -ENOMEM;
> +
> +     src_info->srcID = srcID;
> +     src_info->tsk = current;
> +     init_waitqueue_head(&src_info->recv_wqh);
> +
> +     fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
> +     if (fd < 0) {
> +             err = fd;
> +             goto free_buf;
> +     }
> +
> +     file = anon_inode_getfile("[papr-hvpipe]",
> +                     &papr_hvpipe_handle_ops, (void *)src_info,
> +                     O_RDWR);
> +     if (IS_ERR(file)) {
> +             err = PTR_ERR(file);
> +             goto put_fd;
> +     }
> +
> +     fd_install(fd, file);
> +
> +     spin_lock(&hvpipe_src_list_lock);

Should we check again here to make sure same srcID hasn't been already
added to the list while we were unlocked and return -EALREADY ?

> +     list_add(&src_info->list, &hvpipe_src_list);
> +     spin_unlock(&hvpipe_src_list_lock);
> +
> +     return fd;
> +
> +put_fd:
> +     put_unused_fd(fd);
> +free_buf:
> +     kfree(src_info);
> +     return err;
> +}
> +

Reply via email to