Create a second set stubs, and place them in .text.user.
No change in test behaviour.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
.endm
/* For a single instruction, generate each test variant. */
-.macro GEN_SEQUENCE insn
- GEN_SINGLE \insn \insn
- GEN_SINGLE \insn\()_A \insn addr=1
- GEN_SINGLE \insn\()_F \insn fep=1
- GEN_SINGLE \insn\()_FA \insn fep=1 addr=1
+.macro GEN_SEQUENCE user insn
+ GEN_SINGLE \user\()\insn \insn
+ GEN_SINGLE \user\()\insn\()_A \insn addr=1
+ GEN_SINGLE \user\()\insn\()_F \insn fep=1
+ GEN_SINGLE \user\()\insn\()_FA \insn fep=1 addr=1
.endm
/* Generate test sequences for each instruction. */
-GEN_SEQUENCE int3
-GEN_SEQUENCE int_0x3
-GEN_SEQUENCE icebp
-GEN_SEQUENCE int_0x1
-GEN_SEQUENCE into
+GEN_SEQUENCE , int3
+GEN_SEQUENCE , int_0x3
+GEN_SEQUENCE , icebp
+GEN_SEQUENCE , int_0x1
+GEN_SEQUENCE , into
+
+.pushsection .text.user, "ax", @progbits
+
+GEN_SEQUENCE user_ int3
+GEN_SEQUENCE user_ int_0x3
+GEN_SEQUENCE user_ icebp
+GEN_SEQUENCE user_ int_0x1
+GEN_SEQUENCE user_ into
+
+.popsection
/*
* Local variables:
* Nomaclature:
* - `stub_$X_$Y()`
* - Stub function executing instruction `$X` with prefix `$Y`.
+ * - `stub_user_$X_$Y()`
+ * - Stub function executing instruction `$X` with prefix `$Y` in userspace.
*
* Instructions `$X`:
* - int3
unsigned long stub_into_F(void);
unsigned long stub_into_FA(void);
+
+unsigned long stub_user_int3(void);
+unsigned long stub_user_int3_A(void);
+unsigned long stub_user_int3_F(void);
+unsigned long stub_user_int3_FA(void);
+
+unsigned long stub_user_int_0x3(void);
+unsigned long stub_user_int_0x3_A(void);
+unsigned long stub_user_int_0x3_F(void);
+unsigned long stub_user_int_0x3_FA(void);
+
+unsigned long stub_user_icebp(void);
+unsigned long stub_user_icebp_A(void);
+unsigned long stub_user_icebp_F(void);
+unsigned long stub_user_icebp_FA(void);
+
+unsigned long stub_user_int_0x1(void);
+unsigned long stub_user_int_0x1_A(void);
+unsigned long stub_user_int_0x1_F(void);
+unsigned long stub_user_int_0x1_FA(void);
+
+unsigned long stub_user_into(void);
+unsigned long stub_user_into_A(void);
+unsigned long stub_user_into_F(void);
+unsigned long stub_user_into_FA(void);
+
#endif /* __LOWLEVEL_H__ */
/*
const char test_title[] = "Software interrupt emulation";
-bool test_wants_user_mappings = true;
-
#ifdef __i386__
# define COND(_32, _64) _32
#else
{
const char *name;
unsigned long (*fn[4])(void);
+ unsigned long (*user_fn[4])(void);
};
const struct insn int3 = {
stub_int3_F,
stub_int3_FA,
},
+ {
+ stub_user_int3,
+ stub_user_int3_A,
+ stub_user_int3_F,
+ stub_user_int3_FA,
+ },
};
const struct insn int_0x3 = {
stub_int_0x3_F,
stub_int_0x3_FA,
},
+ {
+ stub_user_int_0x3,
+ stub_user_int_0x3_A,
+ stub_user_int_0x3_F,
+ stub_user_int_0x3_FA,
+ },
};
const struct insn icebp = {
stub_icebp_F,
stub_icebp_FA,
},
+ {
+ stub_user_icebp,
+ stub_user_icebp_A,
+ stub_user_icebp_F,
+ stub_user_icebp_FA,
+ },
};
const struct insn int_0x1 = {
stub_int_0x1_F,
stub_int_0x1_FA,
},
+ {
+ stub_user_int_0x1,
+ stub_user_int_0x1_A,
+ stub_user_int_0x1_F,
+ stub_user_int_0x1_FA,
+ },
};
const struct insn into = {
stub_into_F,
stub_into_FA,
},
+ {
+ stub_user_into,
+ stub_user_into_A,
+ stub_user_into_F,
+ stub_user_into_FA,
+ },
};
void test_insn(enum mode user, const struct insn *insn, exinfo_t exp)
{
exinfo_t got;
- got = user ? exec_user(insn->fn[i]) : insn->fn[i]();
+ got = user ? exec_user(insn->user_fn[i]) : insn->fn[i]();
if ( exp != got )
xtf_failure(" Fail (Force%c, Addr%c): expected %pe %s, got %pe %s\n",