|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 07/15] xen: generate hypercall interface related code
Hi Juergen,
On 01.11.2021 16:20, Juergen Gross wrote:
> 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.
>
> Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
> ---
> V2:
> - split platform_op for doe and compat prefixes (Jan Beulich)
> - add "addline:" directive
> - add priorities to handlers (Jan Beulich)
> ---
> .gitignore | 1 +
> xen/Makefile | 10 ++
> xen/include/hypercall-defs.c | 285 +++++++++++++++++++++++++++++++
> xen/scripts/gen_hypercall.awk | 306 ++++++++++++++++++++++++++++++++++
> 4 files changed, 602 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/Makefile b/xen/Makefile
> index a3189eb47c..dfdae47e74 100644
> --- a/xen/Makefile
> +++ b/xen/Makefile
> @@ -383,6 +383,7 @@ _clean: delete-unfresh-files
> -o -name "*.gcno" -o -name ".*.cmd" -o -name "lib.a" \) -exec
> rm -f {} \;
> rm -f include/asm $(TARGET) $(TARGET).gz $(TARGET).efi
> $(TARGET).efi.map $(TARGET)-syms $(TARGET)-syms.map *~ core
> rm -f asm-offsets.s include/asm-*/asm-offsets.h
> + rm -f include/xen/hypercall-defs.h include/hypercall-defs.i
> rm -f .banner .allconfig.tmp
>
> .PHONY: _distclean
> @@ -405,6 +406,7 @@ $(TARGET): delete-unfresh-files
> $(MAKE) -f $(BASEDIR)/Rules.mk -C include
> $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) include
> $(MAKE) -f $(BASEDIR)/Rules.mk include/asm-$(TARGET_ARCH)/asm-offsets.h
> + $(MAKE) -f $(BASEDIR)/Rules.mk include/xen/hypercall-defs.h
> $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) $@
>
> # drivers/char/console.o contains static banner/compile info. Blow it away.
> @@ -466,6 +468,14 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h: asm-offsets.s
> echo ""; \
> echo "#endif") <$< >$@
>
> +quiet_cmd_genhyp = GEN $@
> +define cmd_genhyp
> + awk -f scripts/gen_hypercall.awk <$< >$@
> +endef
> +
> +include/xen/hypercall-defs.h: include/hypercall-defs.i
> scripts/gen_hypercall.awk FORCE
> + $(call if_changed,genhyp)
> +
> SUBDIRS = xsm arch/$(TARGET_ARCH) common drivers lib test
> define all_sources
> ( find include/asm-$(TARGET_ARCH) -name '*.h' -print; \
> diff --git a/xen/include/hypercall-defs.c b/xen/include/hypercall-defs.c
> new file mode 100644
> index 0000000000..67f6081558
> --- /dev/null
> +++ b/xen/include/hypercall-defs.c
> @@ -0,0 +1,285 @@
> +/*
> + * 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>)".
> + *
> + * A verbatim line can be added via:
> + * addline: <line-contents>
> + * Its position is kept in regard of other "handle:" and "defhandle:" lines.
> + *
> + * 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
> +addline: typedef struct compat_platform_op compat_platform_op_t;
> +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..26017c0900
> --- /dev/null
> +++ b/xen/scripts/gen_hypercall.awk
> @@ -0,0 +1,306 @@
> +# 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 "addline:" line
> +$1 == "addline:" {
> + if (NF < 2)
> + do_err("\"addline:\" requires at least one parameter");
> + e++;
> + emit[e] = rest_of_line(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;
> + for (pl = 1; pl <= n_prios[ca]; pl++)
> + p_list[pl] = prio_list[ca, pl];
> + asort(p_list, p_list, "@val_num_asc");
Just to let you know:
asort is a gawk built-in. I was trying to build your changes on my aarch64
chroot environment.
I did not have gawk installed and I got an error when building xen:
make[4]: Leaving directory '/home/micorz01/xen_main/xen/include'
GEN include/xen/hypercall-defs.h
awk: scripts/gen_hypercall.awk: line 308: function asort never defined
Makefile:477: recipe for target 'include/xen/hypercall-defs.h' failed
During configure step I did not get any failure that gawk is not installed.
If you are making use of gawk built-ins, shouldn't configure test for it?
> + need_mask = 0;
> + # If any prio but the default one has more than 1 entry we need
> "mask"
> + for (pl = 1; pl < n_prios[ca]; pl++) {
> + if (prios[ca, p_list[pl]] > 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");
> + 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");
> + }
> + 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]]);
> + printf(" { \\\n");
> + do_call(call_fn[i], call_p[i]);
> + printf(" } \\\n");
> + }
> + }
> + if (pl < n_prios[ca] || prios[ca, pl] == 1)
> + printf(" else ");
> + }
> + if (prios[ca, p_list[n_prios[ca]]] == 1) {
> + printf("\\\n");
> + printf(" ret = -ENOSYS; \\\n");
> + }
> + printf("}\n");
> + 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");
> + }
> +}
>
Cheers,
Michal
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |