Commit 0d6d75d2 authored by Heiko Carstens's avatar Heiko Carstens

KVM: s390: generate kvm hypercall functions

Generate kvm hypercall functions with a macro instead of duplicating
the more or less identical code seven times. This also reduces number
of lines of code.
However the main purpose is to get rid of as many as possible open
coded error prone register asm constructs in s390 architecture code.

For the only user of kvm_hypercall identical code is created
before/after this patch (drivers/s390/virtio/virtio_ccw.c).
Reviewed-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Acked-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Link: https://lore.kernel.org/r/20210713145713.2815167-1-hca@linux.ibm.comSigned-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 70aa5d39
...@@ -24,162 +24,79 @@ ...@@ -24,162 +24,79 @@
#include <uapi/asm/kvm_para.h> #include <uapi/asm/kvm_para.h>
#include <asm/diag.h> #include <asm/diag.h>
static inline long __kvm_hypercall0(unsigned long nr) #define HYPERCALL_FMT_0
{ #define HYPERCALL_FMT_1 , "0" (r2)
register unsigned long __nr asm("1") = nr; #define HYPERCALL_FMT_2 , "d" (r3) HYPERCALL_FMT_1
register long __rc asm("2"); #define HYPERCALL_FMT_3 , "d" (r4) HYPERCALL_FMT_2
#define HYPERCALL_FMT_4 , "d" (r5) HYPERCALL_FMT_3
asm volatile ("diag 2,4,0x500\n" #define HYPERCALL_FMT_5 , "d" (r6) HYPERCALL_FMT_4
: "=d" (__rc) : "d" (__nr): "memory", "cc"); #define HYPERCALL_FMT_6 , "d" (r7) HYPERCALL_FMT_5
return __rc;
} #define HYPERCALL_PARM_0
#define HYPERCALL_PARM_1 , unsigned long arg1
static inline long kvm_hypercall0(unsigned long nr) #define HYPERCALL_PARM_2 HYPERCALL_PARM_1, unsigned long arg2
{ #define HYPERCALL_PARM_3 HYPERCALL_PARM_2, unsigned long arg3
diag_stat_inc(DIAG_STAT_X500); #define HYPERCALL_PARM_4 HYPERCALL_PARM_3, unsigned long arg4
return __kvm_hypercall0(nr); #define HYPERCALL_PARM_5 HYPERCALL_PARM_4, unsigned long arg5
} #define HYPERCALL_PARM_6 HYPERCALL_PARM_5, unsigned long arg6
static inline long __kvm_hypercall1(unsigned long nr, unsigned long p1) #define HYPERCALL_REGS_0
{ #define HYPERCALL_REGS_1 \
register unsigned long __nr asm("1") = nr; register unsigned long r2 asm("2") = arg1
register unsigned long __p1 asm("2") = p1; #define HYPERCALL_REGS_2 \
register long __rc asm("2"); HYPERCALL_REGS_1; \
register unsigned long r3 asm("3") = arg2
asm volatile ("diag 2,4,0x500\n" #define HYPERCALL_REGS_3 \
: "=d" (__rc) : "d" (__nr), "0" (__p1) : "memory", "cc"); HYPERCALL_REGS_2; \
return __rc; register unsigned long r4 asm("4") = arg3
} #define HYPERCALL_REGS_4 \
HYPERCALL_REGS_3; \
static inline long kvm_hypercall1(unsigned long nr, unsigned long p1) register unsigned long r5 asm("5") = arg4
{ #define HYPERCALL_REGS_5 \
diag_stat_inc(DIAG_STAT_X500); HYPERCALL_REGS_4; \
return __kvm_hypercall1(nr, p1); register unsigned long r6 asm("6") = arg5
} #define HYPERCALL_REGS_6 \
HYPERCALL_REGS_5; \
static inline long __kvm_hypercall2(unsigned long nr, unsigned long p1, register unsigned long r7 asm("7") = arg6
unsigned long p2)
{ #define HYPERCALL_ARGS_0
register unsigned long __nr asm("1") = nr; #define HYPERCALL_ARGS_1 , arg1
register unsigned long __p1 asm("2") = p1; #define HYPERCALL_ARGS_2 HYPERCALL_ARGS_1, arg2
register unsigned long __p2 asm("3") = p2; #define HYPERCALL_ARGS_3 HYPERCALL_ARGS_2, arg3
register long __rc asm("2"); #define HYPERCALL_ARGS_4 HYPERCALL_ARGS_3, arg4
#define HYPERCALL_ARGS_5 HYPERCALL_ARGS_4, arg5
asm volatile ("diag 2,4,0x500\n" #define HYPERCALL_ARGS_6 HYPERCALL_ARGS_5, arg6
: "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2)
: "memory", "cc"); #define GENERATE_KVM_HYPERCALL_FUNC(args) \
return __rc; static inline \
} long __kvm_hypercall##args(unsigned long nr HYPERCALL_PARM_##args) \
{ \
static inline long kvm_hypercall2(unsigned long nr, unsigned long p1, register unsigned long __nr asm("1") = nr; \
unsigned long p2) register long __rc asm("2"); \
{ HYPERCALL_REGS_##args; \
diag_stat_inc(DIAG_STAT_X500); \
return __kvm_hypercall2(nr, p1, p2); asm volatile ( \
} " diag 2,4,0x500\n" \
: "=d" (__rc) \
static inline long __kvm_hypercall3(unsigned long nr, unsigned long p1, : "d" (__nr) HYPERCALL_FMT_##args \
unsigned long p2, unsigned long p3) : "memory", "cc"); \
{ return __rc; \
register unsigned long __nr asm("1") = nr; } \
register unsigned long __p1 asm("2") = p1; \
register unsigned long __p2 asm("3") = p2; static inline \
register unsigned long __p3 asm("4") = p3; long kvm_hypercall##args(unsigned long nr HYPERCALL_PARM_##args) \
register long __rc asm("2"); { \
diag_stat_inc(DIAG_STAT_X500); \
asm volatile ("diag 2,4,0x500\n" return __kvm_hypercall##args(nr HYPERCALL_ARGS_##args); \
: "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2), }
"d" (__p3) : "memory", "cc");
return __rc; GENERATE_KVM_HYPERCALL_FUNC(0)
} GENERATE_KVM_HYPERCALL_FUNC(1)
GENERATE_KVM_HYPERCALL_FUNC(2)
static inline long kvm_hypercall3(unsigned long nr, unsigned long p1, GENERATE_KVM_HYPERCALL_FUNC(3)
unsigned long p2, unsigned long p3) GENERATE_KVM_HYPERCALL_FUNC(4)
{ GENERATE_KVM_HYPERCALL_FUNC(5)
diag_stat_inc(DIAG_STAT_X500); GENERATE_KVM_HYPERCALL_FUNC(6)
return __kvm_hypercall3(nr, p1, p2, p3);
}
static inline long __kvm_hypercall4(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4)
{
register unsigned long __nr asm("1") = nr;
register unsigned long __p1 asm("2") = p1;
register unsigned long __p2 asm("3") = p2;
register unsigned long __p3 asm("4") = p3;
register unsigned long __p4 asm("5") = p4;
register long __rc asm("2");
asm volatile ("diag 2,4,0x500\n"
: "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2),
"d" (__p3), "d" (__p4) : "memory", "cc");
return __rc;
}
static inline long kvm_hypercall4(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4)
{
diag_stat_inc(DIAG_STAT_X500);
return __kvm_hypercall4(nr, p1, p2, p3, p4);
}
static inline long __kvm_hypercall5(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5)
{
register unsigned long __nr asm("1") = nr;
register unsigned long __p1 asm("2") = p1;
register unsigned long __p2 asm("3") = p2;
register unsigned long __p3 asm("4") = p3;
register unsigned long __p4 asm("5") = p4;
register unsigned long __p5 asm("6") = p5;
register long __rc asm("2");
asm volatile ("diag 2,4,0x500\n"
: "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2),
"d" (__p3), "d" (__p4), "d" (__p5) : "memory", "cc");
return __rc;
}
static inline long kvm_hypercall5(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5)
{
diag_stat_inc(DIAG_STAT_X500);
return __kvm_hypercall5(nr, p1, p2, p3, p4, p5);
}
static inline long __kvm_hypercall6(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5,
unsigned long p6)
{
register unsigned long __nr asm("1") = nr;
register unsigned long __p1 asm("2") = p1;
register unsigned long __p2 asm("3") = p2;
register unsigned long __p3 asm("4") = p3;
register unsigned long __p4 asm("5") = p4;
register unsigned long __p5 asm("6") = p5;
register unsigned long __p6 asm("7") = p6;
register long __rc asm("2");
asm volatile ("diag 2,4,0x500\n"
: "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2),
"d" (__p3), "d" (__p4), "d" (__p5), "d" (__p6)
: "memory", "cc");
return __rc;
}
static inline long kvm_hypercall6(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5,
unsigned long p6)
{
diag_stat_inc(DIAG_STAT_X500);
return __kvm_hypercall6(nr, p1, p2, p3, p4, p5, p6);
}
/* kvm on s390 is always paravirtualization enabled */ /* kvm on s390 is always paravirtualization enabled */
static inline int kvm_para_available(void) static inline int kvm_para_available(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment