├── README.md ├── msr ├── end-to-end-msr.sh ├── manual_setup.md ├── msr-driver-changes.patch ├── msr-idl-changes.patch ├── msr_autogen │ ├── Kbuild │ ├── boot │ │ ├── Kbuild │ │ └── main.c │ ├── glue_user.c │ ├── glue_user.h │ ├── msr_klcd │ │ ├── Kbuild │ │ └── main.c │ └── msr_lcd │ │ ├── Kbuild │ │ ├── main.c │ │ └── msr.c └── toggle_ht.sh ├── table4 ├── manual_setup.md └── table4.sh └── table_3_IDL ├── edac ├── sb_edac.idl └── skx_edac.idl └── net ├── alx.idl ├── ixgbe.idl └── null_net.idl /README.md: -------------------------------------------------------------------------------- 1 | # Artifact Evaluation - OSDI'22 2 | 3 | Thank you for your time and picking our paper for the artifact evaluation. 4 | 5 | This documentation contains steps necessary to reproduce the artifacts for our 6 | paper titled **KSplit: Automating Device Driver Isolation**. 7 | 8 | All the experiments are evaluated on a Dell PowerEdge R820 machine on the 9 | [Emulab Infrastructure](https://www.emulab.net/apt/show-hardware.php?type=d820) 10 | 11 | ## Setting up the hardware 12 | 13 | * Create an account on [Cloudlab](https://www.cloudlab.us/) and login. 14 | 15 | ### Configuring the experiment 16 | 17 | #### Automated setup 18 | * The easiest way to setup our experiment is to use "Repository based profile". 19 | 20 | * Create an experiment profile by selecting 21 | `Experiments > Create Experiment profile` 22 | 23 | * Select `Git Repo` and use this repository. The profile comes pre-installed 24 | with source code for evaluating ksplit's static analysis. 25 | ``` 26 | https://github.com/ksplit/ksplit-cloudlab 27 | ``` 28 | * Populate the name field and click `Create` 29 | 30 | * If successful, instantiate the created profile by clicking `Instantiate` 31 | button on the left pane. 32 | 33 | * *NOTE* You can select different branches on the git repository. Please select 34 | `master` branch. 35 | 36 | * For a more descriptive explanation and its inner details, consult the 37 | cloudlab documentation on [repo based profiles](https://docs.cloudlab.us/creating-profiles.html#(part._repo-based-profiles) 38 | 39 | * The profile git repository contains a bootstrapping script which 40 | automatically clones and builds the following repositories, upon a successful bootup of the node. 41 | - `pdg` - Static analyses 42 | - `lvd-linux` - modified LVDs kernel 43 | - `bflank` - modified bareflank hypervisor 44 | - `bc-files` - llvm bit-code files for driver modules 45 | 46 | * Please allow sometime to clone and build all the source code. You can check 47 | the progress by tailing the log file. 48 | 49 | * A short log is located at `/users/geniuser/ksplit-setup.log`. If the setup is 50 | successful, the short log should contain something similar to the one below 51 | ``` 52 | [Thu Apr 14 00:55:13 CDT 2022] Begin setup! 53 | [Thu Apr 14 00:55:13 CDT 2022] Installing dependencies... 54 | [Thu Apr 14 00:55:21 CDT 2022] Downloading llvm script to /users/geniuser/llvm.sh 55 | [Thu Apr 14 00:55:28 CDT 2022] Preparing local partition ... 56 | [Thu Apr 14 00:55:39 CDT 2022] Cloning PDG 57 | [Thu Apr 14 00:55:39 CDT 2022] Cloning Bareflank 58 | [Thu Apr 14 00:55:40 CDT 2022] Cloning LVD linux 59 | [Thu Apr 14 00:57:14 CDT 2022] Cloning bc-files 60 | [Thu Apr 14 01:07:51 CDT 2022] Building SVF 61 | [Thu Apr 14 01:07:51 CDT 2022] Building PDG 62 | [Thu Apr 14 01:07:52 CDT 2022] Building bareflank 63 | [Thu Apr 14 01:10:41 CDT 2022] Building Linux 64 | [Thu Apr 14 01:15:46 CDT 2022] Building lcd-domains 65 | [Thu Apr 14 01:18:56 CDT 2022] Done Setting up! 66 | ``` 67 | 68 | * A detailed log is available at `/users/geniuser/ksplit-verbose.log` 69 | 70 | * The script that gets executed after startup is available 71 | [here](https://github.com/ksplit/ksplit-cloudlab/blob/ksplit-test/ksplit-top.sh) 72 | 73 | * *NOTE* The automated script is executed by a different user (`geniuser`). If 74 | you need to manually build something under `/opt/ksplit` make sure to change 75 | ownership. 76 | ``` 77 | pushd /opt/ksplit 78 | sudo chown -R : . 79 | ``` 80 | 81 | #### Manual setup 82 | * If you want to set up the source repos manually for some reason, 83 | ``` 84 | mkdir /local 85 | # make sure you have permissions or use chown 86 | git clone https://github.com/ksplit/ksplit-cloudlab.git /local/respository 87 | # invoke the top level script 88 | /local/respository/ksplit-top.sh 89 | ``` 90 | 91 | ## Experiments 92 | 93 | ### Prerequisites 94 | * The following steps assume that the experiment profile is created using the 95 | aforementioned steps (i.e., using the git repo for creating the profile). 96 | 97 | * To create this setup manually, 98 | - Clone https://github.com/ksplit/ksplit-cloudlab 99 | - Make sure `/opt/ksplit` is writable 100 | - Execute `ksplit-top.sh` 101 | 102 | ### Building KSplit Static Analyses 103 | * The pdg sources should automatically be built for you. If not, refer to the 104 | Prerequisites subsection above to set it up manually. 105 | 106 | * Clone the artifacts repository in your `${HOME}` directory. The scripts have 107 | this path hardcoded. 108 | ``` 109 | cd ${HOME} 110 | git clone https://github.com/ksplit/ksplit-artifacts.git 111 | ``` 112 | 113 | ### Table 1.a - 1.e Replication 114 | 115 | * To replicate Table1 from the paper, please invoke this script which runs the 116 | analyses, collects the results and present it in a csv file. 117 | ```bash 118 | cd /opt/ksplit/bc-files 119 | ./run_benchmarks.sh table1 120 | ``` 121 | 122 | * The above step runs the analysis in the background and should take 1-2 hours 123 | to complete. If successful, the results for table1 should be available in 124 | `/opt/ksplit/bc-files/benchmark_stats/merged_stats.csv`. The format is 125 | similar to our Table1 on paper. Inorder to visually compare, one can paste 126 | the `merged_stats.csv` into a csv viewer (e.g., google sheets). 127 | 128 | * The remaining numbers (1.f - 1.g) are part of the manual effort. 129 | Unfortunately, we do not have an automated way to replicate these numbers as 130 | many of them requires domain knowledge (IDL syntax, understanding kernel - 131 | driver interaction patterns to classify pointer misclassifications etc). 132 | 133 | ### Table 2 (Subsystem stats) 134 | 135 | * Similar to Table1, Table2 script can be invoked with, 136 | ```bash 137 | cd /opt/ksplit/bc-files 138 | ./run_benchmarks.sh table2 139 | ``` 140 | This script runs the analyses for the subsystems listed under 141 | `/opt/ksplit/bc-files/subsystems_list` collects the results and present it in 142 | a csv file. 143 | 144 | * The above snippet should take around 5-6 hours to finish. Upon completion, 145 | running the below script would accumulate summarize all the individual stats 146 | into a summary file for the subsystem. To cut down on the total time, we 147 | picked only a few subsystems out of the whole list, namely block, edac, hwmon 148 | and usb. However, the same steps can be used to collect metrics for all the 149 | available subsystems under our `bc-files` repository. 150 | 151 | * If successful, the script generates a merged csv file at 152 | `/opt/ksplit/bc-files/benchmark_stats/table2/merged_stats_table2.csv` 153 | 154 | ### Table 3 (Similarity) 155 | ```bash 156 | cd table_3_IDL/net/ 157 | cd table_3_IDL/edac/ 158 | ``` 159 | Compare the IDL between `ixgbe`, `null_net` and `alx`. 160 | Compare the IDL between `skx_edac` and `sb_edac`. 161 | 162 | > Counting method: 163 | - **Shared rpc comparison**: compare rpc stubs (function start with rpc/rpc_ptr) among the IDLs and count the common ones. 164 | - **Shared rpcs IDL delta**: compare the rpc stubs and count the different ones. 165 | - **Shared rpcs Annotation**: compare the annotations among the IDLs and count the differences. 166 | - **New IDL**: Count the IDL difference between the referenced IDL and the comparison IDL. The IDLs exist in the compared IDL but do not exist in the referenced IDL are considered as new IDL. For example, the referenced IDL is ixgbe and the null_net IDL is used for comparison. Then, we go through the IDL code in the null_net IDL and then find the part of code that are not exist in the ixgbe. The lines of these code are counted as new IDL. 167 | 168 | 169 | ### Table 4 170 | 171 | * Make sure you have cloned the artifacts repo in your `${HOME}` folder. The script should 172 | output the numbers from `dmesg` in csv format. 173 | ``` 174 | cd ${HOME} 175 | cd ksplit-artifacts/table4 176 | ./table4.sh 177 | ``` 178 | 179 | *NOTE:* There are some known issues in loading two LVD modules at the same time 180 | or back-to-back. To avoid these troubles and to have a clean setup, please reboot 181 | before loading the second test module. 182 | 183 | ### End-to-End examples 184 | 185 | #### `msr` driver 186 | 187 | `msr` driver is located at `/opt/ksplit/lvd-linux/arch/x86/kernel/msr.c` 188 | 189 | * The push-button script does the following 190 | * Generates the IDL file from `msr.ko.bc` and `msr_kernel.bc` 191 | * Patch the IDL and driver 192 | * Load and test by reading/writing to `/dev/cpu/x/msr` 193 | 194 | * invoke the script 195 | ``` 196 | cd ${HOME}/ksplit-artifacts/msr 197 | ./end-to-end-msr.sh 198 | ``` 199 | 200 | * The script performs a read, write and a read back from the msr device file. 201 | Upon successful execution, you should see this message at the end 202 | ``` 203 | ===================================== 204 | Autogenerated msr module test passed 205 | ===================================== 206 | ``` 207 | 208 | ### Figure 4 209 | 210 | At the moment, this artifact package does not contain the scripts necessary for 211 | replicating the memcached benchmarks. It is still a work in progress. 212 | 213 | ### Approximate running time 214 | 215 | Here is an estimate for how long it takes to replicate each benchmark 216 | 217 | * setup -> 30-40 minutes (one-time) 218 | * table1 -> ~1 hour 219 | * table2 -> 5-6 hours 220 | * table3 -> 1-2 hours (manual effort) 221 | * table4 -> 10-20 minutes 222 | * End-to-End example -> 1-2 hours 223 | -------------------------------------------------------------------------------- /msr/end-to-end-msr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ARTIFACTS_HOME="${HOME}/ksplit-artifacts" 4 | MSR_ARTIFACT="${ARTIFACTS_HOME}/msr" 5 | MSR_BOILERPLATE="${MSR_ARTIFACT}/msr_autogen" 6 | 7 | BASE_DIR="/opt/ksplit" 8 | BCFILES="${BASE_DIR}/bc-files" 9 | MSR_BC="${BCFILES}/arch_x86/msr/" 10 | 11 | BFLANK_BUILD="${BASE_DIR}/bflank/build" 12 | 13 | LVD_LINUX="${BASE_DIR}/lvd-linux" 14 | LVD_DOMAINS="${LVD_LINUX}/lcd-domains" 15 | TEST_MODS="${LVD_DOMAINS}/test_mods" 16 | 17 | MSR_AUTOGEN_BUILD_DIR="${LVD_DOMAINS}/build/test_mods/msr_autogen" 18 | BOOT_KO="${MSR_AUTOGEN_BUILD_DIR}/boot/lcd_test_mod_msr_autogen_boot.ko" 19 | KLCD_KO="${MSR_AUTOGEN_BUILD_DIR}/msr_klcd/lcd_test_mod_msr_autogen_msr_klcd.ko" 20 | LCD_KO="${MSR_AUTOGEN_BUILD_DIR}/msr_lcd/lcd_test_mod_msr_autogen_msr_lcd.ko" 21 | 22 | IDLC_BIN="${BASE_DIR}/lcds-idl/build/idlc" 23 | 24 | chown() { 25 | USER=$(id -u -n) 26 | GROUP=$(id -g -n) 27 | sudo chown -R ${USER}:${GROUP} ${BASE_DIR} 28 | } 29 | 30 | generate_idl() { 31 | pushd ${MSR_BC} 32 | sudo ../../run_nescheck.sh msr 33 | # Yeah I know 34 | sleep 60 35 | popd 36 | } 37 | 38 | autogen_module() { 39 | pushd ${TEST_MODS} 40 | cp -a ${MSR_BOILERPLATE} . 41 | pushd msr_autogen 42 | cp ${MSR_BC}/kernel.idl msr_autogen.idl 43 | patch -p0 < ${MSR_ARTIFACT}/msr-idl-changes.patch 44 | ${IDLC_BIN} ./msr_autogen.idl 45 | popd 46 | popd 47 | } 48 | 49 | prepare_module() { 50 | pushd ${TEST_MODS} 51 | rm -f ${TEST_MODS}/config 52 | DEFCONFIG="${LVD_DOMAINS}/scripts/defaultconfig" 53 | echo "msr_autogen/boot nonisolated" >> ${DEFCONFIG} 54 | echo "msr_autogen/msr_lcd isolated" >> ${DEFCONFIG} 55 | echo "msr_autogen/msr_klcd nonisolated" >> ${DEFCONFIG} 56 | 57 | echo "obj-m += msr_autogen/" >> "${LVD_DOMAINS}/scripts/Kbuild.test_mods" 58 | 59 | patch -p0 < "${MSR_ARTIFACT}/msr-driver-changes.patch" 60 | popd 61 | } 62 | 63 | build_module() { 64 | pushd ${LVD_DOMAINS} 65 | make 66 | 67 | if [[ ! -n ${BOOT_KO} ]] || [[ ! -n ${KLCD_KO} ]] || [[ ! -n ${LCD_KO} ]];then 68 | echo "Building autogenerated module failed" 69 | else 70 | echo "Module successfully built" 71 | fi 72 | popd 73 | } 74 | 75 | load_bflank_module() { 76 | sudo ${MSR_ARTIFACT}/toggle_ht.sh off 77 | pushd "${BFLANK_BUILD}" 78 | make driver_quick && make quick 79 | popd 80 | } 81 | 82 | load_module() { 83 | load_bflank_module; 84 | pushd ${LVD_DOMAINS} 85 | ./scripts/mk 86 | sleep 5; 87 | ./scripts/loadex msr_autogen 88 | # allow some time for the module to get loaded 89 | sleep 120; 90 | popd 91 | } 92 | 93 | test_module() { 94 | if ! [ -x "$(command -v rdmsr)" ]; then 95 | echo "Installing msr-tools ..." 96 | sudo apt update 97 | sudo apt install -y msr-tools 98 | fi 99 | RDMSR_BIN=$(which rdmsr) 100 | WRMSR_BIN=$(which wrmsr) 101 | 102 | sudo ${RDMSR_BIN} 0x1a4 103 | sudo ${WRMSR_BIN} 0x1a4 0xf 104 | READ_BACK=$(sudo ${RDMSR_BIN} 0x1a4) 105 | 106 | if [[ ${READ_BACK} == "f" ]]; then 107 | echo "====================================="; 108 | echo "Autogenerated msr module test passed"; 109 | echo "====================================="; 110 | else 111 | echo "Failed to readback the written value from msr"; 112 | fi 113 | } 114 | 115 | chown 116 | generate_idl 117 | autogen_module 118 | prepare_module 119 | 120 | build_module 121 | load_module 122 | test_module 123 | -------------------------------------------------------------------------------- /msr/manual_setup.md: -------------------------------------------------------------------------------- 1 | *NOTE:* 2 | For the push-button script, execute `end-to-end-msr.sh`. Please look for instructions in the top-level `README.md 3 | 4 | ## Detailed manual setup 5 | 6 | 1) First step is to gather the bc files. For performing the analysis, we need 7 | two bc files, `msr_driver.bc` and `msr_kernel.bc`. The bc files for msr are 8 | available at `/opt/ksplit/bc-files/arch_x86/msr/` 9 | 10 | 2) Run static analysis to generate the idl. 11 | ```bash 12 | pushd /opt/ksplit/bc-files/arch_x86/msr/ 13 | sudo bash ../../run_nescheck.sh msr 14 | popd 15 | ``` 16 | 17 | 3) Create a new test module folder in `lvd-linux` and copy the generated IDL 18 | ``` 19 | pushd /opt/ksplit/lvd-linux/lcd-domains/test_mods 20 | mkdir msr_autogen 21 | # copy the auto generated idl here 22 | cp /opt/ksplit/bc-files/arch_x86/msr/kernel.idl msr_autogen.idl 23 | ``` 24 | 25 | 4) Patch the auto generated IDL that require manual intervention. 26 | ``` 27 | patch -p0 < msr-idl-changes.patch 28 | ``` 29 | 30 | 5) Generate rpc stubs. If successful, this should generate `common.{c,h}`, 31 | `client.c`, `server.c` and a linker script. 32 | ``` 33 | /opt/ksplit/lcds-idl/build/idlc ./msr_autogen.idl 34 | ``` 35 | 6) Create entries in the configuration script and Kbuild. 36 | - Add config entry to `/opt/ksplit/lvd-linux/lcd-domains/scripts/defaultconfig` 37 | ``` 38 | msr_autogen/boot nonisolated 39 | msr_autogen/msr_lcd isolated 40 | msr_autogen/msr_klcd nonisolated 41 | ``` 42 | 43 | - Add Kbuild entry to `/opt/ksplit/lvd-linux/lcd-domains/scripts/Kbuild.test_mods` 44 | ``` 45 | obj-m += msr_autogen/ 46 | ``` 47 | 48 | 7) The isolated module needs a bunch of boilerplate code to bootstrap. All the 49 | necessary files are available in this repo under `msr/msr_autogen` folder. After 50 | the above steps, you can copy all the files under `msr/msr_autogen` to the 51 | directory created in step2. 52 | 53 | *NOTE* The boilerplate code assumes that the directory created is named 54 | `msr_autogen`. If you have created it with some other name, it needs to be 55 | reflected in the boilerplate code. 56 | 57 | - Before compiling the module, a few lines need to be patched in the auto-generated code. 58 | The patch is located at `msr/msr-driver-changes.patch`. 59 | 60 | ``` 61 | cd /opt/ksplit/lvd-linux/lcd-domains/test_mods 62 | patch -p0 < msr/msr-driver-changes.patch 63 | ``` 64 | 65 | 8) Compile the newly auto-generated module 66 | ``` 67 | cd /opt/ksplit/lvd-linux/lcd-domains/ 68 | rm test_mods/config 69 | make test_mods 70 | ``` 71 | 72 | 9) Load the hypervisor. Follow step 2 under Table4 experiments above 73 | 74 | 10) Load the microkernel and msr_autogen 75 | ``` 76 | cd /opt/ksplit/lvd-linux/lcd-domains/ 77 | ./scripts/mk 78 | ./scripts/loadex msr_autogen 79 | ``` 80 | 81 | 11) Test the msr driver 82 | ``` 83 | sudo apt install msr-tools 84 | # This should trigger an msr read through the isolated driver 85 | sudo rdmsr 0x1a4 86 | ``` 87 | -------------------------------------------------------------------------------- /msr/msr-driver-changes.patch: -------------------------------------------------------------------------------- 1 | diff -Naur msr_autogen.orig/client.c msr_autogen/client.c 2 | --- msr_autogen.orig/client.c 2022-05-20 09:00:44.944356033 -0500 3 | +++ msr_autogen/client.c 2022-05-20 04:47:17.828444811 -0500 4 | @@ -4,6 +4,8 @@ 5 | 6 | #include 7 | 8 | +volatile unsigned long jiffies; 9 | + 10 | struct class* __class_create(struct module* owner, char const* name, struct lock_class_key* key) 11 | { 12 | struct fipc_message __buffer = {0}; 13 | @@ -469,7 +471,7 @@ 14 | } 15 | } 16 | 17 | -struct device* device_create(struct class* class, struct device* parent, unsigned int devt, void* drvdata, char const* fmt, unsigned int cpu) 18 | +struct device* __device_create(struct class* class, struct device* parent, unsigned int devt, void* drvdata, char const* fmt, unsigned int cpu) 19 | { 20 | struct fipc_message __buffer = {0}; 21 | struct fipc_message *__msg = &__buffer; 22 | @@ -1477,11 +1479,16 @@ 23 | return ret; 24 | } 25 | 26 | +void __init_globals(void) { 27 | + jiffies = get_jiffies(); 28 | +} 29 | + 30 | int try_dispatch(enum RPC_ID id, struct fipc_message* __msg, struct ext_registers* __ext) 31 | { 32 | switch(id) { 33 | case MODULE_INIT: 34 | glue_user_trace("MODULE_INIT"); 35 | + __init_globals(); 36 | __module_lcd_init(); 37 | shared_mem_init(); 38 | break; 39 | diff -Naur msr_autogen.orig/common.h msr_autogen/common.h 40 | --- msr_autogen.orig/common.h 2022-05-20 09:00:44.934355864 -0500 41 | +++ msr_autogen/common.h 2022-05-20 08:26:14.582748670 -0500 42 | @@ -32,7 +32,7 @@ 43 | 44 | #ifndef LCD_ISOLATE 45 | #define glue_unpack_rpc_ptr(pos, msg, ext, name) \ 46 | - glue_peek(pos, msg, ext) ? (fptr_##name)glue_unpack_rpc_ptr_impl(glue_unpack(pos, msg, ext, void*), LCD_DUP_TRAMPOLINE(trmp_##name), LCD_TRAMPOLINE_SIZE(trmp_##name)) : NULL 47 | + (fptr_##name)glue_unpack_rpc_ptr_impl(glue_unpack(pos, msg, ext, void*), LCD_DUP_TRAMPOLINE(trmp_##name), LCD_TRAMPOLINE_SIZE(trmp_##name)) 48 | 49 | #else 50 | #define glue_unpack_rpc_ptr(pos, msg, ext, name) NULL; glue_user_panic("Trampolines cannot be used on LCD side") 51 | @@ -153,34 +153,43 @@ 52 | 53 | static inline void glue_mark_visited(struct glue_visit_list* visited, const void* ptr) 54 | { 55 | +#if 0 56 | if (visited->size + 1 > visited->capacity) { 57 | visited->capacity *= 2; 58 | visited->values = krealloc(visited->values, visited->capacity * sizeof(void*), GFP_KERNEL); 59 | } 60 | 61 | visited->values[visited->size++] = ptr; 62 | +#endif 63 | } 64 | 65 | static inline struct glue_visit_list glue_create_visit_list(void) 66 | { 67 | struct glue_visit_list visited = {0}; 68 | +#if 0 69 | visited.capacity = 1; 70 | visited.values = kzalloc(sizeof(void*), GFP_KERNEL); 71 | +#endif 72 | return visited; 73 | } 74 | 75 | static inline void glue_free_visit_list(struct glue_visit_list* visited) 76 | { 77 | +#if 0 78 | kfree(visited->values); 79 | +#endif 80 | } 81 | 82 | static inline void glue_clear_visit_list(struct glue_visit_list* visited) 83 | { 84 | +#if 0 85 | visited->size = 0; 86 | +#endif 87 | } 88 | 89 | static inline bool glue_should_visit(struct glue_visit_list* visited, const void* ptr) 90 | { 91 | +#if 0 92 | int i; 93 | if (!ptr) 94 | return 0; 95 | @@ -192,6 +201,7 @@ 96 | 97 | glue_mark_visited(visited, ptr); 98 | 99 | +#endif 100 | return 1; 101 | } 102 | 103 | diff -Naur msr_autogen.orig/server.c msr_autogen/server.c 104 | --- msr_autogen.orig/server.c 2022-05-20 09:00:44.944356033 -0500 105 | +++ msr_autogen/server.c 2022-05-20 04:47:17.828444811 -0500 106 | @@ -484,7 +484,7 @@ 107 | return impl(target, dev, mode); 108 | } 109 | 110 | -void device_create_callee(struct fipc_message* __msg, struct ext_registers* __ext) 111 | +void __device_create_callee(struct fipc_message* __msg, struct ext_registers* __ext) 112 | { 113 | size_t n_pos = 0; 114 | size_t* __pos = &n_pos; 115 | @@ -1588,7 +1588,7 @@ 116 | 117 | case RPC_ID_device_create: 118 | glue_user_trace("device_create\n"); 119 | - device_create_callee(__msg, __ext); 120 | + __device_create_callee(__msg, __ext); 121 | break; 122 | 123 | case RPC_ID_device_destroy: 124 | -------------------------------------------------------------------------------- /msr/msr-idl-changes.patch: -------------------------------------------------------------------------------- 1 | --- msr_autogen.idl 2022-04-15 13:56:17.326306100 -0600 2 | +++ msr_manual.idl 2022-04-15 13:57:15.811640073 -0600 3 | @@ -1,89 +1,106 @@ 4 | // Sync stubs for boundary functions 5 | module kernel { 6 | -rpc projection ret_class* __class_create( projection module *owner, char *name, projection lock_class_key *key ) { 7 | +rpc projection ret_class [alloc(caller)] * __class_create( projection module [alloc(callee)] * owner, string [alloc(callee)]* name, projection lock_class_key [alloc(callee)] * key ) { 8 | projection < struct class > ret_class { 9 | - char* [out] name; 10 | + string [alloc(caller), out] *name; 11 | } 12 | projection < struct module > module { 13 | } 14 | projection < struct lock_class_key > lock_class_key { 15 | } 16 | } 17 | -rpc int __register_chrdev( unsigned int major, unsigned int baseminor, unsigned int count, string *name, projection _global_file_operations [in] fops ) { 18 | +rpc int __register_chrdev( unsigned int major, unsigned int baseminor, unsigned int count, string [alloc(callee)] * name, const projection _global_file_operations [alloc(callee)] * fops ) { 19 | } 20 | -rpc void __unregister_chrdev( unsigned int major, unsigned int baseminor, unsigned int count, char [unused] *name ) { 21 | +rpc void __unregister_chrdev( unsigned int major, unsigned int baseminor, unsigned int count, string * [unused] name ) { 22 | } 23 | rpc bool capable( int cap ) { 24 | } 25 | rpc void class_destroy( projection class [in] *cls ) { 26 | projection < struct class > class { 27 | - char* [in] name; 28 | + //char* [in] name; 29 | } 30 | } 31 | rpc void cpu_maps_update_begin( ) { 32 | } 33 | rpc void cpu_maps_update_done( ) { 34 | } 35 | -rpc projection ret_device* device_create( projection class *class, projection device *parent, unsigned int devt, void *drvdata, char *fmt ) { 36 | +rpc_ptr array [alloc(caller)] * devnode( projection device [alloc(callee)] *dev, unsigned short * [unused] mode ) { 37 | + projection device { 38 | + unsigned int devt; 39 | + } 40 | +} 41 | + 42 | +rpc projection ret_device [bind(caller)] * device_create( projection class* class, projection device [alloc(callee)] * parent, unsigned int devt, void* [unused] drvdata, string [alloc(callee)] * fmt, u32 cpu) { 43 | projection < struct device > ret_device { 44 | } 45 | projection < struct class > class { 46 | + rpc_ptr devnode devnode; 47 | } 48 | projection < struct device > device { 49 | } 50 | } 51 | -rpc void device_destroy( projection class [in] *class, unsigned int [unused] devt ) { 52 | +rpc void device_destroy( projection class* [in] class, unsigned int [unused] devt ) { 53 | projection < struct class > class { 54 | - char* [in] name; 55 | + //char* [in] name; 56 | } 57 | } 58 | -rpc int rdmsr_safe_on_cpu( unsigned int cpu, unsigned int msr_no, unsigned int [out] *l, unsigned int [out] *h ) { 59 | -} 60 | -rpc int rdmsr_safe_regs_on_cpu( unsigned int cpu, unsigned int *regs ) { 61 | +rpc int rdmsr_safe_on_cpu( unsigned int cpu, unsigned int msr_no, unsigned int [alloc(callee), out] * l, unsigned int [alloc(callee), out] * h ) { 62 | } 63 | -rpc void warn_slowpath_fmt( char *file, int line, char *fmt ) { 64 | +rpc int rdmsr_safe_regs_on_cpu( unsigned int cpu, array [alloc(callee), in, out] * regs ) { 65 | } 66 | +/*rpc void warn_slowpath_fmt( char* file, int line, char* fmt ) { 67 | +}*/ 68 | rpc int wrmsr_safe_on_cpu( unsigned int cpu, unsigned int msr_no, unsigned int l, unsigned int h ) { 69 | } 70 | -rpc int wrmsr_safe_regs_on_cpu( unsigned int cpu, unsigned int *regs ) { 71 | +rpc int wrmsr_safe_regs_on_cpu( unsigned int cpu, array [alloc(callee), in, out] *regs ) { 72 | +} 73 | +rpc long long no_seek_end_llseek( projection file * file, long long offset, int whence ) { 74 | + projection < struct file > file { 75 | + unsigned int [in] f_mode; 76 | + u64 [in,out] f_pos; 77 | + u64 [out] f_version; 78 | + } 79 | } 80 | -rpc u64 no_seek_end_llseek( projection file [in] *file, u64 offset, int whence ) { 81 | + 82 | +rpc_ptr s64 llseek( projection file [alloc(callee)] * file, s64 offset, int whence ) { 83 | projection < struct file > file { 84 | unsigned int [in] f_mode; 85 | u64 [in,out] f_pos; 86 | u64 [out] f_version; 87 | } 88 | + 89 | } 90 | -rpc_ptr u64 msr_read( projection file [in] *file, char [in,user<{{8}}>] *buf, u64 count, u64 [in] *ppos ) { 91 | + 92 | +rpc_ptr u64 msr_read( projection file [alloc(callee)] * file, array [alloc(callee), in, out] *buf, u64 count, u64 [alloc(callee)] * ppos ) { 93 | projection < struct file > file { 94 | - projection file_inode* f_inode; 95 | + projection file_inode [alloc(callee)]* f_inode; 96 | } 97 | projection < struct inode > file_inode { 98 | unsigned int [in] i_rdev; 99 | } 100 | } 101 | -rpc_ptr u64 msr_write( projection file [in] *file, char [in,user<{{8}}>] *buf, u64 count, u64 [in] *ppos ) { 102 | +rpc_ptr u64 msr_write( projection file [alloc(callee)] * file, array [alloc(callee), in, out] *buf, u64 count, u64 [alloc(callee)]* ppos ) { 103 | projection < struct file > file { 104 | - projection file_inode* f_inode; 105 | + projection file_inode [alloc(callee)]* f_inode; 106 | } 107 | projection < struct inode > file_inode { 108 | unsigned int [in] i_rdev; 109 | } 110 | } 111 | -rpc_ptr u64 msr_ioctl( projection file [in] *file, unsigned int ioc, u64 arg ) { 112 | +rpc_ptr u64 msr_ioctl( projection file [alloc(callee)] * file, unsigned int ioc, u64 arg ) { 113 | projection < struct file > file { 114 | - projection file_inode* f_inode; 115 | + projection file_inode [alloc(callee)]* f_inode; 116 | unsigned int [in] f_mode; 117 | } 118 | projection < struct inode > file_inode { 119 | unsigned int [in] i_rdev; 120 | } 121 | } 122 | -rpc_ptr int msr_open( projection inode [unused] *inode, projection file [in] *file ) { 123 | +rpc_ptr int msr_open( projection inode [alloc(callee)] * inode, projection file [alloc(callee)] * file ) { 124 | projection < struct inode > inode { 125 | } 126 | projection < struct file > file { 127 | - projection file_inode* f_inode; 128 | + projection file_inode [alloc(callee)]* f_inode; 129 | } 130 | projection < struct inode > file_inode { 131 | unsigned int [in] i_rdev; 132 | @@ -95,8 +112,8 @@ 133 | rpc_ptr msr_open open; 134 | rpc_ptr msr_read read; 135 | rpc_ptr msr_write write; 136 | - rpc_ptr no_seek_end_llseek llseek; 137 | + rpc_ptr llseek llseek; 138 | } 139 | - 140 | - 141 | + rpc unsigned long get_jiffies() { 142 | + } 143 | } 144 | -------------------------------------------------------------------------------- /msr/msr_autogen/Kbuild: -------------------------------------------------------------------------------- 1 | obj-$(LCD_CONFIG_BUILD_MSR_AUTOGEN_BOOT) += boot/ 2 | 3 | obj-$(LCD_CONFIG_BUILD_MSR_AUTOGEN_MSR_LCD) += msr_lcd/ 4 | 5 | obj-$(LCD_CONFIG_BUILD_MSR_AUTOGEN_MSR_KLCD) += msr_klcd/ 6 | -------------------------------------------------------------------------------- /msr/msr_autogen/boot/Kbuild: -------------------------------------------------------------------------------- 1 | obj-m += lcd_test_mod_msr_autogen_boot.o 2 | 3 | 4 | lcd_test_mod_msr_autogen_boot-y += main.o 5 | 6 | ccflags-y += $(NONISOLATED_CFLAGS) 7 | -------------------------------------------------------------------------------- /msr/msr_autogen/boot/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * boot.c - non-isolated kernel module, does setup of klcd and launch the lcd 3 | * module in an isolated container 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #define ISOLATED_MODULE_NAME "msr" 18 | 19 | cptr_t msr_klcd, msr_lcd; 20 | struct lcd_create_ctx *msr_ctx; 21 | static unsigned int bind_cpu = 2; 22 | 23 | module_param(bind_cpu, uint, 0644); 24 | MODULE_PARM_DESC(bind_cpu, "Bind kthread to this cpu"); 25 | 26 | static int boot_main(void) 27 | { 28 | int ret; 29 | struct module *m = NULL; 30 | 31 | /* 32 | * Enter lcd mode 33 | */ 34 | ret = lcd_enter(); 35 | if (ret) { 36 | LIBLCD_ERR("lcd enter failed"); 37 | goto fail1; 38 | } 39 | 40 | /* ---------- Create LCDs ---------- */ 41 | 42 | m = lvd_create_module_klcd_no_thread(LCD_DIR("msr_autogen/msr_klcd"), 43 | "lcd_test_mod_msr_autogen_msr_klcd", 44 | &msr_klcd); 45 | 46 | if (!m) { 47 | LIBLCD_ERR("failed to create net klcd"); 48 | ret = -1; 49 | goto fail3; 50 | } 51 | ret = lvd_create_module_lvd(LCD_DIR("msr_autogen/msr_lcd"), 52 | "lcd_test_mod_msr_autogen_msr_lcd", 53 | &msr_lcd, 54 | &msr_ctx, 1); 55 | if (ret) { 56 | LIBLCD_ERR("failed to create msr lcd"); 57 | goto fail4; 58 | } 59 | 60 | /* ---------- RUN! ---------- */ 61 | 62 | LIBLCD_MSG("starting network..."); 63 | 64 | /* run KLCD init */ 65 | ret = lcd_run(msr_klcd); 66 | if (ret) { 67 | LIBLCD_ERR("failed to start net klcd"); 68 | goto fail8; 69 | } 70 | 71 | LIBLCD_MSG("starting %s", ISOLATED_MODULE_NAME); 72 | 73 | ret = lcd_run(msr_lcd); 74 | if (ret) { 75 | LIBLCD_ERR("failed to start msr lcd"); 76 | goto fail9; 77 | } 78 | 79 | return 0; 80 | 81 | /* The destroy's will free up everything ... */ 82 | fail9: 83 | fail8: 84 | lcd_cap_delete(msr_lcd); 85 | lcd_destroy_create_ctx(msr_ctx); 86 | fail4: 87 | //lcd_cap_delete(msr_klcd); 88 | lcd_destroy_module_klcd(msr_klcd, "lcd_test_mod_msr_autogen_msr_klcd"); 89 | fail3: 90 | lcd_exit(0); /* will free endpoints */ 91 | fail1: 92 | return ret; 93 | } 94 | 95 | static DECLARE_WAIT_QUEUE_HEAD(wq); 96 | static int shutdown = 0; 97 | 98 | int boot_lcd_thread(void *data) 99 | { 100 | static unsigned once = 0; 101 | int ret = 0; 102 | while (!kthread_should_stop()) { 103 | if (!once) { 104 | LCD_MAIN({ 105 | ret = boot_main(); 106 | }); 107 | } 108 | once = 1; 109 | wait_event_interruptible(wq, shutdown != 0); 110 | } 111 | msleep(2000); 112 | LIBLCD_MSG("Exiting thread"); 113 | if (!ret) { 114 | /* trigger exit module */ 115 | lcd_stop(msr_klcd); 116 | 117 | lcd_destroy_module_klcd(msr_klcd, 118 | "lcd_test_mod_msr_autogen_msr_klcd"); 119 | if (current->lcd) 120 | lcd_cap_delete(msr_lcd); 121 | if (msr_ctx) 122 | lcd_destroy_create_ctx(msr_ctx); 123 | 124 | lcd_exit(0); 125 | } 126 | return 0; 127 | } 128 | 129 | struct task_struct *boot_task; 130 | 131 | static int boot_init(void) 132 | { 133 | LIBLCD_MSG("%s: entering on cpu: %d", __func__, bind_cpu); 134 | 135 | boot_task = kthread_create(boot_lcd_thread, NULL, "boot_lcd_thread"); 136 | 137 | kthread_bind(boot_task, bind_cpu); 138 | if (!IS_ERR(boot_task)) 139 | wake_up_process(boot_task); 140 | return 0; 141 | } 142 | 143 | static void boot_exit(void) 144 | { 145 | /* nothing to do */ 146 | if (!IS_ERR(boot_task)) { 147 | LIBLCD_MSG("%s: exiting", __func__); 148 | shutdown = 1; 149 | wake_up_interruptible(&wq); 150 | kthread_stop(boot_task); 151 | } 152 | } 153 | 154 | module_init(boot_init); 155 | module_exit(boot_exit); 156 | 157 | MODULE_LICENSE("GPL"); 158 | -------------------------------------------------------------------------------- /msr/msr_autogen/glue_user.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "common.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | DEFINE_HASHTABLE(shadow_ht, 4); 12 | DEFINE_HASHTABLE(to_shadow_ht, 4); 13 | bool initialized = 0; 14 | 15 | struct shadow_link { 16 | struct hlist_node hentry; 17 | struct hlist_node to_hentry; 18 | void* shadow; 19 | const void* object; 20 | }; 21 | 22 | void glue_user_panic(const char* msg) 23 | { 24 | LIBLCD_ERR(msg); 25 | while (true) {}; 26 | } 27 | 28 | void glue_user_trace(const char* msg) 29 | { 30 | LIBLCD_MSG(msg); 31 | } 32 | 33 | void glue_user_call_server(struct fipc_message* msg, size_t id) 34 | { 35 | msg->vmfunc_id = VMFUNC_RPC_CALL; 36 | msg->rpc_id = id; 37 | glue_user_trace("Committing to KLCD call"); 38 | vmfunc_wrapper(msg); 39 | glue_user_trace("Completed call in LCD"); 40 | } 41 | 42 | void glue_user_call_client(struct fipc_message* msg, size_t id) 43 | { 44 | msg->vmfunc_id = VMFUNC_RPC_CALL; 45 | msg->rpc_id = id; 46 | glue_user_trace("Committing to LCD call"); 47 | vmfunc_klcd_wrapper(msg, OTHER_DOMAIN); 48 | glue_user_trace("Completed call in KLCD"); 49 | } 50 | 51 | void* glue_user_map_to_shadow(const void* obj, bool fail) 52 | { 53 | struct shadow_link *link; 54 | 55 | LIBLCD_MSG("Lookup for key %p\n", obj); 56 | hash_for_each_possible(to_shadow_ht, link, 57 | to_hentry, (unsigned long) obj) { 58 | if (!link) 59 | glue_user_panic("Null detected in shadow_ht"); 60 | 61 | if (link->object == obj) { 62 | glue_user_trace("Found remote for shadow"); 63 | if (!link->shadow) 64 | glue_user_panic("Remote for shadow was NULL"); 65 | 66 | return link->shadow; 67 | } 68 | } 69 | 70 | if (fail) 71 | glue_user_panic("Remote for shadow was not found in to_shadow_ht"); 72 | 73 | return NULL; 74 | } 75 | 76 | const void* glue_user_map_from_shadow(const void* shadow) 77 | { 78 | struct shadow_link *link; 79 | 80 | LIBLCD_MSG("Lookup for key %p\n", shadow); 81 | hash_for_each_possible(shadow_ht, link, 82 | hentry, (unsigned long) shadow) { 83 | if (!link) 84 | glue_user_panic("Null detected in shadow_ht"); 85 | 86 | if (link->shadow == shadow) { 87 | glue_user_trace("Found remote for shadow"); 88 | if (!link->object) 89 | glue_user_panic("Remote for shadow was NULL"); 90 | 91 | return link->object; 92 | } 93 | } 94 | 95 | glue_user_panic("Remote for shadow was not found in shadow_ht"); 96 | 97 | return NULL; 98 | } 99 | 100 | void glue_user_add_shadow(const void* ptr, void* shadow) 101 | { 102 | struct shadow_link *link = kzalloc(sizeof(*link), GFP_KERNEL); 103 | 104 | if (!ptr) 105 | glue_user_panic("Remote for shadowing was NULL"); 106 | 107 | if (!shadow) 108 | glue_user_panic("New shadow was NULL"); 109 | 110 | if (!link) { 111 | glue_user_panic("Couldn't allocate"); 112 | } 113 | 114 | link->shadow = shadow; 115 | link->object = ptr; 116 | 117 | /* use shadow pointer as the key */ 118 | hash_add(shadow_ht, &link->hentry, (unsigned long) shadow); 119 | hash_add(to_shadow_ht, &link->to_hentry, (unsigned long) link->object); 120 | LIBLCD_MSG("Inserted shadow with \n", shadow, ptr); 121 | } 122 | 123 | void* glue_user_alloc(size_t size, gfp_t flags) 124 | { 125 | void* ptr = kzalloc(size, flags); 126 | if (!ptr) { 127 | glue_user_panic("Couldn't allocate"); 128 | } 129 | printk("%s, allocated %p | size %ld\n", __func__, ptr, size); 130 | 131 | return ptr; 132 | } 133 | 134 | void glue_user_free(void* ptr) 135 | { 136 | kfree(ptr); 137 | } 138 | 139 | void glue_user_init(void) 140 | { 141 | glue_user_trace("Initialized glue layer"); 142 | hash_init(shadow_ht); 143 | hash_init(to_shadow_ht); 144 | } 145 | 146 | // TODO 147 | -------------------------------------------------------------------------------- /msr/msr_autogen/glue_user.h: -------------------------------------------------------------------------------- 1 | #ifndef GLUE_USER_H 2 | #define GLUE_USER_H 3 | 4 | #include 5 | #include 6 | 7 | int __module_lcd_init(void); 8 | void __module_lcd_exit(void); 9 | 10 | #ifndef LCD_ISOLATE 11 | #define get_jiffies() ({ jiffies; }) 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /msr/msr_autogen/msr_klcd/Kbuild: -------------------------------------------------------------------------------- 1 | obj-m += lcd_test_mod_msr_autogen_msr_klcd.o 2 | 3 | lcd_test_mod_msr_autogen_msr_klcd-y += main.o 4 | lcd_test_mod_msr_autogen_msr_klcd-y += $(addprefix ../, server.o common.o glue_user.o) 5 | 6 | cppflags-y += $(NONISOLATED_CFLAGS) 7 | 8 | extra-y += $(addprefix ../, trampolines.lds) 9 | ldflags-y += -T $(LCD_TEST_MODULES_BUILD_DIR)/msr_autogen/trampolines.lds 10 | 11 | 12 | ccflags-y += $(NONISOLATED_CFLAGS) 13 | -------------------------------------------------------------------------------- /msr/msr_autogen/msr_klcd/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | //#include "../glue_helper.h" 12 | #include 13 | 14 | #include "../common.h" 15 | 16 | #include 17 | 18 | #define INIT_FIPC_MSG(msg) memset(msg, 0x0, sizeof(*msg)) 19 | 20 | extern int vmfunc_init(void *stack_page, rpc_handler_t rpc_handler, 21 | rpc_handler_t sync_handler); 22 | 23 | /* INIT / EXIT ---------------------------------------- */ 24 | struct cspace *klcd_cspace; 25 | extern void *lcd_stack; 26 | 27 | int msr_klcd_dispatch_loop(struct fipc_message *msg) 28 | { 29 | const size_t id = msg->rpc_id; 30 | if (!try_dispatch(id, msg, get_register_page(smp_processor_id()))) { 31 | glue_user_panic("Couldn't dispatch on KLCD side"); 32 | } 33 | 34 | return 0; 35 | } 36 | 37 | int msr_klcd_syncipc_dispatch(struct fipc_message *message) 38 | { 39 | glue_user_panic("Shouldn't have done a synchronous call!\n"); 40 | return -1; 41 | } 42 | 43 | static int msr_klcd_init(void) 44 | { 45 | int ret = 0; 46 | struct fipc_message m; 47 | /* 48 | * Set up cptr cache, etc. 49 | */ 50 | #ifndef CONFIG_LVD 51 | ret = lcd_enter(); 52 | if (ret) { 53 | LIBLCD_ERR("lcd enter"); 54 | goto fail1; 55 | } 56 | #endif 57 | 58 | INIT_FIPC_MSG(&m); 59 | 60 | /* save cspace for future use 61 | * when userspace functions call function pointers, 62 | * we need to get access to the sync_ep of this klcd 63 | * to transfer pointers and data thro sync IPC to the lcd 64 | */ 65 | klcd_cspace = get_current_cspace(current); 66 | 67 | /* 68 | * Init net glue 69 | */ 70 | glue_user_init(); 71 | LIBLCD_MSG("-===== > glue msr init called\n"); 72 | 73 | if (ret) { 74 | LIBLCD_ERR("msr init"); 75 | goto fail2; 76 | } 77 | 78 | vmfunc_init(lcd_stack, msr_klcd_dispatch_loop, msr_klcd_syncipc_dispatch); 79 | 80 | /* call module_init for lcd */ 81 | m.vmfunc_id = VMFUNC_RPC_CALL; 82 | m.rpc_id = MODULE_INIT; 83 | LIBLCD_MSG("vmfunc_init successfull! Calling MODULE_INIT of dummy_lcd"); 84 | vmfunc_klcd_wrapper(&m, OTHER_DOMAIN); 85 | 86 | return 0; 87 | 88 | fail2: 89 | lcd_exit(ret); 90 | #ifndef CONFIG_LVD 91 | fail1: 92 | #endif 93 | return ret; 94 | } 95 | 96 | /* 97 | * make module loader happy (so we can unload). we don't actually call 98 | * this before unloading the lcd (yet) 99 | */ 100 | static void __exit msr_klcd_exit(void) 101 | { 102 | struct fipc_message m; 103 | 104 | LIBLCD_MSG("%s: exiting", __func__); 105 | 106 | INIT_FIPC_MSG(&m); 107 | 108 | /* call module_init for lcd */ 109 | m.vmfunc_id = VMFUNC_RPC_CALL; 110 | m.rpc_id = MODULE_EXIT; 111 | LIBLCD_MSG("Calling MODULE_EXIT of dummy_lcd"); 112 | vmfunc_klcd_wrapper(&m, OTHER_DOMAIN); 113 | 114 | #ifndef CONFIG_LVD 115 | /* 116 | * In case of LVD, boot module calls lcd_exit 117 | */ 118 | lcd_exit(0); 119 | #endif 120 | 121 | return; 122 | } 123 | 124 | module_init(msr_klcd_init); 125 | module_exit(msr_klcd_exit); 126 | MODULE_LICENSE("GPL"); 127 | -------------------------------------------------------------------------------- /msr/msr_autogen/msr_lcd/Kbuild: -------------------------------------------------------------------------------- 1 | obj-m += lcd_test_mod_msr_autogen_msr_lcd.o 2 | 3 | lcd_test_mod_msr_autogen_msr_lcd-y += main.o 4 | 5 | # Original code 6 | lcd_test_mod_msr_autogen_msr_lcd-y += msr.o 7 | 8 | 9 | lcd_test_mod_msr_autogen_msr_lcd-y += $(LIBLCD) 10 | 11 | lcd_test_mod_msr_autogen_msr_lcd-y += $(addprefix ../, client.o common.o glue_user.o) 12 | 13 | ccflags-y += $(ISOLATED_CFLAGS) 14 | 15 | extra-y += ../../../liblcd_build/common/vmfunc.lds 16 | 17 | ldflags-y += -T $(LIBLCD_BUILD_DIR)/common/vmfunc.lds 18 | 19 | cppflags-y += $(ISOLATED_CFLAGS) 20 | 21 | -------------------------------------------------------------------------------- /msr/msr_autogen/msr_lcd/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * main.c - runs when dummy lcd boots 3 | */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "../common.h" 14 | 15 | #include 16 | 17 | struct thc_channel *msr_async; 18 | struct glue_cspace *msr_cspace; 19 | cptr_t msr_sync_endpoint; 20 | 21 | int msr_init(void); 22 | void msr_exit(void); 23 | 24 | int handle_rpc_calls(struct fipc_message* msg) 25 | { 26 | const size_t id = msg->rpc_id; 27 | if (!try_dispatch(id, msg, get_register_page(smp_processor_id()))) { 28 | glue_user_panic("Couldn't dispatch on LCD side"); 29 | } 30 | 31 | return 0; 32 | } 33 | 34 | static int module_lcd_init(void) 35 | { 36 | int ret = 0; 37 | 38 | printk("LCD enter: current:%p \n", current); 39 | ret = lcd_enter(); 40 | if (ret) 41 | goto fail1; 42 | 43 | glue_user_init(); 44 | 45 | ret = msr_init(); 46 | 47 | return ret; 48 | fail1: 49 | lcd_exit(ret); 50 | } 51 | 52 | int __module_lcd_init(void) 53 | { 54 | return module_lcd_init(); 55 | } 56 | 57 | static void module_lcd_exit(void) 58 | { 59 | LIBLCD_MSG("%s: exiting", __func__); 60 | 61 | msr_exit(); 62 | 63 | lvd_exit(0); 64 | return; 65 | } 66 | 67 | void __module_lcd_exit(void) 68 | { 69 | module_lcd_exit(); 70 | } 71 | 72 | module_init(__module_lcd_init); 73 | module_exit(__module_lcd_exit); 74 | MODULE_LICENSE("GPL"); 75 | MODULE_INFO(livepatch, "Y"); 76 | 77 | /* extract data from linker variables */ 78 | size_t vmfunc_sboard_page_size = (size_t)&__vmfunc_sboard_page_size; 79 | unsigned long* vmfunc_sboard_load_addr = (unsigned long*) &__vmfunc_sboard_load_addr; 80 | 81 | /* extract data from linker variables */ 82 | size_t vmfunc_trampoline_page_size = (size_t)&__vmfunc_trampoline_page_size; 83 | unsigned long* vmfunc_trampoline_load_addr = (unsigned long*) &__vmfunc_trampoline_load_addr; 84 | 85 | EXPORT_SYMBOL(vmfunc_sboard_load_addr); 86 | EXPORT_SYMBOL(vmfunc_trampoline_load_addr); 87 | 88 | -------------------------------------------------------------------------------- /msr/msr_autogen/msr_lcd/msr.c: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- * 2 | * 3 | * Copyright 2000-2008 H. Peter Anvin - All Rights Reserved 4 | * Copyright 2009 Intel Corporation; author: H. Peter Anvin 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, 9 | * USA; either version 2 of the License, or (at your option) any later 10 | * version; incorporated herein by reference. 11 | * 12 | * ----------------------------------------------------------------------- */ 13 | 14 | /* 15 | * x86 MSR access device 16 | * 17 | * This device is accessed by lseek() to the appropriate register number 18 | * and then read/write in chunks of 8 bytes. A larger size means multiple 19 | * reads or writes of the same register. 20 | * 21 | * This driver uses /dev/cpu/%d/msr where %d is the minor number, and on 22 | * an SMP box will direct the access to CPU %d. 23 | */ 24 | 25 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 26 | 27 | #ifdef LCD_ISOLATE 28 | #include 29 | #endif 30 | 31 | 32 | #include 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | #include 49 | #include 50 | 51 | #ifdef LCD_ISOLATE 52 | #include 53 | #endif 54 | 55 | extern 56 | struct device* __device_create(struct class* class, struct device* parent, unsigned int devt, void* drvdata, char const* fmt, unsigned int cpu); 57 | static struct class *msr_class; 58 | 59 | static ssize_t msr_read(struct file *file, char __user *buf, 60 | size_t count, loff_t *ppos) 61 | { 62 | u32 __user *tmp = (u32 __user *) buf; 63 | u32 data[2]; 64 | u32 reg = *ppos; 65 | int cpu = iminor(file_inode(file)); 66 | int err = 0; 67 | ssize_t bytes = 0; 68 | 69 | if (count % 8) 70 | return -EINVAL; /* Invalid chunk size */ 71 | 72 | for (; count; count -= 8) { 73 | err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]); 74 | if (err) 75 | break; 76 | #ifdef LCD_ISOLATE 77 | memcpy(tmp, &data, 8); 78 | #else 79 | if (copy_to_user(tmp, &data, 8)) { 80 | err = -EFAULT; 81 | break; 82 | } 83 | #endif 84 | tmp += 2; 85 | bytes += 8; 86 | } 87 | 88 | return bytes ? bytes : err; 89 | } 90 | 91 | static ssize_t msr_write(struct file *file, const char __user *buf, 92 | size_t count, loff_t *ppos) 93 | { 94 | const u32 __user *tmp = (const u32 __user *)buf; 95 | u32 data[2]; 96 | u32 reg = *ppos; 97 | int cpu = iminor(file_inode(file)); 98 | int err = 0; 99 | ssize_t bytes = 0; 100 | 101 | if (count % 8) 102 | return -EINVAL; /* Invalid chunk size */ 103 | 104 | for (; count; count -= 8) { 105 | #ifdef LCD_ISOLATE 106 | memcpy(&data, tmp, 8); 107 | #else 108 | if (copy_from_user(&data, tmp, 8)) { 109 | err = -EFAULT; 110 | break; 111 | } 112 | #endif 113 | err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); 114 | if (err) 115 | break; 116 | tmp += 2; 117 | bytes += 8; 118 | } 119 | 120 | return bytes ? bytes : err; 121 | } 122 | 123 | static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg) 124 | { 125 | u32 __user *uregs = (u32 __user *)arg; 126 | u32 regs[8]; 127 | int cpu = iminor(file_inode(file)); 128 | int err; 129 | 130 | switch (ioc) { 131 | case X86_IOC_RDMSR_REGS: 132 | if (!(file->f_mode & FMODE_READ)) { 133 | err = -EBADF; 134 | break; 135 | } 136 | if (copy_from_user(®s, uregs, sizeof regs)) { 137 | err = -EFAULT; 138 | break; 139 | } 140 | err = rdmsr_safe_regs_on_cpu(cpu, regs); 141 | if (err) 142 | break; 143 | if (copy_to_user(uregs, ®s, sizeof regs)) 144 | err = -EFAULT; 145 | break; 146 | 147 | case X86_IOC_WRMSR_REGS: 148 | if (!(file->f_mode & FMODE_WRITE)) { 149 | err = -EBADF; 150 | break; 151 | } 152 | if (copy_from_user(®s, uregs, sizeof regs)) { 153 | err = -EFAULT; 154 | break; 155 | } 156 | err = wrmsr_safe_regs_on_cpu(cpu, regs); 157 | if (err) 158 | break; 159 | if (copy_to_user(uregs, ®s, sizeof regs)) 160 | err = -EFAULT; 161 | break; 162 | 163 | default: 164 | err = -ENOTTY; 165 | break; 166 | } 167 | 168 | return err; 169 | } 170 | 171 | static int msr_open(struct inode *inode, struct file *file) 172 | { 173 | unsigned int cpu = iminor(file_inode(file)); 174 | struct cpuinfo_x86 *c; 175 | 176 | if (!capable(CAP_SYS_RAWIO)) 177 | return -EPERM; 178 | 179 | if (cpu >= nr_cpu_ids || !cpu_online(cpu)) 180 | return -ENXIO; /* No such CPU */ 181 | 182 | c = &cpu_data(cpu); 183 | if (!cpu_has(c, X86_FEATURE_MSR)) 184 | return -EIO; /* MSR not supported */ 185 | 186 | return 0; 187 | } 188 | 189 | /* 190 | * File operations we support 191 | */ 192 | static const struct file_operations msr_fops = { 193 | .owner = THIS_MODULE, 194 | .llseek = no_seek_end_llseek, 195 | .read = msr_read, 196 | .write = msr_write, 197 | .open = msr_open, 198 | .unlocked_ioctl = msr_ioctl, 199 | .compat_ioctl = msr_ioctl, 200 | }; 201 | 202 | static int msr_device_create(int cpu) 203 | { 204 | struct device *dev; 205 | 206 | dev = __device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu), NULL, 207 | "msr%d", cpu); 208 | return PTR_ERR_OR_ZERO(dev); 209 | } 210 | 211 | static void msr_device_destroy(int cpu) 212 | { 213 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); 214 | } 215 | /* 216 | static int msr_class_cpu_callback(struct notifier_block *nfb, 217 | unsigned long action, void *hcpu) 218 | { 219 | unsigned int cpu = (unsigned long)hcpu; 220 | int err = 0; 221 | 222 | switch (action) { 223 | case CPU_UP_PREPARE: 224 | err = msr_device_create(cpu); 225 | break; 226 | case CPU_UP_CANCELED: 227 | case CPU_UP_CANCELED_FROZEN: 228 | case CPU_DEAD: 229 | msr_device_destroy(cpu); 230 | break; 231 | } 232 | return notifier_from_errno(err); 233 | } 234 | 235 | static struct notifier_block __refdata msr_class_cpu_notifier = { 236 | .notifier_call = msr_class_cpu_callback, 237 | };*/ 238 | 239 | static char *msr_devnode(struct device *dev, umode_t *mode) 240 | { 241 | return kasprintf(GFP_KERNEL, "cpu/%u/msr", MINOR(dev->devt)); 242 | } 243 | 244 | #ifndef LCD_ISOLATE 245 | static int __init msr_init(void) 246 | #else 247 | int msr_init(void) 248 | #endif 249 | { 250 | int i, err = 0; 251 | i = 0; 252 | 253 | if (__register_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr", &msr_fops)) { 254 | pr_err("unable to get major %d for msr\n", MSR_MAJOR); 255 | err = -EBUSY; 256 | goto out; 257 | } 258 | msr_class = class_create(THIS_MODULE, "msr"); 259 | if (IS_ERR(msr_class)) { 260 | err = PTR_ERR(msr_class); 261 | goto out_chrdev; 262 | } 263 | msr_class->devnode = msr_devnode; 264 | 265 | cpu_notifier_register_begin(); 266 | for_each_online_cpu(i) { 267 | err = msr_device_create(i); 268 | if (err != 0) 269 | goto out_class; 270 | } 271 | //__register_hotcpu_notifier(&msr_class_cpu_notifier); 272 | cpu_notifier_register_done(); 273 | 274 | err = 0; 275 | goto out; 276 | 277 | out_class: 278 | i = 0; 279 | for_each_online_cpu(i) 280 | msr_device_destroy(i); 281 | cpu_notifier_register_done(); 282 | class_destroy(msr_class); 283 | out_chrdev: 284 | __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr"); 285 | out: 286 | return err; 287 | } 288 | 289 | #ifndef LCD_ISOLATE 290 | static void __exit msr_exit(void) 291 | #else 292 | void msr_exit(void) 293 | #endif 294 | { 295 | int cpu = 0; 296 | 297 | cpu_notifier_register_begin(); 298 | for_each_online_cpu(cpu) 299 | msr_device_destroy(cpu); 300 | class_destroy(msr_class); 301 | __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr"); 302 | //__unregister_hotcpu_notifier(&msr_class_cpu_notifier); 303 | cpu_notifier_register_done(); 304 | } 305 | 306 | 307 | #ifndef LCD_ISOLATE 308 | module_init(msr_init); 309 | module_exit(msr_exit) 310 | 311 | MODULE_AUTHOR("H. Peter Anvin "); 312 | MODULE_DESCRIPTION("x86 generic MSR driver"); 313 | MODULE_LICENSE("GPL"); 314 | #endif 315 | -------------------------------------------------------------------------------- /msr/toggle_ht.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | typeset -i core_id 3 | typeset -i sibling_id 4 | typeset -i state 5 | 6 | NPROC=$(lscpu | grep "^CPU(s):" | awk '{print $2}') 7 | 8 | 9 | toggle() { 10 | for cpu in $(seq 0 $(( ${NPROC} - 1 ))); do 11 | i="/sys/devices/system/cpu/cpu${cpu}" 12 | core_id="${i##*cpu}" 13 | sibling_id="-1" 14 | 15 | if [ -f ${i}/topology/thread_siblings_list ]; then 16 | sibling_id="$(cut -d',' -f1 ${i}/topology/thread_siblings_list)" 17 | fi 18 | 19 | if [ $core_id -ne $sibling_id ]; then 20 | state="$(<${i}/online)" 21 | echo -n "$((1-state))" > "${i}/online" 22 | echo "switched ${i}/online to $((1-state))" 23 | fi 24 | done 25 | } 26 | 27 | ht_control() { 28 | for cpu in $(seq 0 $(( ${NPROC} - 1 ))); do 29 | i="/sys/devices/system/cpu/cpu${cpu}" 30 | core_id="${i##*cpu}" 31 | sibling_id="-1" 32 | 33 | if [ -f ${i}/topology/thread_siblings_list ]; then 34 | sibling_id="$(cut -d',' -f1 ${i}/topology/thread_siblings_list)" 35 | fi 36 | 37 | if [ $core_id -ne $sibling_id ]; then 38 | state=$1 39 | echo -n "${state}" > "${i}/online" 40 | echo "switched ${i}/online to ${state}" 41 | fi 42 | done 43 | } 44 | 45 | 46 | if [ "$1" == "off" ]; then 47 | ht_control 0 48 | elif [ "$1" == "on" ]; then 49 | ht_control 1 50 | else 51 | toggle 52 | fi 53 | -------------------------------------------------------------------------------- /table4/manual_setup.md: -------------------------------------------------------------------------------- 1 | ## Table 4 benchmarks 2 | -- 3 | 4 | If you are looking for a push-button script, please invoke `table4.sh` 5 | 6 | Here is a detailed explanation of the steps involved to recreate table4 from 7 | the paper. 8 | 9 | 1. Following the above steps, the node should be running the `4.8.4-lvd` kernel. 10 | ``` 11 | uname -r 12 | 4.8.4-lvd 13 | ``` 14 | 15 | 2. Insert bareflank hypervisor module 16 | ``` 17 | cd /opt/ksplit/bflank/build 18 | make driver_quick && make quick 19 | ``` 20 | 21 | You should see similar messages on the console 22 | ``` 23 | Scanning dependencies of target driver_quick 24 | Scanning dependencies of target driver_unload 25 | Built target driver_unload 26 | Scanning dependencies of target driver_clean 27 | Built target driver_clean 28 | Scanning dependencies of target driver_build 29 | Built target driver_build 30 | Scanning dependencies of target driver_load 31 | Built target driver_load 32 | Built target driver_quick 33 | Scanning dependencies of target quick 34 | Built target quick 35 | ``` 36 | 37 | In `dmesg`, you should see 38 | ``` 39 | [ 2682.962046] [BAREFLANK DEBUG]: dev_init succeeded 40 | [ 2683.051737] [BAREFLANK DEBUG]: dev_open succeeded 41 | [ 2683.081715] [BAREFLANK DEBUG]: IOCTL_ADD_MODULE_LENGTH: succeeded 42 | [ 2683.082097] [BAREFLANK DEBUG]: IOCTL_ADD_MODULE: succeeded 43 | [ 2683.494023] [BAREFLANK DEBUG]: IOCTL_LOAD_VMM: succeeded 44 | [ 2683.494046] [BAREFLANK DEBUG]: dev_release succeeded 45 | [ 2683.501491] [BAREFLANK DEBUG]: dev_open succeeded 46 | [ 2694.136286] [BAREFLANK DEBUG]: IOCTL_START_VMM: succeeded 47 | [ 2694.136330] [BAREFLANK DEBUG]: dev_release succeeded 48 | ``` 49 | 50 | 4. Loading the test module. 51 | 52 | * Load the microkernel module 53 | ``` 54 | cd /opt/ksplit/lvd-linux/lcd-domains 55 | # load lcd-domains.ko 56 | ./scripts/mk 57 | ``` 58 | 59 | * Load the `vmfunc_klcd` module 60 | ``` 61 | # load the test module that runs marshalling overheads test 62 | ./scripts/loadex vmfunc_klcd 63 | ``` 64 | 65 | * In another terminal, check the dmesg with `sudo dmesg -w` 66 | 67 | * If successful, you should see something like 68 | ``` 69 | message from lcd ffff881421cbd800: =============== 70 | message from lcd ffff881421cbd800: LCD BOOTED 71 | message from lcd ffff881421cbd800: =============== 72 | Running marshal_empty test! 73 | test_marshal_empty: 1000000 iterations of marshal none took 530368116 cycles (avg: 530 cycles) 74 | Running marshal_int test! 75 | test_marshal_int: 1000000 iterations of marshal int took 537546720 cycles (avg: 537 cycles) 76 | Running marshal_array test! 77 | message from lcd ffff881421cbd800: marshal_array_callee, allocating an array of size 32 78 | test_marshal_array: 1000000 iterations of marshal array[32] took 706914708 cycles (avg: 706 cycles) 79 | Running marshal_string test! 80 | test_marshal_string: 1000000 iterations of marshal string (len: 255) took 1312815912 cycles (avg: 1312 cycles) 81 | Running marshal_voidptr test! 82 | message from lcd ffff881421cbd800: marshal_voidptr_callee, allocating a buffer of size 4096 83 | test_marshal_voidptr: 1000000 iterations of marshal void ptr (sz=4096) took 886989248 cycles (avg: 886 cycles) 84 | Running marshal_union test! 85 | test_marshal_union: 1000000 iterations of marshal union took 700801680 cycles (avg: 700 cycles) 86 | ``` 87 | 88 | -------------------------------------------------------------------------------- /table4/table4.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ARTIFACTS_HOME="${HOME}/ksplit-artifacts" 4 | MSR_ARTIFACT="${ARTIFACTS_HOME}/msr" 5 | 6 | BASE_DIR="/opt/ksplit" 7 | BFLANK_BUILD="${BASE_DIR}/bflank/build" 8 | 9 | LVD_LINUX="${BASE_DIR}/lvd-linux" 10 | LVD_DOMAINS="${LVD_LINUX}/lcd-domains" 11 | TEST_MODS="${LVD_DOMAINS}/test_mods" 12 | 13 | TESTMOD="vmfunc_klcd" 14 | 15 | TESTMOD_BUILD_DIR="${LVD_DOMAINS}/build/test_mods/${TESTMOD}" 16 | BOOT_KO="${TESTMOD_BUILD_DIR}/boot/lcd_test_mod_${TESTMOD}_boot.ko" 17 | KLCD_KO="${TESTMOD_BUILD_DIR}/msr_klcd/lcd_test_mod_${TESTMOD}_caller_klcd.ko" 18 | LCD_KO="${TESTMOD_BUILD_DIR}/msr_lcd/lcd_test_mod_${TESTMOD}_callee_lcd.ko" 19 | 20 | 21 | chown() { 22 | USER=$(id -u -n) 23 | GROUP=$(id -g -n) 24 | sudo chown -R ${USER}:${GROUP} ${BASE_DIR} 25 | } 26 | 27 | build_module() { 28 | pushd ${LVD_DOMAINS} 29 | make 30 | 31 | if [[ ! -n ${BOOT_KO} ]] || [[ ! -n ${KLCD_KO} ]] || [[ ! -n ${LCD_KO} ]];then 32 | echo "Building autogenerated module failed" 33 | else 34 | echo "Module successfully built" 35 | fi 36 | popd 37 | } 38 | 39 | load_bflank_module() { 40 | sudo ${MSR_ARTIFACT}/toggle_ht.sh off 41 | pushd "${BFLANK_BUILD}" 42 | make driver_quick && make quick 43 | popd 44 | } 45 | 46 | load_module() { 47 | load_bflank_module; 48 | pushd ${LVD_DOMAINS} 49 | ./scripts/mk 50 | sleep 5; 51 | ./scripts/loadex ${TESTMOD} 52 | # allow some time for the module to get loaded 53 | sleep 120; 54 | popd 55 | } 56 | 57 | get_test_output() { 58 | TEST_NAME=$1 59 | GREP_STR="test_marshal_${TEST_NAME}:" 60 | OUTPUT=$(sudo dmesg | grep ${GREP_STR} | tail -1 | awk '{print $(NF-1)}') 61 | echo ${OUTPUT} 62 | } 63 | 64 | test_module() { 65 | echo "test, number of cycles" 66 | for t in "empty" "int" "array" "string" "voidptr" "union"; do 67 | CYCLES=$(get_test_output ${t}) 68 | echo "${t}, ${CYCLES}" 69 | done 70 | } 71 | 72 | chown 73 | build_module 74 | load_module 75 | test_module 76 | -------------------------------------------------------------------------------- /table_3_IDL/edac/sb_edac.idl: -------------------------------------------------------------------------------- 1 | // Sync stubs for boundary functions 2 | module kernel { 3 | rpc int edac_mc_add_mc_with_groups( projection mem_ctl_info [in] *mci, projection attribute_group **groups ) { 4 | projection < struct work> work { 5 | projection timer timer; 6 | } 7 | projection < struct timer> timer { 8 | u64 [out] data; 9 | } 10 | projection < struct mem_ctl_info > mem_ctl_info { 11 | u64 [in] mtype_cap; 12 | u64 [in] edac_ctl_cap; 13 | u64 [in] edac_cap; 14 | int [in] mc_idx; 15 | array csrows; 16 | unsigned int [in] nr_csrows; 17 | unsigned int [in] tot_dimms; 18 | array dimms; 19 | projection mem_ctl_info_device* pdev; 20 | char* [in] mod_name; 21 | char* [in] ctl_name; 22 | char* [in] dev_name; 23 | void* [in] pvt_info; 24 | u64 [out] start_time; 25 | projection work work; 26 | int [in,out] op_state; 27 | } 28 | projection < struct dimm_info > mem_ctl_info_dimm_info { 29 | } 30 | projection < struct device > mem_ctl_info_device { 31 | } 32 | projection < struct attribute_group > attribute_group { 33 | } 34 | } 35 | rpc projection ret_mem_ctl_info* edac_mc_alloc( unsigned int mc_num, unsigned int n_layers, projection edac_mc_layer [in,out] *layers, unsigned int sz_pvt ) { 36 | projection < struct mem_ctl_info > ret_mem_ctl_info { 37 | int mc_idx; 38 | unsigned int [out] nr_csrows; 39 | unsigned int [out] num_cschannel; 40 | unsigned int [out] n_layers; 41 | projection mem_ctl_info_edac_mc_layer* layers; 42 | bool [out] csbased; 43 | unsigned int [out] tot_dimms; 44 | projection mem_ctl_info_dimm_info** dimms; 45 | void* [out] pvt_info; 46 | array< unsigned int, 6> ce_per_layer; 47 | array< unsigned int, 6> ue_per_layer; 48 | int [out] op_state; 49 | } 50 | projection < struct edac_mc_layer > ret_mem_ctl_info_edac_mc_layer { 51 | } 52 | projection < struct dimm_info > ret_mem_ctl_info_dimm_info { 53 | } 54 | projection < struct edac_mc_layer > edac_mc_layer { 55 | unsigned int [in,out] type; 56 | bool [in,out] is_virt_csrow; 57 | } 58 | } 59 | rpc projection ret_mem_ctl_info* edac_mc_del_mc( projection device *dev ) { 60 | projection < struct mem_ctl_info > ret_mem_ctl_info { 61 | int mc_idx; 62 | char* mod_name; 63 | char* ctl_name; 64 | char* dev_name; 65 | int [out] op_state; 66 | } 67 | projection < struct device > device { 68 | } 69 | } 70 | rpc void edac_mc_free( projection mem_ctl_info [in] *mci ) { 71 | projection < struct mem_ctl_info > mem_ctl_info { 72 | unsigned int [in] nr_csrows; 73 | unsigned int [in] num_cschannel; 74 | unsigned int [in] tot_dimms; 75 | projection mem_ctl_info_dimm_info** dimms; 76 | } 77 | projection < struct dimm_info > mem_ctl_info_dimm_info { 78 | } 79 | } 80 | rpc void edac_mc_handle_error( unsigned int type, projection mem_ctl_info [in] *mci, unsigned short error_count, u64 page_frame_number, u64 offset_in_page, u64 syndrome, int top_layer, int mid_layer, int low_layer, string [in,out] *msg, string [in,out] *other_detail ) { 81 | projection < struct error_desc> error_desc { 82 | array< char, 256> [in] location; 83 | array< char, 296> [in] label; 84 | u64 [in,out] grain; 85 | unsigned short [in,out] error_count; 86 | int [in,out] top_layer; 87 | int [in,out] mid_layer; 88 | int [in,out] low_layer; 89 | u64 [in,out] page_frame_number; 90 | u64 [in,out] offset_in_page; 91 | u64 [in,out] syndrome; 92 | char* [in,out] msg; 93 | char* [in,out] other_detail; 94 | bool [in,out] enable_per_layer_report; 95 | } 96 | projection < struct mem_ctl_info > mem_ctl_info { 97 | unsigned int [in] scrub_mode; 98 | int [in] mc_idx; 99 | array csrows; 100 | unsigned int [in] n_layers; 101 | projection mem_ctl_info_edac_mc_layer* layers; 102 | bool [in] csbased; 103 | unsigned int [in] tot_dimms; 104 | array dimms; 105 | unsigned int [in,out] ce_noinfo_count; 106 | unsigned int [in,out] ue_noinfo_count; 107 | unsigned int [in,out] ue_mc; 108 | unsigned int [in,out] ce_mc; 109 | array< unsigned int, 6> [in] ce_per_layer; 110 | array< unsigned int, 6> [in] ue_per_layer; 111 | projection error_desc error_desc; 112 | } 113 | projection < struct edac_mc_layer > mem_ctl_info_edac_mc_layer { 114 | } 115 | projection < struct dimm_info > mem_ctl_info_dimm_info { 116 | } 117 | } 118 | rpc void* kmalloc_order( u64 size, unsigned int flags, unsigned int order ) { 119 | } 120 | rpc void mce_register_decode_chain( ) { 121 | } 122 | rpc void mce_unregister_decode_chain( ) { 123 | } 124 | rpc int pci_bus_read_config_dword( projection pci_bus [in] *bus, unsigned int devfn, int pos, unsigned int [out] *value ) { 125 | projection < struct pci_bus > pci_bus { 126 | } 127 | } 128 | rpc projection ret_pci_dev* pci_dev_get( projection pci_dev [in] *dev ) { 129 | projection < struct pci_dev > ret_pci_dev { 130 | } 131 | projection < struct pci_dev > pci_dev { 132 | } 133 | } 134 | rpc void pci_dev_put( projection pci_dev [in] *dev ) { 135 | projection < struct pci_dev > pci_dev { 136 | } 137 | } 138 | rpc int pci_enable_device( projection pci_dev [in] *dev ) { 139 | projection < struct pci_dev > pci_dev { 140 | projection pci_dev_pci_bus* bus; 141 | projection pci_dev_pci_bus* subordinate; 142 | unsigned int [in] devfn; 143 | int [in,out] current_state; 144 | unsigned char [in] pm_cap; 145 | unsigned int [in] pme_support : 5; 146 | unsigned int [in] d3_delay; 147 | unsigned int [in] d3cold_delay; 148 | array< projection resource, 11> [in] resource; 149 | unsigned int [in] msi_enabled : 1; 150 | unsigned int [in] msix_enabled : 1; 151 | unsigned int [in] is_virtfn : 1; 152 | unsigned short [in] dev_flags; 153 | } 154 | projection < struct pci_bus > pci_dev_pci_bus { 155 | projection pci_bus* parent; 156 | projection pci_bus_pci_dev* self; 157 | } 158 | projection < struct pci_bus > pci_dev_pci_bus { 159 | } 160 | projection < struct pci_dev > pci_bus_pci_dev { 161 | } 162 | } 163 | rpc projection ret_pci_dev* pci_get_device( unsigned int vendor, unsigned int device, projection pci_dev [in] *from ) { 164 | projection < struct pci_dev > ret_pci_dev { 165 | } 166 | projection < struct pci_dev > pci_dev { 167 | } 168 | } 169 | rpc projection ret_x86_cpu_id* x86_match_cpu( projection x86_cpu_id [in] *match ) { 170 | projection < struct x86_cpu_id > ret_x86_cpu_id { 171 | unsigned short vendor; 172 | unsigned short family; 173 | unsigned short model; 174 | unsigned short feature; 175 | } 176 | projection < struct x86_cpu_id > x86_cpu_id { 177 | unsigned short [in] vendor; 178 | unsigned short [in] family; 179 | unsigned short [in] model; 180 | unsigned short [in] feature; 181 | } 182 | } 183 | rpc_ptr int sbridge_mce_check_error( projection _global_notifier_block [unused] nb, u64 [unused] val, void [in] *data ) { 184 | } 185 | projection < struct notifier_block > _global_notifier_block { 186 | rpc_ptr sbridge_mce_check_error notifier_call; 187 | } 188 | 189 | 190 | } 191 | -------------------------------------------------------------------------------- /table_3_IDL/edac/skx_edac.idl: -------------------------------------------------------------------------------- 1 | // Sync stubs for boundary functions 2 | module kernel { 3 | rpc projection ret_dentry* debugfs_create_dir( string *name, projection dentry [in] *parent ) { 4 | projection < struct dentry > ret_dentry { 5 | } 6 | projection < struct dentry > dentry { 7 | projection dentry_inode* d_inode; 8 | } 9 | projection < struct inode > dentry_inode { 10 | } 11 | } 12 | rpc projection ret_dentry* debugfs_create_file( string *name, unsigned short mode, projection dentry [in] *parent, void *data, projection _global_file_operations fops ) { 13 | projection < struct dentry > ret_dentry { 14 | } 15 | projection < struct dentry > dentry { 16 | projection dentry_inode* d_inode; 17 | } 18 | projection < struct inode > dentry_inode { 19 | } 20 | } 21 | rpc void debugfs_remove_recursive( projection dentry [in] *dentry ) { 22 | projection < struct d_child> d_child { 23 | projection list_head* next; 24 | } 25 | projection < struct d_subdirs> d_subdirs { 26 | projection list_head* next; 27 | } 28 | projection < struct dentry > dentry { 29 | unsigned int [in] d_flags; 30 | projection dentry* d_parent; 31 | projection dentry_inode* d_inode; 32 | projection d_child d_child; 33 | projection d_subdirs d_subdirs; 34 | } 35 | projection < struct inode > dentry_inode { 36 | } 37 | } 38 | rpc int edac_mc_add_mc_with_groups( projection mem_ctl_info [in] *mci, projection attribute_group **groups ) { 39 | projection < struct work> work { 40 | projection timer timer; 41 | } 42 | projection < struct timer> timer { 43 | u64 [out] data; 44 | } 45 | projection < struct mem_ctl_info > mem_ctl_info { 46 | u64 [in] mtype_cap; 47 | u64 [in] edac_ctl_cap; 48 | u64 [in] edac_cap; 49 | int [in] mc_idx; 50 | array csrows; 51 | unsigned int [in] nr_csrows; 52 | unsigned int [in] tot_dimms; 53 | array dimms; 54 | projection mem_ctl_info_device* pdev; 55 | char* [in] mod_name; 56 | char* [in] ctl_name; 57 | char* [in] dev_name; 58 | void* [in] pvt_info; 59 | u64 [out] start_time; 60 | projection work work; 61 | int [in,out] op_state; 62 | } 63 | projection < struct dimm_info > mem_ctl_info_dimm_info { 64 | } 65 | projection < struct device > mem_ctl_info_device { 66 | } 67 | projection < struct attribute_group > attribute_group { 68 | } 69 | } 70 | rpc projection ret_mem_ctl_info* edac_mc_alloc( unsigned int mc_num, unsigned int n_layers, projection edac_mc_layer [in,out] *layers, unsigned int sz_pvt ) { 71 | projection < struct mem_ctl_info > ret_mem_ctl_info { 72 | int mc_idx; 73 | unsigned int [out] nr_csrows; 74 | unsigned int [out] num_cschannel; 75 | unsigned int [out] n_layers; 76 | projection mem_ctl_info_edac_mc_layer* layers; 77 | bool [out] csbased; 78 | unsigned int [out] tot_dimms; 79 | projection mem_ctl_info_dimm_info** dimms; 80 | void* [out] pvt_info; 81 | array< unsigned int, 6> ce_per_layer; 82 | array< unsigned int, 6> ue_per_layer; 83 | int [out] op_state; 84 | } 85 | projection < struct edac_mc_layer > ret_mem_ctl_info_edac_mc_layer { 86 | } 87 | projection < struct dimm_info > ret_mem_ctl_info_dimm_info { 88 | } 89 | projection < struct edac_mc_layer > edac_mc_layer { 90 | unsigned int [in,out] type; 91 | bool [in,out] is_virt_csrow; 92 | } 93 | } 94 | rpc projection ret_mem_ctl_info* edac_mc_del_mc( projection device *dev ) { 95 | projection < struct mem_ctl_info > ret_mem_ctl_info { 96 | int mc_idx; 97 | char* mod_name; 98 | char* ctl_name; 99 | char* dev_name; 100 | int [out] op_state; 101 | } 102 | projection < struct device > device { 103 | } 104 | } 105 | rpc void edac_mc_free( projection mem_ctl_info [in] *mci ) { 106 | projection < struct mem_ctl_info > mem_ctl_info { 107 | u64 [in] scrub_cap; 108 | unsigned int [in] nr_csrows; 109 | unsigned int [in] num_cschannel; 110 | unsigned int [in] tot_dimms; 111 | projection mem_ctl_info_dimm_info** dimms; 112 | } 113 | projection < struct dimm_info > mem_ctl_info_dimm_info { 114 | unsigned int [in] grain; 115 | } 116 | } 117 | rpc void edac_mc_handle_error( unsigned int type, projection mem_ctl_info [in,out] *mci, unsigned short error_count, u64 page_frame_number, u64 offset_in_page, u64 syndrome, int top_layer, int mid_layer, int low_layer, string [in,out] *msg, string [in,out] *other_detail ) { 118 | projection < struct dev> dev { 119 | projection device* parent; 120 | } 121 | projection < struct error_desc> error_desc { 122 | array< char, 256> [in] location; 123 | array< char, 296> [in] label; 124 | u64 [in,out] grain; 125 | unsigned short [in,out] error_count; 126 | int [in,out] top_layer; 127 | int [in,out] mid_layer; 128 | int [in,out] low_layer; 129 | u64 [in,out] page_frame_number; 130 | u64 [in,out] offset_in_page; 131 | u64 [in,out] syndrome; 132 | char* [in,out] msg; 133 | char* [in,out] other_detail; 134 | bool [in,out] enable_per_layer_report; 135 | } 136 | projection < struct mem_ctl_info > mem_ctl_info { 137 | projection dev dev; 138 | u64 [in,out] mtype_cap; 139 | u64 [in,out] scrub_cap; 140 | unsigned int [in,out] scrub_mode; 141 | int [in,out] mc_idx; 142 | unsigned int [in,out] nr_csrows; 143 | unsigned int [in,out] n_layers; 144 | projection mem_ctl_info_edac_mc_layer* layers; 145 | bool [in,out] csbased; 146 | unsigned int [in,out] tot_dimms; 147 | projection mem_ctl_info_dimm_info** dimms; 148 | unsigned int [in,out] ce_noinfo_count; 149 | unsigned int [in,out] ue_noinfo_count; 150 | unsigned int [in,out] ue_mc; 151 | unsigned int [in,out] ce_mc; 152 | array< unsigned int, 6> [in] ce_per_layer; 153 | array< unsigned int, 6> [in] ue_per_layer; 154 | projection error_desc error_desc; 155 | } 156 | projection < struct edac_mc_layer > mem_ctl_info_edac_mc_layer { 157 | unsigned int [in,out] type; 158 | } 159 | projection < struct dev> dev { 160 | array parent; 161 | array pm_domain; 162 | } 163 | projection < struct dimm_info > mem_ctl_info_dimm_info { 164 | projection dev dev; 165 | array< char, 32> [in,out] label; 166 | array< unsigned int, 3> [in,out] location; 167 | unsigned int [in,out] grain; 168 | unsigned int [in,out] mtype; 169 | unsigned int [in,out] edac_mode; 170 | unsigned int [in,out] nr_pages; 171 | unsigned int [in,out] csrow; 172 | unsigned int [in,out] cschannel; 173 | } 174 | projection < struct device > device_device { 175 | } 176 | } 177 | rpc void* kmalloc_order( u64 size, unsigned int flags, unsigned int order ) { 178 | } 179 | rpc void mce_register_decode_chain( ) { 180 | } 181 | rpc void mce_unregister_decode_chain( ) { 182 | } 183 | rpc int pci_bus_read_config_dword( projection pci_bus [in] *bus, unsigned int devfn, int pos, unsigned int [out] *value ) { 184 | projection < struct pci_bus > pci_bus { 185 | } 186 | } 187 | rpc projection ret_pci_dev* pci_dev_get( projection pci_dev [in] *dev ) { 188 | projection < struct pci_dev > ret_pci_dev { 189 | } 190 | projection < struct pci_dev > pci_dev { 191 | } 192 | } 193 | rpc void pci_dev_put( projection pci_dev [in] *dev ) { 194 | projection < struct pci_dev > pci_dev { 195 | } 196 | } 197 | rpc int pci_enable_device( projection pci_dev [in] *dev ) { 198 | projection < struct pci_dev > pci_dev { 199 | projection pci_dev_pci_bus* bus; 200 | projection pci_dev_pci_bus* subordinate; 201 | unsigned int [in] devfn; 202 | int [in,out] current_state; 203 | unsigned char [in] pm_cap; 204 | unsigned int [in] pme_support : 5; 205 | unsigned int [in] d3_delay; 206 | unsigned int [in] d3cold_delay; 207 | array< projection resource, 11> [in] resource; 208 | unsigned int [in] msi_enabled : 1; 209 | unsigned int [in] msix_enabled : 1; 210 | unsigned int [in] is_virtfn : 1; 211 | unsigned short [in] dev_flags; 212 | } 213 | projection < struct pci_bus > pci_dev_pci_bus { 214 | projection pci_bus* parent; 215 | projection pci_bus_pci_dev* self; 216 | } 217 | projection < struct pci_bus > pci_dev_pci_bus { 218 | } 219 | projection < struct pci_dev > pci_bus_pci_dev { 220 | } 221 | } 222 | rpc projection ret_pci_dev* pci_get_device( unsigned int vendor, unsigned int device, projection pci_dev [in] *from ) { 223 | projection < struct pci_dev > ret_pci_dev { 224 | } 225 | projection < struct pci_dev > pci_dev { 226 | } 227 | } 228 | rpc int simple_attr_open( projection inode [in] *inode, projection file [in] *file, rpc_ptr get get, rpc_ptr set set, char *fmt ) { 229 | projection < struct inode > inode { 230 | void* [in] i_private; 231 | } 232 | projection < struct file > file { 233 | void* [out] private_data; 234 | } 235 | } 236 | rpc projection ret_x86_cpu_id* x86_match_cpu( projection x86_cpu_id [in] *match ) { 237 | projection < struct x86_cpu_id > ret_x86_cpu_id { 238 | unsigned short vendor; 239 | unsigned short family; 240 | unsigned short model; 241 | unsigned short feature; 242 | } 243 | projection < struct x86_cpu_id > x86_cpu_id { 244 | unsigned short [in] vendor; 245 | unsigned short [in] family; 246 | unsigned short [in] model; 247 | unsigned short [in] feature; 248 | } 249 | } 250 | rpc u64 generic_file_llseek( projection file [in] *file, u64 offset, int whence ) { 251 | projection < struct file > file { 252 | unsigned int [in] f_mode; 253 | u64 [in,out] f_pos; 254 | u64 [out] f_version; 255 | } 256 | } 257 | rpc u64 simple_attr_write( projection file [in] *file, char [user] *buf, u64 len, u64 [unused] *ppos ) { 258 | projection < struct file > file { 259 | void* [in] private_data; 260 | } 261 | } 262 | rpc u64 simple_attr_read( projection file [in] *file, char [user] *buf, u64 len, u64 [in,out] *ppos ) { 263 | projection < struct file > file { 264 | void* [in] private_data; 265 | } 266 | } 267 | rpc int simple_attr_release( projection inode [unused] *inode, projection file [in] *file ) { 268 | projection < struct inode > inode { 269 | } 270 | projection < struct file > file { 271 | void* [in] private_data; 272 | } 273 | } 274 | rpc_ptr int skx_mce_check_error( projection _global_notifier_block [unused] nb, u64 [unused] val, void [in] *data ) { 275 | } 276 | rpc_ptr int fops_u64_wo_open( projection inode *inode, projection file *file ) { 277 | projection < struct inode > inode { 278 | } 279 | projection < struct file > file { 280 | } 281 | } 282 | projection < struct file_operations > _global_file_operations { 283 | rpc_ptr fops_u64_wo_open open; 284 | rpc_ptr generic_file_llseek llseek; 285 | rpc_ptr simple_attr_read read; 286 | rpc_ptr simple_attr_release release; 287 | rpc_ptr simple_attr_write write; 288 | } 289 | projection < struct notifier_block > _global_notifier_block { 290 | rpc_ptr skx_mce_check_error notifier_call; 291 | } 292 | 293 | 294 | } 295 | -------------------------------------------------------------------------------- /table_3_IDL/net/alx.idl: -------------------------------------------------------------------------------- 1 | // Sync stubs for boundary functions 2 | module kernel { 3 | rpc void __const_udelay( u64 xloops ) { 4 | } 5 | rpc void __dev_kfree_skb_any( projection sk_buff [in,out] *skb, unsigned int reason ) { 6 | projection < struct users> users { 7 | int [in,out] counter; 8 | } 9 | projection < struct sk_buff > sk_buff { 10 | projection sk_buff_net_device* dev; 11 | array< char, 48> [in,out] cb; 12 | u64 [in,out] _skb_refdst; 13 | unsigned char [in] cloned : 1; 14 | unsigned char [in] nohdr : 1; 15 | unsigned char [in] fclone : 2; 16 | unsigned char [in] head_frag : 1; 17 | unsigned char [in] private : 1; 18 | unsigned int [in] end; 19 | unsigned char* [in] head; 20 | projection users users; 21 | } 22 | projection < struct net_device > sk_buff_net_device { 23 | array< char, 16> [in] name; 24 | char* [in] ifalias; 25 | u64 [in] mem_end; 26 | u64 [in] mem_start; 27 | } 28 | } 29 | rpc void __dynamic_dev_dbg( projection _ddebug [in] *descriptor, projection device [in] *dev, char [in] *fmt ) { 30 | projection < struct _ddebug > _ddebug { 31 | char* [in] modname; 32 | char* [in] function; 33 | unsigned int [in] lineno : 18; 34 | unsigned int [in] flags : 8; 35 | } 36 | projection < struct device > device { 37 | char* [in] init_name; 38 | } 39 | } 40 | rpc void __local_bh_enable_ip( u64 [unused] ip, unsigned int cnt ) { 41 | } 42 | rpc void __napi_schedule( projection napi_struct *n ) { 43 | projection < struct napi_struct > napi_struct { 44 | } 45 | } 46 | rpc projection ret_sk_buff* __netdev_alloc_skb( projection net_device *dev, unsigned int len, unsigned int gfp_mask ) { 47 | projection < struct sk_buff > ret_sk_buff { 48 | projection sk_buff_net_device* dev; 49 | unsigned char cloned : 1; 50 | array headers_start; 51 | array __pkt_type_offset; 52 | unsigned char pkt_type : 3; 53 | } 54 | projection < struct net_device > ret_sk_buff_net_device { 55 | } 56 | projection < struct net_device > net_device { 57 | } 58 | } 59 | rpc int __pci_register_driver( projection _global_pci_driver [in] drv, projection module *owner, char *mod_name ) { 60 | projection < struct node> node { 61 | projection list_head* next; 62 | } 63 | projection < struct driver> driver { 64 | char* [out] name; 65 | char* [out] mod_name; 66 | } 67 | projection < struct pci_device_id > pci_driver_pci_device_id { 68 | } 69 | projection < struct module > module { 70 | } 71 | } 72 | rpc void __raw_spin_lock_init( projection raw_spinlock [in] *lock, char [unused] *name, projection lock_class_key [unused] *key ) { 73 | projection < struct raw_spinlock > raw_spinlock { 74 | unsigned int [in,out] magic; 75 | unsigned int [in,out] owner_cpu; 76 | void* [in,out] owner; 77 | } 78 | projection < struct lock_class_key > lock_class_key { 79 | } 80 | } 81 | rpc void _dev_info( projection device [in] *dev, char *fmt ) { 82 | projection < struct device > device { 83 | char* [in] init_name; 84 | } 85 | } 86 | rpc void _raw_spin_unlock( projection raw_spinlock [in,out] *lock ) { 87 | projection < struct raw_spinlock > raw_spinlock { 88 | unsigned int [in] magic; 89 | unsigned int [in,out] owner_cpu; 90 | void* [in,out] owner; 91 | } 92 | } 93 | rpc projection ret_net_device* alloc_etherdev_mqs( int sizeof_priv, unsigned int txqs, unsigned int rxqs ) { 94 | projection < struct net_device > ret_net_device { 95 | } 96 | } 97 | rpc bool cancel_work_sync( projection work_struct [in,out] *work ) { 98 | projection < struct data> data { 99 | u64 [in,out] counter; 100 | } 101 | projection < struct entry> entry { 102 | projection list_head* next; 103 | projection list_head* prev; 104 | } 105 | projection < struct work_struct > work_struct { 106 | projection data data; 107 | projection entry entry; 108 | } 109 | } 110 | rpc void consume_skb( projection sk_buff [in] *skb ) { 111 | projection < struct users> users { 112 | int [in,out] counter; 113 | } 114 | projection < struct sk_buff > sk_buff { 115 | projection sk_buff_net_device* dev; 116 | array< char, 48> [in] cb; 117 | u64 [in,out] _skb_refdst; 118 | unsigned char [in] cloned : 1; 119 | unsigned char [in] nohdr : 1; 120 | unsigned char [in] fclone : 2; 121 | unsigned char [in] head_frag : 1; 122 | unsigned char [in] private : 1; 123 | unsigned int [in] end; 124 | unsigned char* [in] head; 125 | projection users users; 126 | } 127 | projection < struct net_device > sk_buff_net_device { 128 | array< char, 16> [in] name; 129 | char* [in] ifalias; 130 | u64 [in] mem_end; 131 | u64 [in] mem_start; 132 | } 133 | } 134 | rpc unsigned int crc32_le( unsigned int [in] crc, unsigned char [in] *p, u64 len ) { 135 | } 136 | rpc void dev_err( projection device [in] *dev, char *fmt ) { 137 | projection < struct device > device { 138 | char* [in] init_name; 139 | } 140 | } 141 | rpc void dev_warn( projection device [in] *dev, char *fmt ) { 142 | projection < struct device > device { 143 | char* [in] init_name; 144 | } 145 | } 146 | rpc void free_irq( unsigned int irq, void *dev_id ) { 147 | } 148 | rpc void free_netdev( projection net_device [in] *dev ) { 149 | projection < struct napi_list> napi_list { 150 | projection list_head* next; 151 | projection list_head* prev; 152 | } 153 | projection < struct close_list> close_list { 154 | projection list_head* next; 155 | projection list_head* prev; 156 | } 157 | projection < struct dev> dev { 158 | projection device* parent; 159 | char* [in] init_name; 160 | projection mutex mutex; 161 | void* [in] platform_data; 162 | void* [in] driver_data; 163 | long long unsigned int* [in] dma_mask; 164 | u64 [in] coherent_dma_mask; 165 | u64 [in] dma_pfn_offset; 166 | unsigned int [in] devt; 167 | unsigned int [in] id; 168 | bool [in] offline_disabled : 1; 169 | bool [in] offline : 1; 170 | } 171 | projection < struct mutex> mutex { 172 | projection count count; 173 | } 174 | projection < struct count> count { 175 | int [in,out] counter; 176 | } 177 | projection < struct net_device > net_device { 178 | projection napi_list napi_list; 179 | projection close_list close_list; 180 | unsigned short [in] padded; 181 | projection net_device_netdev_queue* ingress_queue; 182 | projection net_device_netdev_queue* _tx; 183 | int* [in,out] pcpu_refcnt; 184 | unsigned int [in,out] reg_state : 8; 185 | projection dev dev; 186 | } 187 | projection < struct netdev_queue > net_device_netdev_queue { 188 | u64 [in] trans_timeout; 189 | } 190 | projection < struct netdev_queue > net_device_netdev_queue { 191 | } 192 | } 193 | rpc void* kmalloc_order( u64 size, unsigned int flags, unsigned int order ) { 194 | } 195 | rpc int mdio_mii_ioctl( projection mdio_if_info [in] *mdio, projection mii_ioctl_data [in,out] *mii_data, int cmd ) { 196 | projection < struct mdio_if_info > mdio_if_info { 197 | int [in] prtad; 198 | unsigned int [in] mmds; 199 | unsigned int [in] mode_support; 200 | projection mdio_if_info_net_device* dev; 201 | } 202 | projection < struct net_device > mdio_if_info_net_device { 203 | } 204 | projection < struct mii_ioctl_data > mii_ioctl_data { 205 | unsigned short [in,out] phy_id; 206 | unsigned short [in] reg_num; 207 | unsigned short [in] val_in; 208 | unsigned short [out] val_out; 209 | } 210 | } 211 | rpc void napi_complete_done( projection napi_struct [in,out] *n, int work_done ) { 212 | projection < struct poll_list> poll_list { 213 | projection list_head* next; 214 | projection list_head* prev; 215 | } 216 | projection < struct napi_struct > napi_struct { 217 | projection poll_list poll_list; 218 | u64 [in,out] state; 219 | int [in,out] weight; 220 | unsigned int [in,out] gro_count; 221 | projection napi_struct_net_device* dev; 222 | projection napi_struct_sk_buff* gro_list; 223 | } 224 | projection < struct net_device > napi_struct_net_device { 225 | array< char, 16> [in,out] name; 226 | u64 [in,out] mem_end; 227 | u64 [in,out] mem_start; 228 | u64 [in] gro_flush_timeout; 229 | } 230 | projection < struct users> users { 231 | int [in,out] counter; 232 | } 233 | projection < struct sk_buff > napi_struct_sk_buff { 234 | projection sk_buff_net_device* dev; 235 | array< char, 48> [in,out] cb; 236 | u64 [in,out] _skb_refdst; 237 | unsigned int [in,out] len; 238 | unsigned int [in,out] data_len; 239 | unsigned short [in,out] mac_len; 240 | unsigned short [in,out] hdr_len; 241 | unsigned short [in,out] queue_mapping; 242 | unsigned char [in,out] cloned : 1; 243 | unsigned char [in,out] nohdr : 1; 244 | unsigned char [in,out] fclone : 2; 245 | unsigned char [in,out] head_frag : 1; 246 | unsigned char [in,out] private : 1; 247 | array [in,out] headers_start; 248 | array [in,out] __pkt_type_offset; 249 | unsigned char [in,out] pkt_type : 3; 250 | unsigned char [in] pfmemalloc : 1; 251 | unsigned char [in] nf_trace : 1; 252 | unsigned char [in,out] ip_summed : 2; 253 | unsigned char [in] l4_hash : 1; 254 | unsigned char [in] sw_hash : 1; 255 | int [in,out] skb_iif; 256 | unsigned int [in] hash; 257 | unsigned short [out] vlan_proto; 258 | unsigned short [in,out] vlan_tci; 259 | unsigned short [in,out] inner_transport_header; 260 | unsigned short [in,out] inner_network_header; 261 | unsigned short [in,out] inner_mac_header; 262 | unsigned short [in,out] protocol; 263 | unsigned short [in,out] transport_header; 264 | unsigned short [in,out] network_header; 265 | unsigned short [in,out] mac_header; 266 | array [in,out] headers_end; 267 | unsigned int [in,out] tail; 268 | unsigned int [in,out] end; 269 | unsigned char* [in,out] head; 270 | unsigned char* [in,out] data; 271 | unsigned int [in,out] truesize; 272 | projection users users; 273 | } 274 | projection < struct net_device > sk_buff_net_device { 275 | array< char, 16> [in,out] name; 276 | char* [in,out] ifalias; 277 | u64 [in,out] mem_end; 278 | u64 [in] mem_start; 279 | u64 [in] state; 280 | u64 [in,out] features; 281 | u64 [in,out] hw_enc_features; 282 | int [in,out] ifindex; 283 | projection _global_net_device_ops* netdev_ops; 284 | unsigned int [in,out] real_num_rx_queues; 285 | } 286 | } 287 | rpc void napi_disable( projection napi_struct [in] *n ) { 288 | projection < struct napi_struct > napi_struct { 289 | u64 [in] state; 290 | } 291 | } 292 | rpc unsigned int napi_gro_receive( projection napi_struct [in] *napi, projection sk_buff [in,out] *skb ) { 293 | projection < struct napi_struct > napi_struct { 294 | unsigned int [in,out] gro_count; 295 | projection napi_struct_sk_buff* gro_list; 296 | } 297 | projection < struct users> users { 298 | int [in,out] counter; 299 | } 300 | projection < struct sk_buff > napi_struct_sk_buff { 301 | projection sk_buff_net_device* dev; 302 | array< char, 48> [in,out] cb; 303 | u64 [in,out] _skb_refdst; 304 | unsigned int [in,out] len; 305 | unsigned int [in,out] data_len; 306 | unsigned short [in,out] mac_len; 307 | unsigned short [in,out] hdr_len; 308 | unsigned short [in,out] queue_mapping; 309 | unsigned char [in,out] cloned : 1; 310 | unsigned char [in,out] nohdr : 1; 311 | unsigned char [in,out] fclone : 2; 312 | unsigned char [in,out] head_frag : 1; 313 | unsigned char [in,out] private : 1; 314 | array [in,out] headers_start; 315 | array [in,out] __pkt_type_offset; 316 | unsigned char [in,out] pkt_type : 3; 317 | unsigned char [in] pfmemalloc : 1; 318 | unsigned char [in] nf_trace : 1; 319 | unsigned char [in,out] ip_summed : 2; 320 | unsigned char [in] l4_hash : 1; 321 | unsigned char [in] sw_hash : 1; 322 | int [in,out] skb_iif; 323 | unsigned int [in] hash; 324 | unsigned short [out] vlan_proto; 325 | unsigned short [in,out] vlan_tci; 326 | unsigned short [in,out] inner_transport_header; 327 | unsigned short [in,out] inner_network_header; 328 | unsigned short [in,out] inner_mac_header; 329 | unsigned short [in,out] protocol; 330 | unsigned short [in,out] transport_header; 331 | unsigned short [in,out] network_header; 332 | unsigned short [in,out] mac_header; 333 | array [in,out] headers_end; 334 | unsigned int [in,out] tail; 335 | unsigned int [in,out] end; 336 | unsigned char* [in,out] head; 337 | unsigned char* [in,out] data; 338 | unsigned int [in,out] truesize; 339 | projection users users; 340 | } 341 | projection < struct net_device > sk_buff_net_device { 342 | array< char, 16> [in,out] name; 343 | char* [in,out] ifalias; 344 | u64 [in,out] mem_end; 345 | u64 [in] mem_start; 346 | u64 [in] state; 347 | u64 [in,out] features; 348 | u64 [in,out] hw_enc_features; 349 | int [in,out] ifindex; 350 | projection _global_net_device_ops* netdev_ops; 351 | unsigned int [in,out] real_num_rx_queues; 352 | } 353 | projection < struct users> users { 354 | int [in,out] counter; 355 | } 356 | projection < struct sk_buff > sk_buff { 357 | projection sk_buff_net_device* dev; 358 | array< char, 48> [in,out] cb; 359 | u64 [in,out] _skb_refdst; 360 | unsigned int [in,out] len; 361 | unsigned int [in,out] data_len; 362 | unsigned short [in,out] mac_len; 363 | unsigned short [in,out] hdr_len; 364 | unsigned short [in,out] queue_mapping; 365 | unsigned char [in,out] cloned : 1; 366 | unsigned char [in,out] nohdr : 1; 367 | unsigned char [in,out] fclone : 2; 368 | unsigned char [in,out] head_frag : 1; 369 | unsigned char [in,out] private : 1; 370 | array [in,out] headers_start; 371 | array [in,out] __pkt_type_offset; 372 | unsigned char [in,out] pkt_type : 3; 373 | unsigned char [in] pfmemalloc : 1; 374 | unsigned char [in] nf_trace : 1; 375 | unsigned char [in,out] ip_summed : 2; 376 | unsigned char [in] l4_hash : 1; 377 | unsigned char [in] sw_hash : 1; 378 | int [in,out] skb_iif; 379 | unsigned int [in] hash; 380 | unsigned short [out] vlan_proto; 381 | unsigned short [in,out] vlan_tci; 382 | unsigned short [in,out] inner_transport_header; 383 | unsigned short [in,out] inner_network_header; 384 | unsigned short [in,out] inner_mac_header; 385 | unsigned short [in,out] protocol; 386 | unsigned short [in,out] transport_header; 387 | unsigned short [in,out] network_header; 388 | unsigned short [in,out] mac_header; 389 | array [in,out] headers_end; 390 | unsigned int [in,out] tail; 391 | unsigned int [in,out] end; 392 | unsigned char* [in,out] head; 393 | unsigned char* [in,out] data; 394 | unsigned int [in,out] truesize; 395 | projection users users; 396 | } 397 | projection < struct napi_list> napi_list { 398 | projection list_head* next; 399 | projection list_head* prev; 400 | } 401 | projection < struct unreg_list> unreg_list { 402 | projection list_head* next; 403 | projection list_head* prev; 404 | } 405 | projection < struct ptype_all> ptype_all { 406 | projection list_head* next; 407 | } 408 | projection < struct ptype_specific> ptype_specific { 409 | projection list_head* next; 410 | } 411 | projection < struct rx_dropped> rx_dropped { 412 | u64 [in,out] counter; 413 | } 414 | projection < struct rx_nohandler> rx_nohandler { 415 | u64 [in,out] counter; 416 | } 417 | projection < struct net_device > sk_buff_net_device { 418 | array< char, 16> [in,out] name; 419 | char* [in,out] ifalias; 420 | u64 [in,out] mem_end; 421 | u64 [in] mem_start; 422 | u64 [in] state; 423 | projection napi_list napi_list; 424 | projection unreg_list unreg_list; 425 | projection ptype_all ptype_all; 426 | projection ptype_specific ptype_specific; 427 | u64 [in,out] features; 428 | u64 [in,out] hw_enc_features; 429 | int [in,out] ifindex; 430 | projection rx_dropped rx_dropped; 431 | projection rx_nohandler rx_nohandler; 432 | projection _global_net_device_ops* netdev_ops; 433 | unsigned int [in,out] real_num_rx_queues; 434 | } 435 | } 436 | rpc void netdev_info( projection net_device [in] *dev, char *fmt ) { 437 | projection < struct dev> dev { 438 | projection device* parent; 439 | } 440 | projection < struct net_device > net_device { 441 | array< char, 16> [in] name; 442 | unsigned int [in] reg_state : 8; 443 | projection dev dev; 444 | } 445 | } 446 | rpc void netdev_update_features( projection net_device [in] *dev ) { 447 | projection < struct adj_list> adj_list { 448 | projection upper upper; 449 | projection lower lower; 450 | } 451 | projection < struct upper> upper { 452 | projection list_head* next; 453 | projection list_head* prev; 454 | } 455 | projection < struct lower> lower { 456 | projection list_head* next; 457 | } 458 | projection < struct stats> stats { 459 | u64 [in] rx_bytes; 460 | u64 [in] tx_compressed; 461 | } 462 | projection < struct net_device > net_device { 463 | array< char, 16> [in] name; 464 | projection adj_list adj_list; 465 | u64 [in,out] features; 466 | u64 [in] hw_features; 467 | u64 [in] wanted_features; 468 | u64 [in] gso_partial_features; 469 | int [in] ifindex; 470 | projection stats stats; 471 | projection _global_net_device_ops* netdev_ops; 472 | } 473 | } 474 | rpc void netdev_warn( projection net_device [in] *dev, char *fmt ) { 475 | projection < struct dev> dev { 476 | projection device* parent; 477 | } 478 | projection < struct net_device > net_device { 479 | array< char, 16> [in] name; 480 | unsigned int [in] reg_state : 8; 481 | projection dev dev; 482 | } 483 | } 484 | rpc void netif_carrier_off( projection net_device [in] *dev ) { 485 | projection < struct net_device > net_device { 486 | unsigned int [in] reg_state : 8; 487 | } 488 | } 489 | rpc void netif_carrier_on( projection net_device [in] *dev ) { 490 | projection < struct net_device > net_device { 491 | u64 [in] state; 492 | projection _global_net_device_ops* netdev_ops; 493 | int [in,out] watchdog_timeo; 494 | int* [in] pcpu_refcnt; 495 | unsigned int [in] reg_state : 8; 496 | } 497 | } 498 | rpc void netif_device_attach( projection net_device [in] *dev ) { 499 | projection < struct net_device > net_device { 500 | u64 [in] state; 501 | projection _global_net_device_ops* netdev_ops; 502 | projection _netdev_queue* _tx; 503 | unsigned int [in] num_tx_queues; 504 | int [in,out] watchdog_timeo; 505 | int* [in] pcpu_refcnt; 506 | } 507 | projection < struct netdev_queue > net_device_netdev_queue { 508 | } 509 | } 510 | rpc void netif_device_detach( projection net_device [in] *dev ) { 511 | projection < struct net_device > net_device { 512 | u64 [in] state; 513 | projection net_device_netdev_queue* _tx; 514 | unsigned int [in] num_tx_queues; 515 | } 516 | projection < struct netdev_queue > net_device_netdev_queue { 517 | } 518 | } 519 | rpc void netif_napi_add( projection net_device [in] *dev, projection napi_struct [in,out] *napi, rpc_ptr poll poll, int weight ) { 520 | projection < struct net_device > net_device { 521 | array< char, 16> [in] name; 522 | } 523 | projection < struct napi_struct > napi_struct { 524 | u64 [in] state; 525 | int [out] weight; 526 | unsigned int [out] gro_count; 527 | projection napi_struct_net_device* dev; 528 | projection napi_struct_sk_buff* gro_list; 529 | projection napi_struct_sk_buff* skb; 530 | unsigned int [in,out] napi_id; 531 | } 532 | projection < struct net_device > napi_struct_net_device { 533 | } 534 | projection < struct sk_buff > napi_struct_sk_buff { 535 | } 536 | projection < struct sk_buff > napi_struct_sk_buff { 537 | } 538 | } 539 | rpc void netif_napi_del( projection napi_struct [in] *napi ) { 540 | projection < struct napi_struct > napi_struct { 541 | unsigned int [out] gro_count; 542 | projection napi_struct_sk_buff* gro_list; 543 | projection napi_struct_sk_buff* skb; 544 | } 545 | projection < struct users> users { 546 | int [in,out] counter; 547 | } 548 | projection < struct sk_buff > napi_struct_sk_buff { 549 | projection sk_buff_net_device* dev; 550 | array< char, 48> [in] cb; 551 | u64 [in,out] _skb_refdst; 552 | unsigned char [in] cloned : 1; 553 | unsigned char [in] nohdr : 1; 554 | unsigned char [in] fclone : 2; 555 | unsigned char [in] head_frag : 1; 556 | unsigned char [in] private : 1; 557 | unsigned int [in] end; 558 | unsigned char* [in] head; 559 | projection users users; 560 | } 561 | projection < struct users> users { 562 | int [in,out] counter; 563 | } 564 | projection < struct sk_buff > napi_struct_sk_buff { 565 | projection sk_buff_net_device* dev; 566 | array< char, 48> [in] cb; 567 | u64 [in,out] _skb_refdst; 568 | unsigned char [in] cloned : 1; 569 | unsigned char [in] nohdr : 1; 570 | unsigned char [in] fclone : 2; 571 | unsigned char [in] head_frag : 1; 572 | unsigned char [in] private : 1; 573 | unsigned int [in] end; 574 | unsigned char* [in] head; 575 | projection users users; 576 | } 577 | projection < struct net_device > sk_buff_net_device { 578 | array< char, 16> [in] name; 579 | char* [in] ifalias; 580 | u64 [in] mem_end; 581 | u64 [in] mem_start; 582 | } 583 | projection < struct net_device > sk_buff_net_device { 584 | array< char, 16> [in] name; 585 | char* [in] ifalias; 586 | u64 [in] mem_end; 587 | u64 [in] mem_start; 588 | } 589 | } 590 | rpc void netif_schedule_queue( projection netdev_queue [in] *txq ) { 591 | projection < struct netdev_queue > netdev_queue { 592 | u64 [in] state; 593 | } 594 | } 595 | rpc void netif_tx_wake_queue( projection netdev_queue [in] *dev_queue ) { 596 | projection < struct netdev_queue > netdev_queue { 597 | u64 [in] state; 598 | } 599 | } 600 | rpc int pci_bus_read_config_word( projection pci_bus [in] *bus, unsigned int devfn, int pos, unsigned short [out] *value ) { 601 | projection < struct pci_bus > pci_bus { 602 | } 603 | } 604 | rpc int pci_bus_write_config_word( projection pci_bus [in] *bus, unsigned int devfn, int pos, unsigned short value ) { 605 | projection < struct pci_bus > pci_bus { 606 | } 607 | } 608 | rpc int pci_cleanup_aer_uncorrect_error_status( projection pci_dev [in] *dev ) { 609 | projection < struct pci_dev > pci_dev { 610 | projection pci_dev_pci_bus* bus; 611 | unsigned int [in] devfn; 612 | int [in] cfg_size; 613 | } 614 | projection < struct pci_bus > pci_dev_pci_bus { 615 | } 616 | } 617 | rpc void pci_disable_device( projection pci_dev [in] *dev ) { 618 | projection < struct pci_dev > pci_dev { 619 | projection pci_dev_pci_bus* bus; 620 | unsigned int [in] devfn; 621 | unsigned int [in,out] transparent : 1; 622 | unsigned int [in] is_managed : 1; 623 | } 624 | projection < struct pci_bus > pci_dev_pci_bus { 625 | } 626 | } 627 | rpc void pci_disable_msi( projection pci_dev [in] *dev ) { 628 | projection < struct dev> dev { 629 | projection device* parent; 630 | projection msi_list msi_list; 631 | } 632 | projection < struct msi_list> msi_list { 633 | projection list_head* next; 634 | } 635 | projection < struct pci_dev > pci_dev { 636 | projection pci_dev_pci_bus* bus; 637 | unsigned int [in] devfn; 638 | unsigned char [in] msi_cap; 639 | projection dev dev; 640 | unsigned int [out] irq; 641 | unsigned int [in,out] transparent : 1; 642 | unsigned int [in] msi_enabled : 1; 643 | unsigned int [in] is_managed : 1; 644 | unsigned short [in] dev_flags; 645 | } 646 | projection < struct pci_bus > pci_dev_pci_bus { 647 | } 648 | } 649 | rpc int pci_disable_pcie_error_reporting( projection pci_dev [in] *dev ) { 650 | projection < struct pci_dev > pci_dev { 651 | projection pci_dev_pci_bus* bus; 652 | unsigned int [in] devfn; 653 | unsigned char [in] pcie_cap; 654 | unsigned short [in] pcie_flags_reg; 655 | unsigned int [in] __aer_firmware_first_valid : 1; 656 | unsigned int [in] __aer_firmware_first : 1; 657 | } 658 | projection < struct pci_bus > pci_dev_pci_bus { 659 | } 660 | } 661 | rpc int pci_enable_device( projection pci_dev [in] *dev ) { 662 | projection < struct pci_dev > pci_dev { 663 | projection pci_dev_pci_bus* bus; 664 | projection pci_dev_pci_bus* subordinate; 665 | unsigned int [in] devfn; 666 | int [in,out] current_state; 667 | unsigned char [in] pm_cap; 668 | unsigned int [in] pme_support : 5; 669 | unsigned int [in] d3cold_delay; 670 | array< projection resource, 11> [in] resource; 671 | unsigned int [in] msi_enabled : 1; 672 | unsigned int [in] msix_enabled : 1; 673 | unsigned short [in] dev_flags; 674 | } 675 | projection < struct pci_bus > pci_dev_pci_bus { 676 | projection pci_bus* parent; 677 | projection pci_bus_pci_dev* self; 678 | } 679 | projection < struct pci_bus > pci_dev_pci_bus { 680 | } 681 | projection < struct pci_dev > pci_bus_pci_dev { 682 | } 683 | } 684 | rpc int pci_enable_device_mem( projection pci_dev [in] *dev ) { 685 | projection < struct pci_dev > pci_dev { 686 | projection pci_dev_pci_bus* bus; 687 | projection pci_dev_pci_bus* subordinate; 688 | unsigned int [in] devfn; 689 | int [in,out] current_state; 690 | unsigned char [in] pm_cap; 691 | unsigned int [in] pme_support : 5; 692 | unsigned int [in] d3cold_delay; 693 | array< projection resource, 11> [in] resource; 694 | unsigned int [in] msi_enabled : 1; 695 | unsigned int [in] msix_enabled : 1; 696 | unsigned short [in] dev_flags; 697 | } 698 | projection < struct pci_bus > pci_dev_pci_bus { 699 | projection pci_bus* parent; 700 | projection pci_bus_pci_dev* self; 701 | } 702 | projection < struct pci_bus > pci_dev_pci_bus { 703 | } 704 | projection < struct pci_dev > pci_bus_pci_dev { 705 | } 706 | } 707 | rpc int pci_enable_msi_range( projection pci_dev [in] *dev, int minvec, int maxvec ) { 708 | projection < struct pci_dev > pci_dev { 709 | projection pci_dev_pci_bus* bus; 710 | int [in] current_state; 711 | unsigned int [in] no_msi : 1; 712 | unsigned int [in] msi_enabled : 1; 713 | unsigned int [in] msix_enabled : 1; 714 | } 715 | projection < struct pci_bus > pci_dev_pci_bus { 716 | projection pci_bus* parent; 717 | unsigned short [in] bus_flags; 718 | } 719 | } 720 | rpc int pci_enable_pcie_error_reporting( projection pci_dev [in] *dev ) { 721 | projection < struct pci_dev > pci_dev { 722 | projection pci_dev_pci_bus* bus; 723 | unsigned int [in] devfn; 724 | unsigned char [in] pcie_cap; 725 | unsigned short [in] pcie_flags_reg; 726 | int [in] cfg_size; 727 | unsigned int [in] __aer_firmware_first_valid : 1; 728 | unsigned int [in] __aer_firmware_first : 1; 729 | } 730 | projection < struct pci_bus > pci_dev_pci_bus { 731 | } 732 | } 733 | rpc void* pci_ioremap_bar( projection pci_dev [in] *pdev, int bar ) { 734 | projection < struct pci_dev > pci_dev { 735 | array< projection resource, 11> [in] resource; 736 | } 737 | } 738 | rpc void pci_release_selected_regions( projection pci_dev [in] *pdev, int bars ) { 739 | projection < struct pci_dev > pci_dev { 740 | array< projection resource, 11> [in] resource; 741 | unsigned int [in] is_managed : 1; 742 | } 743 | } 744 | rpc int pci_request_selected_regions( projection pci_dev [in] *pdev, int bars, char *res_name ) { 745 | projection < struct pci_dev > pci_dev { 746 | array< projection resource, 11> [in] resource; 747 | unsigned int [in] is_managed : 1; 748 | } 749 | } 750 | rpc int pci_select_bars( projection pci_dev [in] *dev, u64 flags ) { 751 | projection < struct pci_dev > pci_dev { 752 | array< projection resource, 11> [in] resource; 753 | } 754 | } 755 | rpc void pci_set_master( projection pci_dev [in] *dev ) { 756 | projection < struct pci_dev > pci_dev { 757 | projection pci_dev_pci_bus* bus; 758 | unsigned int [in] devfn; 759 | unsigned char [in] pcie_cap; 760 | unsigned int [in,out] transparent : 1; 761 | } 762 | projection < struct pci_bus > pci_dev_pci_bus { 763 | } 764 | } 765 | rpc void pci_unregister_driver( projection _global_pci_driver [in,out] drv ) { 766 | projection < struct node> node { 767 | projection list_head* next; 768 | projection list_head* prev; 769 | } 770 | projection < struct dynids> dynids { 771 | projection list list; 772 | } 773 | projection < struct list> list { 774 | projection list_head* next; 775 | projection list_head* prev; 776 | } 777 | projection < struct pci_device_id > pci_driver_pci_device_id { 778 | } 779 | } 780 | rpc int pcie_get_readrq( projection pci_dev [in] *dev ) { 781 | projection < struct pci_dev > pci_dev { 782 | projection pci_dev_pci_bus* bus; 783 | unsigned int [in] devfn; 784 | unsigned char [in] pcie_cap; 785 | unsigned short [in] pcie_flags_reg; 786 | } 787 | projection < struct pci_bus > pci_dev_pci_bus { 788 | } 789 | } 790 | rpc int pcie_set_readrq( projection pci_dev [in] *dev, int rq ) { 791 | projection < struct pci_dev > pci_dev { 792 | projection pci_dev_pci_bus* bus; 793 | unsigned int [in] devfn; 794 | unsigned char [in] pcie_cap; 795 | unsigned short [in] pcie_flags_reg; 796 | } 797 | projection < struct pci_bus > pci_dev_pci_bus { 798 | } 799 | } 800 | rpc bool queue_work_on( int cpu, projection workqueue_struct [in,out] *wq, projection work_struct [in] *work ) { 801 | projection < struct workqueue_struct > workqueue_struct { 802 | array< char, 24> [in] name; 803 | unsigned int [in] flags; 804 | array [in,out] numa_pwq_tbl; 805 | } 806 | projection < struct work_struct > work_struct { 807 | } 808 | } 809 | rpc int register_netdev( projection net_device [in,out] *dev ) { 810 | projection < struct unreg_list> unreg_list { 811 | projection list_head* next; 812 | projection list_head* prev; 813 | } 814 | projection < struct ptype_all> ptype_all { 815 | projection list_head* next; 816 | projection list_head* prev; 817 | } 818 | projection < struct ptype_specific> ptype_specific { 819 | projection list_head* next; 820 | projection list_head* prev; 821 | } 822 | projection < struct adj_list> adj_list { 823 | projection upper upper; 824 | projection lower lower; 825 | } 826 | projection < struct upper> upper { 827 | projection list_head* next; 828 | projection list_head* prev; 829 | } 830 | projection < struct lower> lower { 831 | projection list_head* next; 832 | } 833 | projection < struct stats> stats { 834 | u64 [in] tx_compressed; 835 | } 836 | projection < struct watchdog_timer> watchdog_timer { 837 | u64 [out] data; 838 | } 839 | projection < struct dev> dev { 840 | projection device* parent; 841 | char* [in] init_name; 842 | void* [in] platform_data; 843 | void* [in] driver_data; 844 | long long unsigned int* [in] dma_mask; 845 | u64 [in] coherent_dma_mask; 846 | u64 [in] dma_pfn_offset; 847 | unsigned int [in] devt; 848 | unsigned int [in] id; 849 | bool [in] offline_disabled : 1; 850 | bool [in] offline : 1; 851 | } 852 | projection < struct net_device > net_device { 853 | array< char, 16> [in,out] name; 854 | u64 [in,out] state; 855 | projection unreg_list unreg_list; 856 | projection ptype_all ptype_all; 857 | projection ptype_specific ptype_specific; 858 | projection adj_list adj_list; 859 | u64 [in,out] features; 860 | u64 [in,out] hw_features; 861 | u64 [in,out] wanted_features; 862 | u64 [in,out] vlan_features; 863 | u64 [in,out] hw_enc_features; 864 | u64 [in,out] mpls_features; 865 | u64 [in] gso_partial_features; 866 | int [in,out] ifindex; 867 | projection stats stats; 868 | projection _global_net_device_ops* netdev_ops; 869 | unsigned int [in,out] flags; 870 | array< unsigned char, 32> [in,out] perm_addr; 871 | unsigned char [in,out] addr_assign_type; 872 | unsigned char [in,out] addr_len; 873 | unsigned char* [in,out] dev_addr; 874 | projection _netdev_queue* ingress_queue; 875 | projection watchdog_timer watchdog_timer; 876 | int* [in] pcpu_refcnt; 877 | unsigned int [in,out] reg_state : 8; 878 | unsigned int [in,out] rtnl_link_state : 16; 879 | projection dev dev; 880 | } 881 | projection < struct netdev_queue > net_device_netdev_queue { 882 | } 883 | } 884 | rpc int request_threaded_irq( unsigned int irq, rpc_ptr irq_nested_primary_handler handler, rpc_ptr irq_default_primary_handler thread_fn, u64 irqflags, char *devname, void *dev_id ) { 885 | } 886 | rpc int rtnl_is_locked( ) { 887 | } 888 | rpc void rtnl_lock( ) { 889 | } 890 | rpc void rtnl_unlock( ) { 891 | } 892 | rpc unsigned char* skb_put( projection sk_buff [in] *skb, unsigned int len ) { 893 | projection < struct sk_buff > sk_buff { 894 | projection sk_buff_net_device* dev; 895 | unsigned int [in,out] len; 896 | unsigned int [in] data_len; 897 | array [in,out] headers_end; 898 | unsigned int [in,out] tail; 899 | unsigned int [in] end; 900 | array head; 901 | unsigned char* [in] data; 902 | } 903 | projection < struct net_device > sk_buff_net_device { 904 | array< char, 16> [in] name; 905 | } 906 | } 907 | rpc void synchronize_irq( unsigned int irq ) { 908 | } 909 | rpc void unregister_netdev( projection net_device [in] *dev ) { 910 | projection < struct unreg_list> unreg_list { 911 | projection list_head* next; 912 | projection list_head* prev; 913 | } 914 | projection < struct net_device > net_device { 915 | projection unreg_list unreg_list; 916 | } 917 | } 918 | rpc int eth_validate_addr( projection net_device [in] *dev ) { 919 | projection < struct net_device > net_device { 920 | unsigned char* [in] dev_addr; 921 | } 922 | } 923 | rpc unsigned int ethtool_op_get_link( projection net_device [in] *dev ) { 924 | projection < struct net_device > net_device { 925 | u64 [in] state; 926 | } 927 | } 928 | rpc_ptr int alx_get_settings( projection net_device *netdev, projection ethtool_cmd [in] *ecmd ) { 929 | projection < struct net_device > net_device { 930 | } 931 | projection < struct ethtool_cmd > ethtool_cmd { 932 | unsigned int [in,out] supported; 933 | unsigned int [in,out] advertising; 934 | unsigned short [out] speed; 935 | unsigned char [out] duplex; 936 | unsigned char [out] port; 937 | unsigned char [out] phy_address; 938 | unsigned char [out] transceiver; 939 | unsigned char [out] autoneg; 940 | unsigned short [out] speed_hi; 941 | } 942 | } 943 | rpc_ptr int alx_set_settings( projection net_device *netdev, projection ethtool_cmd [in] *ecmd ) { 944 | projection < struct net_device > net_device { 945 | } 946 | projection < struct ethtool_cmd > ethtool_cmd { 947 | unsigned int [in] advertising; 948 | unsigned short [in] speed; 949 | unsigned char [in] duplex; 950 | unsigned char [in] autoneg; 951 | unsigned short [in] speed_hi; 952 | } 953 | } 954 | rpc_ptr unsigned int alx_get_msglevel( projection net_device *netdev ) { 955 | projection < struct net_device > net_device { 956 | } 957 | } 958 | rpc_ptr void alx_set_msglevel( projection net_device *netdev, unsigned int data ) { 959 | projection < struct net_device > net_device { 960 | } 961 | } 962 | rpc_ptr void alx_get_pauseparam( projection net_device *netdev, projection ethtool_pauseparam [in] *pause ) { 963 | projection < struct net_device > net_device { 964 | } 965 | projection < struct ethtool_pauseparam > ethtool_pauseparam { 966 | unsigned int [out] autoneg; 967 | unsigned int [out] rx_pause; 968 | unsigned int [out] tx_pause; 969 | } 970 | } 971 | rpc_ptr int alx_set_pauseparam( projection net_device *netdev, projection ethtool_pauseparam [in] *pause ) { 972 | projection < struct net_device > net_device { 973 | } 974 | projection < struct ethtool_pauseparam > ethtool_pauseparam { 975 | unsigned int [in] autoneg; 976 | unsigned int [in] rx_pause; 977 | unsigned int [in] tx_pause; 978 | } 979 | } 980 | rpc_ptr void alx_get_strings( projection net_device [unused] *netdev, unsigned int stringset, unsigned char [in] *buf ) { 981 | projection < struct net_device > net_device { 982 | } 983 | } 984 | rpc_ptr void alx_get_ethtool_stats( projection net_device *netdev, projection ethtool_stats [unused] *estats, long long unsigned int [out] *data ) { 985 | projection < struct net_device > net_device { 986 | } 987 | projection < struct ethtool_stats > ethtool_stats { 988 | } 989 | } 990 | rpc_ptr int alx_get_sset_count( projection net_device [unused] *netdev, int sset ) { 991 | projection < struct net_device > net_device { 992 | } 993 | } 994 | rpc_ptr int alx_probe( projection pci_dev [in] *pdev, projection pci_device_id [in] *ent ) { 995 | projection < struct pci_dev > pci_dev { 996 | unsigned char [in] pm_cap; 997 | unsigned int [in] irq; 998 | unsigned short [in,out] dev_flags; 999 | } 1000 | projection < struct pci_device_id > pci_device_id { 1001 | u64 [in] driver_data; 1002 | } 1003 | } 1004 | rpc_ptr void alx_remove( projection pci_dev [in] *pdev ) { 1005 | projection < struct pci_dev > pci_dev { 1006 | } 1007 | } 1008 | rpc_ptr unsigned int alx_pci_error_detected( projection pci_dev [in] *pdev, unsigned int state ) { 1009 | projection < struct pci_dev > pci_dev { 1010 | } 1011 | } 1012 | rpc_ptr unsigned int alx_pci_error_slot_reset( projection pci_dev [in] *pdev ) { 1013 | projection < struct pci_dev > pci_dev { 1014 | } 1015 | } 1016 | rpc_ptr void alx_pci_error_resume( projection pci_dev [in] *pdev ) { 1017 | projection < struct pci_dev > pci_dev { 1018 | } 1019 | } 1020 | rpc_ptr int alx_open( projection net_device [in] *netdev ) { 1021 | projection < struct net_device > net_device { 1022 | } 1023 | } 1024 | rpc_ptr int alx_stop( projection net_device [in] *netdev ) { 1025 | projection < struct net_device > net_device { 1026 | } 1027 | } 1028 | rpc_ptr int alx_start_xmit( projection sk_buff [in] *skb, projection net_device [in] *netdev ) { 1029 | projection < struct sk_buff > sk_buff { 1030 | unsigned int [in] len; 1031 | unsigned char [in] ip_summed : 2; 1032 | unsigned int [in] end; 1033 | unsigned char* [in] head; 1034 | unsigned char* [in] data; 1035 | } 1036 | projection < struct net_device > net_device { 1037 | } 1038 | } 1039 | rpc_ptr void alx_set_rx_mode( projection net_device [in] *netdev ) { 1040 | projection < struct mc> mc { 1041 | projection list list; 1042 | } 1043 | projection < struct list> list { 1044 | projection list_head* next; 1045 | } 1046 | projection < struct net_device > net_device { 1047 | unsigned int [in] flags; 1048 | projection mc mc; 1049 | } 1050 | } 1051 | rpc_ptr int alx_set_mac_address( projection net_device [in] *netdev, void [in] *data ) { 1052 | projection < struct net_device > net_device { 1053 | unsigned char [in,out] addr_assign_type; 1054 | unsigned char [in] addr_len; 1055 | unsigned char* [in] dev_addr; 1056 | } 1057 | } 1058 | rpc_ptr int alx_ioctl( projection net_device [in] *netdev, projection ifreq [in] *ifr, int cmd ) { 1059 | projection < struct net_device > net_device { 1060 | u64 [in] state; 1061 | } 1062 | projection < struct ifreq > ifreq { 1063 | } 1064 | } 1065 | rpc_ptr int alx_change_mtu( projection net_device [in] *netdev, int mtu ) { 1066 | projection < struct net_device > net_device { 1067 | u64 [in] state; 1068 | unsigned int [in,out] mtu; 1069 | } 1070 | } 1071 | rpc_ptr void alx_tx_timeout( projection net_device [in] *dev ) { 1072 | projection < struct net_device > net_device { 1073 | } 1074 | } 1075 | rpc_ptr projection ret_rtnl_link_stats64* alx_get_stats64( projection net_device [in] *dev, projection rtnl_link_stats64 [in,out] *net_stats ) { 1076 | projection < struct rtnl_link_stats64 > ret_rtnl_link_stats64 { 1077 | u64 [out] rx_packets; 1078 | u64 [out] tx_packets; 1079 | u64 [out] rx_bytes; 1080 | u64 [out] tx_bytes; 1081 | u64 rx_errors; 1082 | u64 tx_errors; 1083 | u64 [out] rx_dropped; 1084 | u64 [out] multicast; 1085 | u64 [out] collisions; 1086 | u64 [out] rx_length_errors; 1087 | u64 [out] rx_crc_errors; 1088 | u64 [out] rx_frame_errors; 1089 | u64 [out] rx_fifo_errors; 1090 | u64 [out] tx_aborted_errors; 1091 | u64 [out] tx_fifo_errors; 1092 | u64 [out] tx_window_errors; 1093 | } 1094 | projection < struct net_device > net_device { 1095 | } 1096 | projection < struct rtnl_link_stats64 > rtnl_link_stats64 { 1097 | u64 [out] rx_packets; 1098 | u64 [out] tx_packets; 1099 | u64 [out] rx_bytes; 1100 | u64 [out] tx_bytes; 1101 | u64 [in,out] rx_errors; 1102 | u64 [in,out] tx_errors; 1103 | u64 [out] rx_dropped; 1104 | u64 [out] multicast; 1105 | u64 [out] collisions; 1106 | u64 [out] rx_length_errors; 1107 | u64 [out] rx_crc_errors; 1108 | u64 [out] rx_frame_errors; 1109 | u64 [out] rx_fifo_errors; 1110 | u64 [out] tx_aborted_errors; 1111 | u64 [out] tx_fifo_errors; 1112 | u64 [out] tx_window_errors; 1113 | } 1114 | } 1115 | rpc_ptr u64 alx_fix_features( projection net_device [in] *netdev, u64 features ) { 1116 | projection < struct net_device > net_device { 1117 | unsigned int [in] mtu; 1118 | } 1119 | } 1120 | projection < struct net_device_ops > _global_net_device_ops { 1121 | rpc_ptr alx_change_mtu ndo_change_mtu; 1122 | rpc_ptr alx_fix_features ndo_fix_features; 1123 | rpc_ptr alx_get_stats64 ndo_get_stats64; 1124 | rpc_ptr alx_ioctl ndo_do_ioctl; 1125 | rpc_ptr alx_open ndo_open; 1126 | rpc_ptr alx_set_mac_address ndo_set_mac_address; 1127 | rpc_ptr alx_set_rx_mode ndo_set_rx_mode; 1128 | rpc_ptr alx_start_xmit ndo_start_xmit; 1129 | rpc_ptr alx_stop ndo_stop; 1130 | rpc_ptr alx_tx_timeout ndo_tx_timeout; 1131 | rpc_ptr eth_validate_addr ndo_validate_addr; 1132 | } 1133 | projection < struct pci_driver > _global_pci_driver { 1134 | array id_table; 1135 | char* [in] name; 1136 | projection driver driver; 1137 | projection dynids dynids; 1138 | projection node node; 1139 | rpc_ptr alx_probe probe; 1140 | rpc_ptr alx_remove remove; 1141 | } 1142 | 1143 | 1144 | } 1145 | -------------------------------------------------------------------------------- /table_3_IDL/net/null_net.idl: -------------------------------------------------------------------------------- 1 | // Sync stubs for boundary functions 2 | module kernel { 3 | rpc int __rtnl_link_register( projection _global_rtnl_link_ops [in,out] ops ) { 4 | } 5 | rpc void __rtnl_link_unregister( projection _global_rtnl_link_ops [in,out] ops ) { 6 | } 7 | rpc projection ret_net_device* alloc_netdev_mqs( int sizeof_priv, string *name, unsigned char name_assign_type, rpc_ptr setup setup, unsigned int txqs, unsigned int rxqs ) { 8 | projection < struct net_device > ret_net_device { 9 | array< char, 16> name; 10 | int [out] group; 11 | unsigned int priv_flags; 12 | unsigned short [out] padded; 13 | unsigned char [out] name_assign_type; 14 | unsigned int [out] num_rx_queues; 15 | unsigned int [out] real_num_rx_queues; 16 | unsigned int [out] num_tx_queues; 17 | unsigned int [out] real_num_tx_queues; 18 | u64 tx_queue_len; 19 | int* pcpu_refcnt; 20 | unsigned int [out] gso_max_size; 21 | unsigned short [out] gso_max_segs; 22 | } 23 | } 24 | rpc void consume_skb( projection sk_buff [in] *skb ) { 25 | projection < struct users> users { 26 | int [in,out] counter; 27 | } 28 | projection < struct sk_buff > sk_buff { 29 | projection sk_buff_net_device* dev; 30 | array< char, 48> [in] cb; 31 | u64 [in,out] _skb_refdst; 32 | unsigned char [in] cloned : 1; 33 | unsigned char [in] nohdr : 1; 34 | unsigned char [in] fclone : 2; 35 | unsigned char [in] head_frag : 1; 36 | unsigned char [in] private : 1; 37 | unsigned int [in] end; 38 | unsigned char* [in] head; 39 | projection users users; 40 | } 41 | projection < struct net_device > sk_buff_net_device { 42 | array< char, 16> [in] name; 43 | char* [in] ifalias; 44 | u64 [in] mem_end; 45 | u64 [in] mem_start; 46 | } 47 | } 48 | rpc_ptr int dummy_init_module( ) { 49 | } 50 | rpc void ether_setup( projection net_device [in] *dev ) { 51 | projection < struct net_device > net_device { 52 | unsigned int [out] flags; 53 | unsigned int [in,out] priv_flags; 54 | unsigned int [out] mtu; 55 | unsigned short [out] type; 56 | unsigned short [out] hard_header_len; 57 | unsigned char [out] addr_len; 58 | array< unsigned char, 32> [in] broadcast; 59 | u64 [out] tx_queue_len; 60 | } 61 | } 62 | rpc void free_netdev( projection net_device [in] *dev ) { 63 | projection < struct net_device > net_device { 64 | unsigned short [in] padded; 65 | int* [in,out] pcpu_refcnt; 66 | unsigned int [in,out] reg_state : 8; 67 | } 68 | } 69 | rpc void free_percpu( void *ptr ) { 70 | } 71 | rpc void netif_carrier_off( projection net_device [in] *dev ) { 72 | projection < struct net_device > net_device { 73 | unsigned int [in] reg_state : 8; 74 | } 75 | } 76 | rpc void netif_carrier_on( projection net_device [in] *dev ) { 77 | projection < struct net_device > net_device { 78 | u64 [in] state; 79 | projection _global_net_device_ops* netdev_ops; 80 | int [in,out] watchdog_timeo; 81 | int* [in] pcpu_refcnt; 82 | unsigned int [in] reg_state : 8; 83 | } 84 | } 85 | rpc int register_netdevice( projection net_device [in] *dev ) { 86 | projection < struct watchdog_timer> watchdog_timer { 87 | u64 [out] data; 88 | } 89 | projection < struct dev> dev { 90 | char* [in] init_name; 91 | void* [in] platform_data; 92 | void* [in] driver_data; 93 | long long unsigned int* [in] dma_mask; 94 | u64 [in] coherent_dma_mask; 95 | u64 [in] dma_pfn_offset; 96 | unsigned int [in] devt; 97 | unsigned int [in] id; 98 | bool [in] offline_disabled : 1; 99 | bool [in] offline : 1; 100 | } 101 | projection < struct net_device > net_device { 102 | array< char, 16> [in] name; 103 | u64 [in] state; 104 | u64 [in,out] features; 105 | u64 [in,out] hw_features; 106 | u64 [in,out] wanted_features; 107 | u64 [in,out] vlan_features; 108 | u64 [in,out] hw_enc_features; 109 | u64 [in,out] mpls_features; 110 | u64 [in] gso_partial_features; 111 | int [in,out] ifindex; 112 | projection _global_net_device_ops* netdev_ops; 113 | unsigned int [in] flags; 114 | array< unsigned char, 32> [in] perm_addr; 115 | unsigned char [in] addr_assign_type; 116 | unsigned char [in] addr_len; 117 | unsigned char* [in,out] dev_addr; 118 | unsigned int [in] num_tx_queues; 119 | projection watchdog_timer watchdog_timer; 120 | int* [in] pcpu_refcnt; 121 | unsigned int [in,out] reg_state : 8; 122 | unsigned int [in] rtnl_link_state : 16; 123 | projection dev dev; 124 | projection _global_rtnl_link_ops* rtnl_link_ops; 125 | } 126 | } 127 | rpc void rtnl_link_unregister( projection _global_rtnl_link_ops [in,out] ops ) { 128 | } 129 | rpc void rtnl_lock( ) { 130 | } 131 | rpc void rtnl_unlock( ) { 132 | } 133 | rpc int eth_validate_addr( projection net_device [in] *dev ) { 134 | projection < struct net_device > net_device { 135 | unsigned char* [in] dev_addr; 136 | } 137 | } 138 | rpc int eth_mac_addr( projection net_device [in] *dev, void *p ) { 139 | projection < struct net_device > net_device { 140 | u64 [in] state; 141 | unsigned int [in] priv_flags; 142 | unsigned char* [in] dev_addr; 143 | } 144 | } 145 | rpc_ptr void dummy_setup( projection net_device [in] *dev ) { 146 | projection < struct net_device > net_device { 147 | u64 [in,out] features; 148 | u64 [in,out] hw_features; 149 | u64 [in,out] hw_enc_features; 150 | unsigned int [in,out] flags; 151 | unsigned int [in,out] priv_flags; 152 | unsigned char [out] addr_assign_type; 153 | unsigned char* [in,out] dev_addr; 154 | } 155 | } 156 | rpc_ptr void dummy_get_drvinfo( projection net_device [unused] *dev, projection ethtool_drvinfo [in] *info ) { 157 | projection < struct net_device > net_device { 158 | } 159 | projection < struct ethtool_drvinfo > ethtool_drvinfo { 160 | array< char, 32> [in] driver; 161 | array< char, 32> [in] version; 162 | } 163 | } 164 | rpc_ptr int dummy_dev_init( projection net_device [in] *dev ) { 165 | projection < struct net_device > net_device { 166 | } 167 | } 168 | rpc_ptr void dummy_dev_uninit( projection net_device [in] *dev ) { 169 | projection < struct net_device > net_device { 170 | } 171 | } 172 | rpc_ptr int dummy_xmit( projection sk_buff [in] *skb, projection net_device [in] *dev ) { 173 | projection < struct sk_buff > sk_buff { 174 | unsigned int [in] len; 175 | } 176 | projection < struct net_device > net_device { 177 | } 178 | } 179 | rpc_ptr void set_multicast_list( projection net_device [unused] *dev ) { 180 | projection < struct net_device > net_device { 181 | } 182 | } 183 | rpc_ptr projection ret_rtnl_link_stats64* dummy_get_stats64( projection net_device [in] *dev, projection rtnl_link_stats64 [in] *stats ) { 184 | projection < struct rtnl_link_stats64 > ret_rtnl_link_stats64 { 185 | u64 tx_packets; 186 | u64 tx_bytes; 187 | } 188 | projection < struct net_device > net_device { 189 | } 190 | projection < struct rtnl_link_stats64 > rtnl_link_stats64 { 191 | u64 [in,out] tx_packets; 192 | u64 [in,out] tx_bytes; 193 | } 194 | } 195 | rpc_ptr int dummy_change_carrier( projection net_device *dev, bool new_carrier ) { 196 | projection < struct net_device > net_device { 197 | } 198 | } 199 | rpc_ptr int dummy_validate( projection nlattr [in] **tb, projection nlattr [unused] **data ) { 200 | projection < struct nlattr > nlattr { 201 | } 202 | projection < struct nlattr > nlattr { 203 | } 204 | } 205 | projection < struct net_device_ops > _global_net_device_ops { 206 | rpc_ptr dummy_change_carrier ndo_change_carrier; 207 | rpc_ptr dummy_dev_init ndo_init; 208 | rpc_ptr dummy_dev_uninit ndo_uninit; 209 | rpc_ptr dummy_get_stats64 ndo_get_stats64; 210 | rpc_ptr dummy_xmit ndo_start_xmit; 211 | rpc_ptr eth_mac_addr ndo_set_mac_address; 212 | rpc_ptr eth_validate_addr ndo_validate_addr; 213 | rpc_ptr set_multicast_list ndo_set_rx_mode; 214 | } 215 | projection < struct rtnl_link_ops > _global_rtnl_link_ops { 216 | char* [in] kind; 217 | rpc_ptr dummy_setup setup; 218 | rpc_ptr dummy_validate validate; 219 | } 220 | 221 | 222 | } 223 | --------------------------------------------------------------------------------