diff --git a/lisa/_assets/kmodules/lisa/rust/lisakmod-macros/macros/src/inlinec.rs b/lisa/_assets/kmodules/lisa/rust/lisakmod-macros/macros/src/inlinec.rs index 920fab60153afb12252412b50020c0fb1219dce1..eb5b64b28bbdd71037a11b10c936967485ec0afe 100644 --- a/lisa/_assets/kmodules/lisa/rust/lisakmod-macros/macros/src/inlinec.rs +++ b/lisa/_assets/kmodules/lisa/rust/lisakmod-macros/macros/src/inlinec.rs @@ -125,14 +125,16 @@ fn make_c_func( f_generics: Option<&Generics>, f_args: &[(Ident, Type)], f_ret_ty: &Type, + c_attrs: Vec, c_code: ( Option, Option, Option, ), ) -> Result { - let (c_out, c_header_out, rust_out) = - _make_c_func(rust_name, c_name, f_generics, f_args, f_ret_ty, c_code)?; + let (c_out, c_header_out, rust_out) = _make_c_func( + rust_name, c_name, f_generics, f_args, f_ret_ty, c_attrs, c_code, + )?; let c_out = [ make_c_out(c_out, &format!(".binstore.c.code.{}", c_name))?, @@ -151,6 +153,7 @@ fn _make_c_func( f_generics: Option<&Generics>, f_args: &[(Ident, Type)], f_ret_ty: &Type, + mut c_attrs: Vec, c_code: ( Option, Option, @@ -254,6 +257,10 @@ fn _make_c_func( None => quote! {""}, }; + // Disabling CFI inside the function allows us to call anything we want, including Rust + // functions if needed. + c_attrs.push(quote!{"__nocfi"}); + let c_header_out = concatcp(quote! { r#" #include @@ -264,6 +271,13 @@ fn _make_c_func( #define CONST_TY_DECL(declarator) const declarator #define ATTR_TY_DECL(attributes, declarator) attributes declarator #define FN_TY_DECL(args, declarator) ((declarator)args) + + /* On recent kernels, kCFI is used instead of CFI and __cficanonical is therefore not + * defined anymore + */ + #ifndef __cficanonical + # define __cficanonical + #endif "#, "#line ", #c_code_line, " \"", file!(), "\"\n", @@ -279,7 +293,7 @@ fn _make_c_func( } get() }, - "\n#define ", #c_proto, " ", #c_ret_ty, "(FN_TY_DECL((", #c_args, "), ATTR_TY_DECL(__nocfi, ", #c_name_str, ")))", + "\n#define ", #c_proto, " ", #c_ret_ty, "(FN_TY_DECL((", #c_args, "), ATTR_TY_DECL(", #(#c_attrs, " ",)* ", ", #c_name_str, ")))", "\n#line ", #c_code_line, " \"", file!(), "\"\n", #c_proto, ";\n", })?; @@ -327,6 +341,7 @@ pub fn cfunc(_attrs: TokenStream, code: TokenStream) -> Result Result Result #include + #include "#; r#" // memset() is necessary here, otherwise kobj->name stays uninitialized and that leads // to crashes when calling kobject_add() since it tries to free the previous name. memset(kobj, 0, sizeof(*kobj)); - kobject_init(kobj, kobj_type); + + // Some old kernels (e.g. 5.15) don't have a const qualifier for kobj_type, so we cast + // it away with the warnings disabled to avoid hitting -Werror + kobject_init(kobj, CONST_CAST(struct kobj_type*, kobj_type)); "# } // Increase refcount since we are going to keep a pointer to KObjType. We decrement it diff --git a/lisa/_assets/kmodules/lisa/utils.h b/lisa/_assets/kmodules/lisa/utils.h index c7ab03cea18fae6a973d8ce09cfb0f9312998f8d..6666fa0a50dc5aaaa8f765740a88d7f4466f6097 100644 --- a/lisa/_assets/kmodules/lisa/utils.h +++ b/lisa/_assets/kmodules/lisa/utils.h @@ -12,4 +12,27 @@ #include "linux/kernel.h" +#define IGNORE_WARNING(warning, expr) ({ \ + __diag_push(); \ + __diag(ignored warning); \ + typeof(expr) ___expression_value = expr; \ + __diag_pop(); \ + ___expression_value; \ +}) + +#ifdef __clang__ +# define PER_COMPILER(clang, gcc) clang +#else +# define PER_COMPILER(clang, gcc) gcc +#endif + +/// CONST_CAST - Same as C++ const_cast<> +#define CONST_CAST(type, expr) IGNORE_WARNING( \ + PER_COMPILER( \ + "-Wincompatible-pointer-types-discards-qualifiers", \ + "-Wignored-qualifiers" \ + ), \ + (type)(expr) \ +) + #endif /* _UTILS_H */