On 12/19/23 3:20 PM, kirill.shutemov@xxxxxxxxxxxxxxx wrote:
On Tue, Dec 19, 2023 at 01:57:47PM -0800, Alexey Makhalov wrote:
+static inline
+unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
...
+static inline
+unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
+ uint32_t *out1, uint32_t *out2)
...
+static inline
+unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
+ uint32_t *out1, uint32_t *out2,
+ uint32_t *out3)
...
+static inline
+unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, uint32_t *out2)
...
+static inline
+unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1,
+ unsigned long in3, uint32_t *out2,
+ uint32_t *out3, uint32_t *out4,
+ uint32_t *out5)
...
+static inline
+unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, uint32_t *out1,
+ uint32_t *out2, uint32_t *out3)
Naming is weird. The number in the name doesn't help much as there seems
no system on how many of the parameters are ins and outs.
There was internal discussion on hypercall API naming. One of proposals
was using 2 digits - number of input and number of output arguments.
And it definitely looked weird. So, we agreed to have just single number
- total number of arguments excluding cmd.
Why these combinations of ins/outs are supported?
VMware hypercalls can use up to 6 ins and 6 outs for LB and 7 ins and 7
outs for HB calls. The mapping to x86 registers is below:
in0/out0 - rax
in1/out1 - rbx
in2/out2 - rcx
in3/out3 - rdx
in4/out4 - rsi
in5/out5 - rdi
in6/out6 - rbp (only used in high bandwidth hypercalls)
args 0, 2 and 6 are remapped to r12, r13 and r14 for TDX.
There is a standard on some arguments such as cmd on in2, magic on in0
and output value is on out0. While other arguments are not standardized
across hypercall.
Theoreticaly max hypercall, in term of number of arguments:
vmware_hypercall9(cmd, in1, in3, in4, in5, *out1, *out2, *out3, *out4,
*out5)
But there is no such called in a linux kernel.
Current combination of hypercalls covers all current and future (not yet
upstreamed) callers, with round up to next number in some cases.
And as an outsider, I'm curious where in2 got lost :P
'lost' arguments:
in0 - indirectly initialized inside hypercall function.
out0 - return value from the hypercall.
[LB hypercalls] in2 <- input cmd
[HB hypercalls] in1 <- input cmd
Regards,
--Alexey