On 04.02.20 13:11, Cornelia Huck wrote: > On Mon, 3 Feb 2020 08:19:27 -0500 > Christian Borntraeger <borntraeger@xxxxxxxxxx> wrote: > >> From: Janosch Frank <frankja@xxxxxxxxxxxxx> >> >> This add 2 new variants of the UV CALL. >> >> The first variant handles UV CALLs that might have longer busy >> conditions or just need longer when doing partial completion. We should >> schedule when necessary. >> >> The second variant handles UV CALLs that only need the handle but have >> no payload (e.g. destroying a VM). We can provide a simple wrapper for >> those. >> >> Signed-off-by: Janosch Frank <frankja@xxxxxxxxxxxxx> >> --- >> arch/s390/include/asm/uv.h | 58 ++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 58 insertions(+) >> >> diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h >> index 4eaea95f5c64..3448f12ef57a 100644 >> --- a/arch/s390/include/asm/uv.h >> +++ b/arch/s390/include/asm/uv.h >> @@ -14,6 +14,7 @@ >> #include <linux/types.h> >> #include <linux/errno.h> >> #include <linux/bug.h> >> +#include <linux/sched.h> >> #include <asm/page.h> >> #include <asm/gmap.h> >> >> @@ -92,6 +93,18 @@ struct uv_cb_cfs { >> u64 paddr; >> } __packed __aligned(8); >> >> +/* >> + * A common UV call struct for the following calls: > > "for calls that take no payload"? > > In case there will be more of them in the future :) ack. /* * A common UV call struct for calls that take no payload * Examples: * Destroy cpu/config * Verify */ > >> + * Destroy cpu/config >> + * Verify >> + */ >> +struct uv_cb_nodata { >> + struct uv_cb_header header; >> + u64 reserved08[2]; >> + u64 handle; >> + u64 reserved20[4]; >> +} __packed __aligned(8); >> + >> struct uv_cb_share { >> struct uv_cb_header header; >> u64 reserved08[3]; >> @@ -99,6 +112,31 @@ struct uv_cb_share { >> u64 reserved28; >> } __packed __aligned(8); >> >> +/* >> + * Low level uv_call that takes r1 and r2 as parameter and avoids >> + * stalls for long running busy conditions by doing schedule > > This can only ever return 0 or 1, right? Right. But the r2 parameter is usually an uvcb so callers can fiddle out more information (like rc) themselves. > >> + */ >> +static inline int uv_call_sched(unsigned long r1, unsigned long r2) >> +{ >> + int cc = 3; >> + >> + while (cc > 1) { >> + asm volatile( >> + "0: .insn rrf,0xB9A40000,%[r1],%[r2],0,0\n" >> + " ipm %[cc]\n" >> + " srl %[cc],28\n" >> + : [cc] "=d" (cc) >> + : [r1] "a" (r1), [r2] "a" (r2) >> + : "memory", "cc"); >> + if (need_resched()) >> + schedule(); >> + } >> + return cc; >> +} >> + >> +/* >> + * Low level uv_call that takes r1 and r2 as parameter >> + */ >> static inline int uv_call(unsigned long r1, unsigned long r2) >> { >> int cc; >> @@ -114,6 +152,26 @@ static inline int uv_call(unsigned long r1, unsigned long r2) >> return cc; >> } >> >> +/* >> + * special variant of uv_call that only transport the cpu or guest > > s/transport/transports/ ack.