On 28.11.2023 11:03, Roger Pau Monne wrote:
> --- /dev/null
> +++ b/xen/arch/x86/test-smc.c
> @@ -0,0 +1,68 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#include <xen/errno.h>
> +
> +#include <asm/alternative.h>
> +#include <asm/cpufeature.h>
> +#include <asm/test-smc.h>
> +
> +static bool cf_check test_insn_replacement(void)
> +{
> +#define EXPECTED_VALUE 2
> + unsigned int r = ~EXPECTED_VALUE;
The compiler is permitted to elide the initializer unless ...
> + alternative_io("", "mov $" STR(EXPECTED_VALUE) ", %0",
> + X86_FEATURE_ALWAYS, "=r"(r));
... you use "+r" here. Also (nit) there's a blank missing between that
string and the opening parethesis. Also what's wrong with passing
EXPECTED_VALUE in as an "i" constraint input operand?
> + return r == EXPECTED_VALUE;
> +#undef EXPECTED_VALUE
> +}
> +
> +int test_smc(uint32_t selection, uint32_t *results)
> +{
> + struct {
> + unsigned int mask;
> + bool (*test)(void);
> + const char *name;
> + } static const tests[] = {
> + { XEN_SYSCTL_TEST_SMC_INSN_REPL, &test_insn_replacement,
> + "alternative instruction replacement" },
> + };
> + unsigned int i;
> +
> + if ( selection & ~XEN_SYSCTL_TEST_SMC_ALL )
> + return -EINVAL;
> +
> + if ( results )
> + *results = 0;
> +
> + printk(XENLOG_INFO "Checking Self Modify Code\n");
> +
> + for ( i = 0; i < ARRAY_SIZE(tests); i++ )
> + {
> + if ( !(selection & tests[i].mask) )
> + continue;
> +
> + if ( tests[i].test() )
> + {
> + if ( results )
> + *results |= tests[i].mask;
> + continue;
> + }
> +
> + add_taint(TAINT_ERROR_SMC);
> + printk(XENLOG_ERR "%s test failed\n", tests[i].name);
> + }
> +
> + return 0;
> +}
I think I need to look at the next patch to make sense of this.
> @@ -1261,6 +1269,7 @@ struct xen_sysctl {
> struct xen_sysctl_livepatch_op livepatch;
> #if defined(__i386__) || defined(__x86_64__)
> struct xen_sysctl_cpu_policy cpu_policy;
> + struct xen_sysctl_test_smc smc;
Imo the field name would better be test_smc (leaving aside Stefano's comment).
Jan