aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_kvm_arm64_syzos.h
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2024-12-04 14:05:23 +0100
committerAlexander Potapenko <glider@google.com>2024-12-05 10:57:12 +0000
commit9cdf142495c4f4bc54bb064d7696a5593e95a80a (patch)
tree23012cc0965555adbcce9c1d4b406dfd61b65741 /executor/common_kvm_arm64_syzos.h
parent1eac5906dd00ebafa761f57a933bedec8f09c7ba (diff)
executor: arm64: declare 'noinline' for SyzOS
Apply __attribute__((noinline)) to SyzOS API command handlers to prevent overly optimizing them. While at it, rearrange specifiers in guest function declarations
Diffstat (limited to 'executor/common_kvm_arm64_syzos.h')
-rw-r--r--executor/common_kvm_arm64_syzos.h67
1 files changed, 35 insertions, 32 deletions
diff --git a/executor/common_kvm_arm64_syzos.h b/executor/common_kvm_arm64_syzos.h
index eaf84392e..4764e81b2 100644
--- a/executor/common_kvm_arm64_syzos.h
+++ b/executor/common_kvm_arm64_syzos.h
@@ -10,6 +10,11 @@
// Host will map the code in this section into the guest address space.
#define GUEST_CODE __attribute__((section("guest")))
+// Prevent function inlining. This attribute is applied to every guest_handle_* function,
+// making sure they remain small so that the compiler does not attempt to be too clever
+// (e.g. generate switch tables).
+#define noinline __attribute__((noinline))
+
// Start/end of the guest section.
extern char *__start_guest, *__stop_guest;
@@ -159,7 +164,7 @@ guest_main(uint64 size, uint64 cpu)
guest_uexit((uint64)-1);
}
-GUEST_CODE static void guest_execute_code(uint32* insns, uint64 size)
+GUEST_CODE static noinline void guest_execute_code(uint32* insns, uint64 size)
{
volatile void (*fn)() = (volatile void (*)())insns;
fn();
@@ -168,7 +173,7 @@ GUEST_CODE static void guest_execute_code(uint32* insns, uint64 size)
// Perform a userspace exit that can be handled by the host.
// The host returns from ioctl(KVM_RUN) with kvm_run.exit_reason=KVM_EXIT_MMIO,
// and can handle the call depending on the data passed as exit code.
-GUEST_CODE static void guest_uexit(uint64 exit_code)
+GUEST_CODE static noinline void guest_uexit(uint64 exit_code)
{
volatile uint64* ptr = (volatile uint64*)ARM64_ADDR_UEXIT;
*ptr = exit_code;
@@ -200,8 +205,7 @@ GUEST_CODE static uint32 get_cpu_id()
// Write value to a system register using an MSR instruction.
// The word "MSR" here has nothing to do with the x86 MSR registers.
-__attribute__((noinline))
-GUEST_CODE static void
+GUEST_CODE static noinline void
guest_handle_msr(uint64 reg, uint64 val)
{
uint32 msr = reg_to_msr(reg);
@@ -218,7 +222,7 @@ guest_handle_msr(uint64 reg, uint64 val)
}
// See "SMC Calling Convention", https://documentation-service.arm.com/static/5f8edaeff86e16515cdbe4c6
-GUEST_CODE static void guest_handle_smc(struct api_call_smccc* cmd)
+GUEST_CODE static noinline void guest_handle_smc(struct api_call_smccc* cmd)
{
asm volatile(
"mov x0, %[func_id]\n"
@@ -241,7 +245,7 @@ GUEST_CODE static void guest_handle_smc(struct api_call_smccc* cmd)
"memory");
}
-GUEST_CODE static void guest_handle_hvc(struct api_call_smccc* cmd)
+GUEST_CODE static noinline void guest_handle_hvc(struct api_call_smccc* cmd)
{
asm volatile(
"mov x0, %[func_id]\n"
@@ -315,21 +319,21 @@ GUEST_CODE static void guest_handle_hvc(struct api_call_smccc* cmd)
#define ICC_EOIR1_EL1 "S3_0_C12_C12_1"
#define ICC_DIR_EL1 "S3_0_C12_C11_1"
-static GUEST_CODE __always_inline void __raw_writel(uint32 val, uint64 addr)
+GUEST_CODE static __always_inline void __raw_writel(uint32 val, uint64 addr)
{
asm volatile("str %w0, [%1]"
:
: "rZ"(val), "r"(addr));
}
-static GUEST_CODE __always_inline void __raw_writeq(uint64 val, uint64 addr)
+GUEST_CODE static __always_inline void __raw_writeq(uint64 val, uint64 addr)
{
asm volatile("str %x0, [%1]"
:
: "rZ"(val), "r"(addr));
}
-static GUEST_CODE __always_inline uint32 __raw_readl(uint64 addr)
+GUEST_CODE static __always_inline uint32 __raw_readl(uint64 addr)
{
uint32 val;
asm volatile("ldr %w0, [%1]"
@@ -338,7 +342,7 @@ static GUEST_CODE __always_inline uint32 __raw_readl(uint64 addr)
return val;
}
-static GUEST_CODE __always_inline uint64 __raw_readq(uint64 addr)
+GUEST_CODE static __always_inline uint64 __raw_readq(uint64 addr)
{
uint64 val;
asm volatile("ldr %x0, [%1]"
@@ -365,7 +369,7 @@ static GUEST_CODE __always_inline uint64 __raw_readq(uint64 addr)
} while (0)
// Helper to implement guest_udelay().
-GUEST_CODE uint64 read_cntvct(void)
+GUEST_CODE static uint64 read_cntvct(void)
{
uint64 val;
asm volatile("mrs %0, cntvct_el0"
@@ -451,7 +455,7 @@ GUEST_CODE static void gicv3_dist_init(int nr_spis)
}
// https://developer.arm.com/documentation/198123/0302/Configuring-the-Arm-GIC
-GUEST_CODE void gicv3_enable_redist(uint32 cpu)
+GUEST_CODE static void gicv3_enable_redist(uint32 cpu)
{
uint64 redist_base_cpu = gicr_base_cpu(cpu);
uint32 val = readl(redist_base_cpu + GICR_WAKER);
@@ -462,7 +466,7 @@ GUEST_CODE void gicv3_enable_redist(uint32 cpu)
spin_while_readl(ARM64_ADDR_GICR_BASE + GICR_WAKER, GICR_WAKER_ChildrenAsleep);
}
-GUEST_CODE void gicv3_cpu_init(uint32 cpu)
+GUEST_CODE static void gicv3_cpu_init(uint32 cpu)
{
uint64 sgi_base = sgi_base_cpu(cpu);
@@ -522,7 +526,7 @@ GUEST_CODE static void gicv3_irq_enable(uint32 intid)
gicr_wait_for_rwp(cpu);
}
-GUEST_CODE static void guest_handle_irq_setup(struct api_call_irq_setup* cmd)
+GUEST_CODE static noinline void guest_handle_irq_setup(struct api_call_irq_setup* cmd)
{
int nr_spis = cmd->nr_spis;
if ((nr_spis > VGICV3_MAX_SPI - VGICV3_MIN_SPI) || (nr_spis < 0))
@@ -545,7 +549,7 @@ GUEST_CODE static void guest_handle_irq_setup(struct api_call_irq_setup* cmd)
: "x1");
}
-GUEST_CODE static void guest_handle_memwrite(struct api_call_memwrite* cmd)
+GUEST_CODE static noinline void guest_handle_memwrite(struct api_call_memwrite* cmd)
{
uint64 dest = cmd->base_addr + cmd->offset;
switch (cmd->len) {
@@ -576,7 +580,7 @@ GUEST_CODE static void guest_handle_memwrite(struct api_call_memwrite* cmd)
GUEST_CODE static void guest_prepare_its(int nr_cpus, int nr_devices, int nr_events);
-GUEST_CODE static void guest_handle_its_setup(struct api_call_3* cmd)
+GUEST_CODE static noinline void guest_handle_its_setup(struct api_call_3* cmd)
{
guest_prepare_its(cmd->args[0], cmd->args[1], cmd->args[2]);
}
@@ -859,7 +863,7 @@ struct its_cmd_block {
// Guest memcpy implementation is using volatile accesses to prevent the compiler from optimizing it
// into a memcpy() call.
-__attribute__((noinline)) GUEST_CODE static void guest_memcpy(void* dst, void* src, size_t size)
+GUEST_CODE static noinline void guest_memcpy(void* dst, void* src, size_t size)
{
volatile char* pdst = (char*)dst;
volatile char* psrc = (char*)src;
@@ -869,7 +873,7 @@ __attribute__((noinline)) GUEST_CODE static void guest_memcpy(void* dst, void* s
// Send an ITS command by copying it to the command queue at the offset defined by GITS_CWRITER.
// https://developer.arm.com/documentation/100336/0106/operation/interrupt-translation-service--its-/its-commands-and-errors.
-__attribute__((noinline)) GUEST_CODE static void its_send_cmd(uint64 cmdq_base, struct its_cmd_block* cmd)
+GUEST_CODE static noinline void its_send_cmd(uint64 cmdq_base, struct its_cmd_block* cmd)
{
uint64 cwriter = its_read_u64(GITS_CWRITER);
struct its_cmd_block* dst = (struct its_cmd_block*)(cmdq_base + cwriter);
@@ -954,8 +958,7 @@ GUEST_CODE static void its_init(uint64 coll_tbl,
(~0ULL >> (63 - (h))))
// Avoid inlining this function, because it may cause emitting constants into .rodata.
-__attribute__((noinline))
-GUEST_CODE static void
+GUEST_CODE static noinline void
its_mask_encode(uint64* raw_cmd, uint64 val, int h, int l)
{
uint64 mask = GENMASK_ULL(h, l);
@@ -1014,15 +1017,15 @@ GUEST_CODE static void its_encode_collection(struct its_cmd_block* cmd, uint16 c
its_mask_encode(&cmd->raw_cmd[2], col, 15, 0);
}
-__attribute__((noinline)) GUEST_CODE void guest_memzero(void* ptr, size_t size)
+GUEST_CODE static noinline void guest_memzero(void* ptr, size_t size)
{
volatile char* p = (char*)ptr;
for (size_t i = 0; i < size; i++)
p[i] = 0;
}
-GUEST_CODE void its_send_mapd_cmd(uint64 cmdq_base, uint32 device_id, uint64 itt_base,
- size_t num_idbits, bool valid)
+GUEST_CODE static void its_send_mapd_cmd(uint64 cmdq_base, uint32 device_id, uint64 itt_base,
+ size_t num_idbits, bool valid)
{
struct its_cmd_block cmd;
guest_memzero(&cmd, sizeof(cmd));
@@ -1035,7 +1038,7 @@ GUEST_CODE void its_send_mapd_cmd(uint64 cmdq_base, uint32 device_id, uint64 itt
its_send_cmd(cmdq_base, &cmd);
}
-GUEST_CODE void its_send_mapc_cmd(uint64 cmdq_base, uint32 vcpu_id, uint32 collection_id, bool valid)
+GUEST_CODE static void its_send_mapc_cmd(uint64 cmdq_base, uint32 vcpu_id, uint32 collection_id, bool valid)
{
struct its_cmd_block cmd;
guest_memzero(&cmd, sizeof(cmd));
@@ -1084,7 +1087,7 @@ GUEST_CODE static void its_send_devid_eventid_cmd(uint64 cmdq_base, uint8 cmd_nr
its_send_cmd(cmdq_base, &cmd);
}
-GUEST_CODE void its_send_movall_cmd(uint64 cmdq_base, uint32 vcpu_id, uint32 vcpu_id2)
+GUEST_CODE static void its_send_movall_cmd(uint64 cmdq_base, uint32 vcpu_id, uint32 vcpu_id2)
{
struct its_cmd_block cmd;
guest_memzero(&cmd, sizeof(cmd));
@@ -1118,7 +1121,7 @@ GUEST_CODE static void its_send_sync_cmd(uint64 cmdq_base, uint32 vcpu_id)
its_send_cmd(cmdq_base, &cmd);
}
-GUEST_CODE static void guest_handle_its_send_cmd(struct api_call_its_send_cmd* cmd)
+GUEST_CODE static noinline void guest_handle_its_send_cmd(struct api_call_its_send_cmd* cmd)
{
switch (cmd->type) {
case GITS_CMD_MAPD: {
@@ -1165,11 +1168,11 @@ GUEST_CODE static void guest_handle_its_send_cmd(struct api_call_its_send_cmd* c
}
}
-__attribute__((noinline)) GUEST_CODE static void guest_setup_its_mappings(uint64 cmdq_base,
- uint64 itt_tables,
- uint32 nr_events,
- uint32 nr_devices,
- uint32 nr_cpus)
+GUEST_CODE static noinline void guest_setup_its_mappings(uint64 cmdq_base,
+ uint64 itt_tables,
+ uint32 nr_events,
+ uint32 nr_devices,
+ uint32 nr_cpus)
{
if ((nr_events < 1) || (nr_devices < 1) || (nr_cpus < 1))
return;
@@ -1230,7 +1233,7 @@ void gic_rdist_enable_lpis(uint64 cfg_table, size_t cfg_table_size,
//   452158:       3d800000        str     q0, [x0]
//   45215c:       d65f03c0        ret
// , which for some reason hangs.
-__attribute__((noinline)) GUEST_CODE static void configure_lpis(uint64 prop_table, int nr_devices, int nr_events)
+GUEST_CODE static noinline void configure_lpis(uint64 prop_table, int nr_devices, int nr_events)
{
int nr_lpis = nr_devices * nr_events;
volatile uint8* tbl = (uint8*)prop_table;