[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 |