From: Juergen Gross <jgross@suse.com>
To: xen-devel@lists.xenproject.org
Cc: Juergen Gross <jgross@suse.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
George Dunlap <george.dunlap@citrix.com>,
Jan Beulich <jbeulich@suse.com>, Julien Grall <julien@xen.org>,
Stefano Stabellini <sstabellini@kernel.org>, Wei Liu <wl@xen.org>
Subject: [PATCH v3 05/13] xen: generate hypercall interface related code
Date: Wed, 8 Dec 2021 16:55:58 +0100 [thread overview]
Message-ID: <20211208155606.20029-6-jgross@suse.com> (raw)
In-Reply-To: <20211208155606.20029-1-jgross@suse.com>
Instead of repeating similar data multiple times use a single source
file and a generator script for producing prototypes and call sequences
of the hypercalls.
As the script already knows the number of parameters used add generating
a macro for populating an array with the number of parameters per
hypercall.
The priorities for the specific hypercalls are based on two benchamrks
performed in guests (PV and PVH):
- make -j 4 of the Xen hypervisor (resulting in cpu load with lots of
processes created)
- scp of a large file to the guest (network load)
With a small additional debug patch applied the number of the
different hypercalls in the guest and in dom0 (for looking at backend
activity related hypercalls) were counted while the benchmark in domU
was running:
PV-hypercall PV-guest build PV-guest scp dom0 build dom0 scp
mmu_update 186175729 2865 20936 33725
stack_switch 1273311 62381 108589 270764
multicall 2182803 50 302 524
update_va_mapping 571868 10 60 80
xen_version 73061 850 859 5432
grant_table_op 0 0 35557 139110
iret 75673006 484132 268157 757958
vcpu_op 453037 71199 138224 334988
set_segment_base 1650249 62387 108645 270823
mmuext_op 11225681 188 7239 3426
sched_op 280153 134645 70729 137943
event_channel_op 192327 66204 71409 214191
physdev_op 0 0 7721 4315
(the dom0 values are for the guest running the build or scp test, so
dom0 acting as backend)
HVM-hypercall PVH-guest build PVH-guest scp
vcpu_op 277684 2324
event_channel_op 350233 57383
(the related dom0 counter values are in the same range as with the test
running in the PV guest)
Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- split platform_op for doe and compat prefixes (Jan Beulich)
- add "addline:" directive
- add priorities to handlers (Jan Beulich)
V2.1:
- add missing "delete" statement in awk script
- optimize case of 2 hypercalls with same priority
V2.2:
- avoid asort() function (Michal Orzel)
V3:
- drop "addline:" support, as no longer needed
- enclose call sequence macros in "({ ... })" (Jan Beulich)
- small style adjustment (Jan Beulich)
- move generating to xen/include/Makefile (Anthony PERARD)
Signed-off-by: Juergen Gross <jgross@suse.com>
---
.gitignore | 1 +
xen/include/Makefile | 13 ++
xen/include/hypercall-defs.c | 280 ++++++++++++++++++++++++++++++
xen/scripts/gen_hypercall.awk | 314 ++++++++++++++++++++++++++++++++++
4 files changed, 608 insertions(+)
create mode 100644 xen/include/hypercall-defs.c
create mode 100644 xen/scripts/gen_hypercall.awk
diff --git a/.gitignore b/.gitignore
index 9513506dd9..753a602e29 100644
--- a/.gitignore
+++ b/.gitignore
@@ -336,6 +336,7 @@ xen/include/public/public
xen/include/xen/*.new
xen/include/xen/acm_policy.h
xen/include/xen/compile.h
+xen/include/xen/hypercall-defs.h
xen/include/xen/lib/x86/cpuid-autogen.h
xen/test/livepatch/config.h
xen/test/livepatch/expect_config.h
diff --git a/xen/include/Makefile b/xen/include/Makefile
index 95daa8a289..43509131b9 100644
--- a/xen/include/Makefile
+++ b/xen/include/Makefile
@@ -77,6 +77,18 @@ compat/xlat.h: $(addprefix compat/.xlat/,$(xlat-y)) config/auto.conf Makefile
cat $(filter %.h,$^) >$@.new
mv -f $@.new $@
+quiet_cmd_genhyp = GEN $@
+define cmd_genhyp
+ awk -f ../scripts/gen_hypercall.awk <$< >$@
+endef
+
+all: xen/hypercall-defs.h
+
+xen/hypercall-defs.h: hypercall-defs.i ../scripts/gen_hypercall.awk FORCE
+ $(call if_changed,genhyp)
+
+targets += xen/hypercall-defs.h
+
ifeq ($(XEN_TARGET_ARCH),$(XEN_COMPILE_ARCH))
all: headers.chk headers99.chk headers++.chk
@@ -133,4 +145,5 @@ endif
clean::
rm -rf compat config generated headers*.chk
+ rm -f xen/hypercall-defs.h hypercall-defs.i
rm -f $(BASEDIR)/include/xen/lib/x86/cpuid-autogen.h
diff --git a/xen/include/hypercall-defs.c b/xen/include/hypercall-defs.c
new file mode 100644
index 0000000000..e08b0a343a
--- /dev/null
+++ b/xen/include/hypercall-defs.c
@@ -0,0 +1,280 @@
+/*
+ * Hypercall interface description:
+ * Used by scripts/gen_hypercall.awk to generate hypercall prototypes and call
+ * sequences.
+ *
+ * Syntax is like a prototype, but without return type and without the ";" at
+ * the end. Pointer types will be automatically converted to use the
+ * XEN_GUEST_HANDLE_PARAM() macro. Handlers with no parameters just use a
+ * definition like "fn()".
+ * Hypercall/function names are without the leading "__HYPERVISOR_"/"do_"
+ * strings.
+ *
+ * The return type of a class of prototypes using the same prefix is set via:
+ * rettype: <prefix> <type>
+ * Default return type is "long". A return type for a prefix can be set only
+ * once and it needs to be set before that prefix is being used via the
+ * "prefix:" directive.
+ *
+ * The prefix of the prototypes is set via a line:
+ * prefix: <prefix> ...
+ * Multiple prefixes are possible (restriction see below). Prefixes are without
+ * a trailing "_". The current prefix settings are active until a new "prefix:"
+ * line.
+ *
+ * Caller macros are suffixed with a selectable name via lines like:
+ * caller: <suffix>
+ * When a caller suffix is active, there is only one active prefix allowed.
+ *
+ * With a "defhandle:" line it is possible to add a DEFINE_XEN_GUEST_HANDLE()
+ * to the generated header:
+ * defhandle: <handle-type> [<type>]
+ * Without specifying <type> only a DEFINE_XEN_GUEST_HANDLE(<handle-type>)
+ * will be generated, otherwise it will be a
+ * __DEFINE_XEN_GUEST_HANDLE(<handle-type>, <type>) being generated. Note that
+ * the latter will include the related "const" handle "const_<handle-type>".
+ *
+ * In order to support using coding style compliant pointers in the
+ * prototypes it is possible to add translation entries to generate the correct
+ * handle types:
+ * handle: <handle-type> <type>
+ * This will result in the prototype translation from "<type> *" to
+ * "XEN_GUEST_HANDLE_PARAM(<handle-type>)".
+ *
+ * The hypercall handler calling code will be generated from a final table in
+ * the source file, which is started via the line:
+ * table: <caller> <caller> ...
+ * with the <caller>s specifying the designated caller macro of each column of
+ * the table. Any column of a <caller> not having been set via a "caller:"
+ * line will be ignored.
+ * The first column of the table contains the hypercall/prototype, each
+ * <caller> column contains the prefix for the function to use for that caller.
+ * A function prefix can be annotated with a priority by adding ":<prio>" to it
+ * ("1" being the highest priority, higher numbers mean lower priority, no
+ * priority specified is the lowest priority). The generated code will try to
+ * achieve better performance for calling high priority handlers.
+ * A column not being supported by a <caller> is marked with "-". Lines with all
+ * entries being "-" after removal of inactive <caller> columns are ignored.
+ *
+ * This file is being preprocessed using $(CPP), so #ifdef CONFIG_* conditionals
+ * are possible.
+ */
+
+#ifdef CONFIG_HVM
+#define PREFIX_hvm hvm
+#else
+#define PREFIX_hvm
+#endif
+
+#ifdef CONFIG_COMPAT
+#define PREFIX_compat compat
+rettype: compat int
+#else
+#define PREFIX_compat
+#endif
+
+#ifdef CONFIG_ARM
+#define PREFIX_dep dep
+#else
+#define PREFIX_dep
+#endif
+
+handle: uint unsigned int
+handle: const_void const void
+handle: const_char const char
+
+#ifdef CONFIG_COMPAT
+defhandle: multicall_entry_compat_t
+#ifndef CONFIG_PV_SHIM_EXCLUSIVE
+defhandle: compat_platform_op_t
+#endif
+#endif
+#ifdef CONFIG_PV32
+defhandle: trap_info_compat_t
+defhandle: physdev_op_compat_t
+#endif
+
+prefix: do PREFIX_hvm PREFIX_compat
+physdev_op(int cmd, void *arg)
+#if defined(CONFIG_GRANT_TABLE) || defined(CONFIG_PV_SHIM)
+grant_table_op(unsigned int cmd, void *uop, unsigned int count)
+#endif
+
+prefix: do PREFIX_hvm
+memory_op(unsigned long cmd, void *arg)
+
+prefix: do PREFIX_compat
+xen_version(int cmd, void *arg)
+vcpu_op(int cmd, unsigned int vcpuid, void *arg)
+sched_op(int cmd, void *arg)
+xsm_op(void *op)
+callback_op(int cmd, const void *arg)
+#ifdef CONFIG_ARGO
+argo_op(unsigned int cmd, void *arg1, void *arg2, unsigned long arg3, unsigned long arg4)
+#endif
+#ifdef CONFIG_KEXEC
+kexec_op(unsigned int op, void *uarg)
+#endif
+#ifdef CONFIG_PV
+iret()
+nmi_op(unsigned int cmd, void *arg)
+#ifdef CONFIG_XENOPROF
+xenoprof_op(int op, void *arg)
+#endif
+#endif /* CONFIG_PV */
+
+#ifdef CONFIG_COMPAT
+prefix: compat
+set_timer_op(uint32_t lo, int32_t hi)
+multicall(multicall_entry_compat_t *call_list, uint32_t nr_calls)
+memory_op(unsigned int cmd, void *arg)
+#ifdef CONFIG_IOREQ_SERVER
+dm_op(domid_t domid, unsigned int nr_bufs, void *bufs)
+#endif
+mmuext_op(void *arg, unsigned int count, uint *pdone, unsigned int foreigndom)
+#ifdef CONFIG_PV32
+set_trap_table(trap_info_compat_t *traps)
+set_gdt(unsigned int *frame_list, unsigned int entries)
+set_callbacks(unsigned long event_selector, unsigned long event_address, unsigned long failsafe_selector, unsigned long failsafe_address)
+update_descriptor(uint32_t pa_lo, uint32_t pa_hi, uint32_t desc_lo, uint32_t desc_hi)
+update_va_mapping(unsigned int va, uint32_t lo, uint32_t hi, unsigned int flags)
+physdev_op_compat(physdev_op_compat_t *uop)
+update_va_mapping_otherdomain(unsigned int va, uint32_t lo, uint32_t hi, unsigned int flags, domid_t domid)
+#endif
+#ifndef CONFIG_PV_SHIM_EXCLUSIVE
+platform_op(compat_platform_op_t *u_xenpf_op)
+#endif
+#endif /* CONFIG_COMPAT */
+
+#if defined(CONFIG_PV) || defined(CONFIG_ARM)
+prefix: do PREFIX_dep
+event_channel_op_compat(evtchn_op_t *uop)
+physdev_op_compat(physdev_op_t *uop)
+/* Legacy hypercall (as of 0x00030101). */
+sched_op_compat(int cmd, unsigned long arg)
+#endif
+
+prefix: do
+set_timer_op(s_time_t timeout)
+console_io(unsigned int cmd, unsigned int count, char *buffer)
+vm_assist(unsigned int cmd, unsigned int type)
+event_channel_op(int cmd, void *arg)
+mmuext_op(mmuext_op_t *uops, unsigned int count, unsigned int *pdone, unsigned int foreigndom)
+multicall(multicall_entry_t *call_list, unsigned int nr_calls)
+#ifdef CONFIG_PV
+mmu_update(mmu_update_t *ureqs, unsigned int count, unsigned int *pdone, unsigned int foreigndom)
+stack_switch(unsigned long ss, unsigned long esp)
+fpu_taskswitch(int set)
+set_debugreg(int reg, unsigned long value)
+get_debugreg(int reg)
+set_segment_base(unsigned int which, unsigned long base)
+mca(xen_mc_t *u_xen_mc)
+set_trap_table(const_trap_info_t *traps)
+set_gdt(xen_ulong_t *frame_list, unsigned int entries)
+set_callbacks(unsigned long event_address, unsigned long failsafe_address, unsigned long syscall_address)
+update_descriptor(uint64_t gaddr, seg_desc_t desc)
+update_va_mapping(unsigned long va, uint64_t val64, unsigned long flags)
+update_va_mapping_otherdomain(unsigned long va, uint64_t val64, unsigned long flags, domid_t domid)
+#endif
+#ifdef CONFIG_IOREQ_SERVER
+dm_op(domid_t domid, unsigned int nr_bufs, xen_dm_op_buf_t *bufs)
+#endif
+#ifndef CONFIG_PV_SHIM_EXCLUSIVE
+sysctl(xen_sysctl_t *u_sysctl)
+domctl(xen_domctl_t *u_domctl)
+paging_domctl_cont(xen_domctl_t *u_domctl)
+platform_op(xen_platform_op_t *u_xenpf_op)
+#endif
+#ifdef CONFIG_HVM
+hvm_op(unsigned long op, void *arg)
+#endif
+#ifdef CONFIG_HYPFS
+hypfs_op(unsigned int cmd, const char *arg1, unsigned long arg2, void *arg3, unsigned long arg4)
+#endif
+#ifdef CONFIG_X86
+xenpmu_op(unsigned int op, xen_pmu_params_t *arg)
+#endif
+
+#ifdef CONFIG_PV
+caller: pv64
+#ifdef CONFIG_PV32
+caller: pv32
+#endif
+#endif
+#if defined(CONFIG_HVM) && defined(CONFIG_X86)
+caller: hvm64
+#ifdef CONFIG_COMPAT
+caller: hvm32
+#endif
+#endif
+#ifdef CONFIG_ARM
+caller: arm
+#endif
+
+table: pv32 pv64 hvm32 hvm64 arm
+set_trap_table compat do - - -
+mmu_update do:1 do:1 - - -
+set_gdt compat do - - -
+stack_switch do:2 do:2 - - -
+set_callbacks compat do - - -
+fpu_taskswitch do do - - -
+sched_op_compat do do - - dep
+#ifndef CONFIG_PV_SHIM_EXCLUSIVE
+platform_op compat do compat do do
+#endif
+set_debugreg do do - - -
+get_debugreg do do - - -
+update_descriptor compat do - - -
+memory_op compat do hvm hvm do
+multicall compat:2 do:2 compat do do
+update_va_mapping compat do - - -
+set_timer_op compat do compat do -
+event_channel_op_compat do do - - dep
+xen_version compat do compat do do
+console_io do do do do do
+physdev_op_compat compat do - - dep
+#if defined(CONFIG_GRANT_TABLE) || defined(CONFIG_PV_SHIM)
+grant_table_op compat do hvm hvm do
+#endif
+vm_assist do do do do do
+update_va_mapping_otherdomain compat do - - -
+iret compat:1 do:1 - - -
+vcpu_op compat do compat:1 do:1 do
+set_segment_base do:2 do:2 - - -
+#ifdef CONFIG_PV
+mmuext_op compat:2 do:2 compat do -
+#endif
+xsm_op compat do compat do do
+nmi_op compat do - - -
+sched_op compat do compat do do
+callback_op compat do - - -
+#ifdef CONFIG_XENOPROF
+xenoprof_op compat do - - -
+#endif
+event_channel_op do do do:1 do:1 do
+physdev_op compat do hvm hvm do
+#ifdef CONFIG_HVM
+hvm_op do do do do do
+#endif
+#ifndef CONFIG_PV_SHIM_EXCLUSIVE
+sysctl do do do do do
+domctl do do do do do
+#endif
+#ifdef CONFIG_KEXEC
+kexec_op compat do - - -
+#endif
+tmem_op - - - - -
+#ifdef CONFIG_ARGO
+argo_op compat do compat do do
+#endif
+xenpmu_op do do do do -
+#ifdef CONFIG_IOREQ_SERVER
+dm_op compat do compat do do
+#endif
+#ifdef CONFIG_HYPFS
+hypfs_op do do do do do
+#endif
+mca do do - - -
+#ifndef CONFIG_PV_SHIM_EXCLUSIVE
+paging_domctl_cont do do do do -
+#endif
diff --git a/xen/scripts/gen_hypercall.awk b/xen/scripts/gen_hypercall.awk
new file mode 100644
index 0000000000..34840c514f
--- /dev/null
+++ b/xen/scripts/gen_hypercall.awk
@@ -0,0 +1,314 @@
+# awk script to generate hypercall handler prototypes and a macro for doing
+# the calls of the handlers inside a switch() statement.
+
+BEGIN {
+ printf("/* Generated file, do not edit! */\n\n");
+ e = 0;
+ n = 0;
+ p = 0;
+ nc = 0;
+}
+
+# Issue error to stderr
+function do_err(msg) {
+ print "Error: "msg": "$0 >"/dev/stderr";
+ exit 1;
+}
+
+# Generate handler call
+function do_call(f, p, i) {
+ printf(" ret = %s_%s(", pre[f, p], fn[f]);
+ for (i = 1; i <= n_args[f]; i++) {
+ if (i > 1)
+ printf(", ");
+ if (ptr[f, i])
+ printf("(XEN_GUEST_HANDLE_PARAM(%s)){ _p(a%d) }", typ[f, i], i);
+ else
+ printf("(%s)(a%d)", typ[f, i], i);
+ }
+ printf("); \\\n");
+}
+
+# Generate case statement for call
+function do_case(f, p) {
+ printf(" case __HYPERVISOR_%s: \\\n", fn[f]);
+ do_call(f, p);
+ printf(" break; \\\n");
+}
+
+# Generate switch statement for calling handlers
+function do_switch(ca, p, i) {
+ printf(" switch ( num ) \\\n");
+ printf(" { \\\n");
+ for (i = 1; i <= nc; i++)
+ if (call[i] == ca && call_prio[i] == p)
+ do_case(call_fn[i], call_p[i]);
+ printf(" default: \\\n");
+ printf(" ret = -ENOSYS; \\\n");
+ printf(" break; \\\n");
+ printf(" } \\\n");
+}
+
+function rest_of_line(par, i, val) {
+ val = $(par);
+ for (i = par + 1; i <= NF; i++)
+ val = val " " $(i);
+ return val;
+}
+
+# Handle comments (multi- and single line)
+$1 == "/*" {
+ comment = 1;
+}
+comment == 1 {
+ if ($(NF) == "*/") comment = 0;
+ next;
+}
+
+# Skip preprocessing artefacts
+$1 == "extern" {
+ next;
+}
+/^#/ {
+ next;
+}
+
+# Drop empty lines
+NF == 0 {
+ next;
+}
+
+# Handle "handle:" line
+$1 == "handle:" {
+ if (NF < 3)
+ do_err("\"handle:\" requires at least two parameters");
+ val = rest_of_line(3);
+ xlate[val] = $2;
+ next;
+}
+
+# Handle "defhandle:" line
+$1 == "defhandle:" {
+ if (NF < 2)
+ do_err("\"defhandle:\" requires at least one parameter");
+ e++;
+ if (NF == 2) {
+ emit[e] = sprintf("DEFINE_XEN_GUEST_HANDLE(%s);", $2);
+ } else {
+ val = rest_of_line(3);
+ emit[e] = sprintf("__DEFINE_XEN_GUEST_HANDLE(%s, %s);", $2, val);
+ xlate[val] = $2;
+ }
+ next;
+}
+
+# Handle "rettype:" line
+$1 == "rettype:" {
+ if (NF < 3)
+ do_err("\"rettype:\" requires at least two parameters");
+ if ($2 in rettype)
+ do_err("rettype can be set only once for each prefix");
+ rettype[$2] = rest_of_line(3);
+ next;
+}
+
+# Handle "caller:" line
+$1 == "caller:" {
+ caller[$2] = 1;
+ next;
+}
+
+# Handle "prefix:" line
+$1 == "prefix:" {
+ p = NF - 1;
+ for (i = 2; i <= NF; i++) {
+ prefix[i - 1] = $(i);
+ if (!(prefix[i - 1] in rettype))
+ rettype[prefix[i - 1]] = "long";
+ }
+ next;
+}
+
+# Handle "table:" line
+$1 == "table:" {
+ table = 1;
+ for (i = 2; i <= NF; i++)
+ col[i - 1] = $(i);
+ n_cols = NF - 1;
+ next;
+}
+
+# Handle table definition line
+table == 1 {
+ if (NF != n_cols + 1)
+ do_err("Table definition line has wrong number of fields");
+ for (c = 1; c <= n_cols; c++) {
+ if (caller[col[c]] != 1)
+ continue;
+ if ($(c + 1) == "-")
+ continue;
+ pref = $(c + 1);
+ idx = index(pref, ":");
+ if (idx == 0)
+ prio = 100;
+ else {
+ prio = substr(pref, idx + 1) + 0;
+ pref = substr(pref, 1, idx - 1);
+ if (prio >= 100 || prio < 1)
+ do_err("Priority must be in the range 1..99");
+ }
+ fnd = 0;
+ for (i = 1; i <= n; i++) {
+ if (fn[i] != $1)
+ continue;
+ for (j = 1; j <= n_pre[i]; j++) {
+ if (pre[i, j] == pref) {
+ prios[col[c], prio]++;
+ if (prios[col[c], prio] == 1) {
+ n_prios[col[c]]++;
+ prio_list[col[c], n_prios[col[c]]] = prio;
+ prio_mask[col[c], prio] = "(1ULL << __HYPERVISOR_"$1")";
+ } else
+ prio_mask[col[c], prio] = prio_mask[col[c], prio] " | (1ULL << __HYPERVISOR_"$1")";
+ nc++;
+ call[nc] = col[c];
+ call_fn[nc] = i;
+ call_p[nc] = j;
+ call_prio[nc] = prio;
+ fnd = 1;
+ }
+ }
+ }
+ if (fnd == 0)
+ do_err("No prototype for prefix/hypercall combination");
+ }
+ next;
+}
+
+# Prototype line
+{
+ bro = index($0, "(");
+ brc = index($0, ")");
+ if (bro < 2 || brc < bro)
+ do_err("No valid prototype line");
+ n++;
+ fn[n] = substr($0, 1, bro - 1);
+ n_pre[n] = p;
+ for (i = 1; i <= p; i++)
+ pre[n, i] = prefix[i];
+ args = substr($0, bro + 1, brc - bro - 1);
+ n_args[n] = split(args, a, ",");
+ if (n_args[n] > 5)
+ do_err("Too many parameters");
+ for (i = 1; i <= n_args[n]; i++) {
+ sub("^ *", "", a[i]); # Remove leading white space
+ sub(" +", " ", a[i]); # Replace multiple spaces with single ones
+ sub(" *$", "", a[i]); # Remove trailing white space
+ ptr[n, i] = index(a[i], "*"); # Is it a pointer type?
+ sub("[*]", "", a[i]); # Remove "*"
+ if (index(a[i], " ") == 0)
+ do_err("Parameter with no type or no name");
+ typ[n, i] = a[i];
+ sub(" [^ ]+$", "", typ[n, i]); # Remove parameter name
+ if (ptr[n, i] && (typ[n, i] in xlate))
+ typ[n, i] = xlate[typ[n, i]];
+ arg[n, i] = a[i];
+ sub("^([^ ]+ )+", "", arg[n, i]); # Remove parameter type
+ }
+}
+
+# Generate the output
+END {
+ # Verbatim generated lines
+ for (i = 1; i <= e; i++)
+ printf("%s\n", emit[i]);
+ printf("\n");
+ # Generate prototypes
+ for (i = 1; i <= n; i++) {
+ for (p = 1; p <= n_pre[i]; p++) {
+ printf("%s %s_%s(", rettype[pre[i, p]], pre[i, p], fn[i]);
+ if (n_args[i] == 0)
+ printf("void");
+ else
+ for (j = 1; j <= n_args[i]; j++) {
+ if (j > 1)
+ printf(", ");
+ if (ptr[i, j])
+ printf("XEN_GUEST_HANDLE_PARAM(%s)", typ[i, j]);
+ else
+ printf("%s", typ[i, j]);
+ printf(" %s", arg[i, j]);
+ }
+ printf(");\n");
+ }
+ }
+ # Generate call sequences and args array contents
+ for (ca in caller) {
+ if (caller[ca] != 1)
+ continue;
+ need_mask = 0;
+ for (pl = 1; pl <= n_prios[ca]; pl++) {
+ for (pll = pl; pll > 1; pll--) {
+ if (prio_list[ca, pl] > p_list[pll - 1])
+ break;
+ else
+ p_list[pll] = p_list[pll - 1];
+ }
+ p_list[pll] = prio_list[ca, pl];
+ # If any prio but the default one has more than 1 entry we need "mask"
+ if (p_list[pll] != 100 && prios[ca, p_list[pll]] > 1)
+ need_mask = 1;
+ }
+ printf("\n");
+ printf("#define call_handlers_%s(num, ret, a1, a2, a3, a4, a5) \\\n", ca);
+ printf("({ \\\n");
+ if (need_mask)
+ printf(" uint64_t mask = 1ULL << num; \\\n");
+ printf(" ");
+ for (pl = 1; pl <= n_prios[ca]; pl++) {
+ if (prios[ca, p_list[pl]] > 1) {
+ if (pl < n_prios[ca]) {
+ printf(" if ( likely(mask & (%s)) ) \\\n", prio_mask[ca, p_list[pl]]);
+ printf(" { \\\n");
+ }
+ if (prios[ca, p_list[pl]] == 2) {
+ fnd = 0;
+ for (i = 1; i <= nc; i++)
+ if (call[i] == ca && call_prio[i] == p_list[pl]) {
+ fnd++;
+ if (fnd == 1)
+ printf(" if ( num == __HYPERVISOR_%s ) \\\n", fn[call_fn[i]]);
+ else
+ printf(" else \\\n");
+ do_call(call_fn[i], call_p[i]);
+ }
+ } else {
+ do_switch(ca, p_list[pl]);
+ }
+ if (pl < n_prios[ca])
+ printf(" } \\\n");
+ } else {
+ for (i = 1; i <= nc; i++)
+ if (call[i] == ca && call_prio[i] == p_list[pl]) {
+ printf("if ( likely(num == __HYPERVISOR_%s) ) \\\n", fn[call_fn[i]]);
+ do_call(call_fn[i], call_p[i]);
+ }
+ }
+ if (pl < n_prios[ca] || prios[ca, p_list[pl]] <= 2)
+ printf(" else \\\n");
+ }
+ if (prios[ca, p_list[n_prios[ca]]] <= 2) {
+ printf("\\\n");
+ printf(" ret = -ENOSYS; \\\n");
+ }
+ printf("})\n");
+ delete p_list;
+ printf("\n");
+ printf("#define hypercall_args_%s \\\n", ca);
+ printf("{ \\\n");
+ for (i = 1; i <= nc; i++)
+ if (call[i] == ca)
+ printf("[__HYPERVISOR_%s] = %d, \\\n", fn[call_fn[i]], n_args[call_fn[i]]);
+ printf("}\n");
+ }
+}
--
2.26.2
next prev parent reply other threads:[~2021-12-08 15:56 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-08 15:55 [PATCH v3 00/13] xen: drop hypercall function tables Juergen Gross
2021-12-08 15:55 ` [PATCH v3 01/13] xen: move do_vcpu_op() to arch specific code Juergen Gross
2021-12-14 17:21 ` Julien Grall
2021-12-15 7:12 ` Juergen Gross
2021-12-15 9:40 ` Julien Grall
2021-12-08 15:55 ` [PATCH v3 02/13] xen: harmonize return types of hypercall handlers Juergen Gross
2021-12-14 17:36 ` Julien Grall
2021-12-15 7:03 ` Juergen Gross
2021-12-16 2:10 ` Stefano Stabellini
2021-12-16 5:13 ` Juergen Gross
2021-12-16 20:43 ` Stefano Stabellini
2021-12-16 21:15 ` Stefano Stabellini
2021-12-17 5:34 ` Juergen Gross
2021-12-17 7:45 ` Jan Beulich
2021-12-17 8:50 ` Juergen Gross
2021-12-17 10:41 ` Julien Grall
2021-12-17 11:12 ` Juergen Gross
2021-12-17 23:00 ` Stefano Stabellini
2021-12-20 17:14 ` Julien Grall
2021-12-21 0:08 ` Stefano Stabellini
2021-12-21 7:45 ` Juergen Gross
2021-12-21 9:16 ` Julien Grall
2021-12-17 7:39 ` Jan Beulich
2021-12-17 10:38 ` Julien Grall
2021-12-17 23:05 ` Stefano Stabellini
2021-12-17 10:04 ` Julien Grall
2021-12-08 15:55 ` [PATCH v3 03/13] xen: don't include asm/hypercall.h from C sources Juergen Gross
2021-12-08 15:55 ` [PATCH v3 04/13] xen: include compat/platform.h from hypercall.h Juergen Gross
2021-12-09 9:01 ` Jan Beulich
2021-12-08 15:55 ` Juergen Gross [this message]
2021-12-14 8:56 ` [PATCH v3 05/13] xen: generate hypercall interface related code Jan Beulich
2021-12-08 15:55 ` [PATCH v3 06/13] xen: use generated prototypes for hypercall handlers Juergen Gross
2021-12-08 15:56 ` [PATCH v3 07/13] x86/pv-shim: don't modify hypercall table Juergen Gross
2021-12-08 15:56 ` [PATCH v3 08/13] xen/x86: don't use hypercall table for calling compat hypercalls Juergen Gross
2021-12-08 15:56 ` [PATCH v3 09/13] xen/x86: call hypercall handlers via generated macro Juergen Gross
2021-12-08 15:56 ` [PATCH v3 10/13] xen/arm: " Juergen Gross
2021-12-08 15:56 ` [PATCH v3 11/13] xen/x86: add hypercall performance counters for hvm, correct pv Juergen Gross
2021-12-08 15:56 ` [PATCH v3 12/13] xen: drop calls_to_multicall performance counter Juergen Gross
2021-12-08 15:56 ` [PATCH v3 13/13] tools/xenperf: update hypercall names Juergen Gross
2021-12-09 9:05 ` [PATCH v3 00/13] xen: drop hypercall function tables Jan Beulich
2021-12-09 9:10 ` Juergen Gross
2021-12-13 10:35 ` Jan Beulich
2021-12-13 10:48 ` Juergen Gross
2022-03-08 8:34 ` Jan Beulich
2022-03-08 8:39 ` Juergen Gross
2022-03-08 8:50 ` Jan Beulich
2022-03-08 8:53 ` Juergen Gross
2022-03-08 12:50 ` Jan Beulich
2022-03-08 12:56 ` Juergen Gross
2022-03-08 13:42 ` Jan Beulich
2022-03-08 13:44 ` Juergen Gross
2022-03-08 13:52 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211208155606.20029-6-jgross@suse.com \
--to=jgross@suse.com \
--cc=andrew.cooper3@citrix.com \
--cc=george.dunlap@citrix.com \
--cc=jbeulich@suse.com \
--cc=julien@xen.org \
--cc=sstabellini@kernel.org \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.