Skip to content

Commit 22bfbd4

Browse files
author
Mamatha Inamdar
committed
powerpc/pseries: Send payload with ibm,send-hvpipe-msg RTAS
JIRA: https://issues.redhat.com/browse/RHEL-101849 Conflicts: - Use rtas_token() instead of rtas_function_token() - Use 0 for RTAS_SUCCESS (This definition needs upstream 9592aa5 "powerpc/rtas: Add function return status constants") commit 56dbc66 Author: Haren Myneni <haren@linux.ibm.com> Date: Tue Sep 9 01:43:56 2025 -0700 powerpc/pseries: Send payload with ibm,send-hvpipe-msg RTAS ibm,send-hvpipe-msg RTAS call is used to send data to the source (Ex: Hardware Management Console) over the hypervisor pipe. The maximum data length of 4048 bytes is supported with this RTAS call right now. The user space uses write() to send this payload which invokes this RTAS. Then the write returns the buffer length (including papr_hvpipe_hdr length) to the user space for success or RTAS failure error. ibm,send-hvpipe-msg call takes source ID as target and the buffer in the form of buffer list. The buffer list format consists of work area of size 4K to hold buffer list and number of 4K work areas depends on buffers is as follows: Length of Buffer List in bytes Address of 4K buffer 1 Length of 4K buffer 1 used ... Address of 4K buffer n Length of 4K buffer n used Only one buffer is used right now because of max payload size is 4048 bytes. writev() can be used in future when supported more than one buffer. Signed-off-by: Haren Myneni <haren@linux.ibm.com> Tested-by: Shashank MS <shashank.gowda@in.ibm.com> Reviewed-by: Mahesh Salgaonkar <mahesh@linux.ibm.com> Reviewed-by: Tyrel Datwyler <tyreld@linux.ibm.com> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> Link: https://patch.msgid.link/20250909084402.1488456-5-haren@linux.ibm.com Signed-off-by: Mamatha Inamdar <minamdar@redhat.com>
1 parent 7018cb9 commit 22bfbd4

File tree

2 files changed

+124
-1
lines changed

2 files changed

+124
-1
lines changed

arch/powerpc/platforms/pseries/papr-hvpipe.c

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/of.h>
1515
#include <asm/machdep.h>
1616
#include <asm/rtas.h>
17+
#include <asm/rtas-work-area.h>
1718
#include <uapi/asm/papr-hvpipe.h>
1819
#include "pseries.h"
1920
#include "papr-hvpipe.h"
@@ -59,6 +60,51 @@ static LIST_HEAD(hvpipe_src_list);
5960
* return code for failure.
6061
*/
6162

63+
/*
64+
* ibm,send-hvpipe-msg RTAS call
65+
* @area: Caller-provided work area buffer to send.
66+
* @srcID: Target source for the send pipe message.
67+
*/
68+
static int rtas_ibm_send_hvpipe_msg(struct rtas_work_area *area, u32 srcID)
69+
{
70+
const s32 token = rtas_token("ibm,send-hvpipe-msg");
71+
s32 fwrc;
72+
int ret;
73+
74+
if (token == RTAS_UNKNOWN_SERVICE)
75+
return -ENOENT;
76+
77+
do {
78+
fwrc = rtas_call(token, 2, 1, NULL, srcID,
79+
rtas_work_area_phys(area));
80+
81+
} while (rtas_busy_delay(fwrc));
82+
83+
switch (fwrc) {
84+
case 0: /* Success */
85+
ret = 0;
86+
break;
87+
case RTAS_HARDWARE_ERROR:
88+
ret = -EIO;
89+
break;
90+
case RTAS_INVALID_PARAMETER:
91+
ret = -EINVAL;
92+
break;
93+
case RTAS_HVPIPE_CLOSED:
94+
ret = -EPIPE;
95+
break;
96+
case RTAS_FUNC_NOT_SUPPORTED:
97+
ret = -EOPNOTSUPP;
98+
break;
99+
default:
100+
ret = -EIO;
101+
pr_err_ratelimited("unexpected ibm,receive-hvpipe-msg status %d\n", fwrc);
102+
break;
103+
}
104+
105+
return ret;
106+
}
107+
62108
static struct hvpipe_source_info *hvpipe_find_source(u32 srcID)
63109
{
64110
struct hvpipe_source_info *src_info;
@@ -78,11 +124,81 @@ static ssize_t papr_hvpipe_handle_write(struct file *file,
78124
const char __user *buf, size_t size, loff_t *off)
79125
{
80126
struct hvpipe_source_info *src_info = file->private_data;
127+
struct rtas_work_area *work_area, *work_buf;
128+
unsigned long ret, len;
129+
__be64 *area_be;
81130

82131
if (!src_info)
83132
return -EIO;
84133

85-
return 0;
134+
/*
135+
* Send HVPIPE RTAS is used to send payload to the specific
136+
* source with the input parameters source ID and the payload
137+
* as buffer list. Each entry in the buffer list contains
138+
* address/length pair of the buffer.
139+
*
140+
* The buffer list format is as follows:
141+
*
142+
* Header (length of address/length pairs and the header length)
143+
* Address of 4K buffer 1
144+
* Length of 4K buffer 1 used
145+
* ...
146+
* Address of 4K buffer n
147+
* Length of 4K buffer n used
148+
*
149+
* See PAPR 7.3.32.2 ibm,send-hvpipe-msg
150+
*
151+
* Even though can support max 1MB payload, the hypervisor
152+
* supports only 4048 bytes payload at present and also
153+
* just one address/length entry.
154+
*
155+
* writev() interface can be added in future when the
156+
* hypervisor supports multiple buffer list entries.
157+
*/
158+
/* HVPIPE_MAX_WRITE_BUFFER_SIZE = 4048 bytes */
159+
if ((size > (HVPIPE_HDR_LEN + HVPIPE_MAX_WRITE_BUFFER_SIZE)) ||
160+
(size <= HVPIPE_HDR_LEN))
161+
return -EINVAL;
162+
163+
/*
164+
* The length of (address + length) pair + the length of header
165+
*/
166+
len = (2 * sizeof(u64)) + sizeof(u64);
167+
size -= HVPIPE_HDR_LEN;
168+
buf += HVPIPE_HDR_LEN;
169+
mutex_lock(&rtas_ibm_send_hvpipe_msg_lock);
170+
work_area = rtas_work_area_alloc(SZ_4K);
171+
if (!work_area) {
172+
ret = -ENOMEM;
173+
goto out;
174+
}
175+
area_be = (__be64 *)rtas_work_area_raw_buf(work_area);
176+
/* header */
177+
area_be[0] = cpu_to_be64(len);
178+
179+
work_buf = rtas_work_area_alloc(SZ_4K);
180+
if (!work_buf) {
181+
ret = -ENOMEM;
182+
goto out_work;
183+
}
184+
/* First buffer address */
185+
area_be[1] = cpu_to_be64(rtas_work_area_phys(work_buf));
186+
/* First buffer address length */
187+
area_be[2] = cpu_to_be64(size);
188+
189+
if (!copy_from_user(rtas_work_area_raw_buf(work_buf), buf, size)) {
190+
ret = rtas_ibm_send_hvpipe_msg(work_area, src_info->srcID);
191+
if (!ret)
192+
ret = size + HVPIPE_HDR_LEN;
193+
} else
194+
ret = -EPERM;
195+
196+
rtas_work_area_free(work_buf);
197+
out_work:
198+
rtas_work_area_free(work_area);
199+
out:
200+
mutex_unlock(&rtas_ibm_send_hvpipe_msg_lock);
201+
return ret;
86202
}
87203

88204
/*

arch/powerpc/platforms/pseries/papr-hvpipe.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
#define _PAPR_HVPIPE_H
44

55
#define HVPIPE_HMC_ID_MASK 0x02000000 /*02-HMC,00-reserved and HMC ID */
6+
#define HVPIPE_MAX_WRITE_BUFFER_SIZE 4048
7+
/*
8+
* hvpipe specific RTAS return values
9+
*/
10+
#define RTAS_HVPIPE_CLOSED -4
11+
12+
#define HVPIPE_HDR_LEN sizeof(struct papr_hvpipe_hdr)
613

714
struct hvpipe_source_info {
815
struct list_head list; /* list of sources */

0 commit comments

Comments
 (0)