]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
x86/idle: CFI hardening
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 28 Oct 2021 12:32:34 +0000 (13:32 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 23 Feb 2022 15:33:43 +0000 (15:33 +0000)
Control Flow Integrity schemes use toolchain and optionally hardware support
to help protect against call/jump/return oriented programming attacks.

Use cf_check to annotate function pointer targets for the toolchain.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/acpi/cpu_idle.c
xen/arch/x86/acpi/cpuidle_menu.c
xen/arch/x86/cpu/mwait-idle.c
xen/arch/x86/domain.c
xen/arch/x86/hpet.c
xen/arch/x86/include/asm/cpuidle.h
xen/arch/x86/include/asm/hpet.h
xen/arch/x86/include/asm/time.h
xen/arch/x86/time.c
xen/drivers/cpufreq/cpufreq_misc_governors.c

index 0142671bb8365410d9df0ad843c91c8d97ed7b5f..557bc6ef8642fc4cf9e65d0807f72b3336925f75 100644 (file)
@@ -75,7 +75,7 @@
 #define GET_CC7_RES(val)  GET_HW_RES_IN_NS(0x3FE, val) /* SNB onwards */
 #define PHI_CC6_RES(val)  GET_HW_RES_IN_NS(0x3FF, val) /* Xeon Phi only */
 
-static void lapic_timer_nop(void) { }
+static void cf_check lapic_timer_nop(void) { }
 void (*__read_mostly lapic_timer_off)(void);
 void (*__read_mostly lapic_timer_on)(void);
 
@@ -310,12 +310,27 @@ static char* acpi_cstate_method_name[] =
     "HALT"
 };
 
-static uint64_t get_stime_tick(void) { return (uint64_t)NOW(); }
-static uint64_t stime_ticks_elapsed(uint64_t t1, uint64_t t2) { return t2 - t1; }
-static uint64_t stime_tick_to_ns(uint64_t ticks) { return ticks; }
+static uint64_t cf_check get_stime_tick(void)
+{
+    return NOW();
+}
+
+static uint64_t cf_check stime_ticks_elapsed(uint64_t t1, uint64_t t2)
+{
+    return t2 - t1;
+}
+
+static uint64_t cf_check stime_tick_to_ns(uint64_t ticks)
+{
+    return ticks;
+}
+
+static uint64_t cf_check get_acpi_pm_tick(void)
+{
+    return inl(pmtmr_ioport);
+}
 
-static uint64_t get_acpi_pm_tick(void) { return (uint64_t)inl(pmtmr_ioport); }
-static uint64_t acpi_pm_ticks_elapsed(uint64_t t1, uint64_t t2)
+static uint64_t cf_check acpi_pm_ticks_elapsed(uint64_t t1, uint64_t t2)
 {
     if ( t2 >= t1 )
         return (t2 - t1);
@@ -664,7 +679,7 @@ void update_idle_stats(struct acpi_processor_power *power,
     spin_unlock(&power->stat_lock);
 }
 
-static void acpi_processor_idle(void)
+static void cf_check acpi_processor_idle(void)
 {
     unsigned int cpu = smp_processor_id();
     struct acpi_processor_power *power = processor_powers[cpu];
@@ -869,7 +884,7 @@ static void acpi_processor_idle(void)
         cpuidle_current_governor->reflect(power);
 }
 
-void acpi_dead_idle(void)
+void cf_check acpi_dead_idle(void)
 {
     struct acpi_processor_power *power;
     struct acpi_processor_cx *cx;
index 6ff5fb8ff2159777026f9914865afe7c0eac6705..a275436d799c9440f3895d00cbf9bec48ce15b9d 100644 (file)
@@ -185,7 +185,7 @@ static unsigned int get_sleep_length_us(void)
     return (us >> 32) ? (unsigned int)-2000 : (unsigned int)us;
 }
 
-static int menu_select(struct acpi_processor_power *power)
+static int cf_check menu_select(struct acpi_processor_power *power)
 {
     struct menu_device *data = &this_cpu(menu_devices);
     int i;
@@ -237,7 +237,7 @@ static int menu_select(struct acpi_processor_power *power)
     return data->last_state_idx;
 }
 
-static void menu_reflect(struct acpi_processor_power *power)
+static void cf_check menu_reflect(struct acpi_processor_power *power)
 {
     struct menu_device *data = &this_cpu(menu_devices);
     u64 new_factor;
@@ -275,7 +275,7 @@ static void menu_reflect(struct acpi_processor_power *power)
     data->correction_factor[data->bucket] = new_factor;
 }
 
-static int menu_enable_device(struct acpi_processor_power *power)
+static int cf_check menu_enable_device(struct acpi_processor_power *power)
 {
     memset(&per_cpu(menu_devices, power->cpu), 0, sizeof(struct menu_device));
 
index 927ce1b67aa59269b536e2f90d498ff43cdd825c..f76c64e04b20707a0b5c48564eb7614993b20592 100644 (file)
@@ -773,7 +773,7 @@ static const struct cpuidle_state snr_cstates[] = {
        {}
 };
 
-static void mwait_idle(void)
+static void cf_check mwait_idle(void)
 {
        unsigned int cpu = smp_processor_id();
        struct acpi_processor_power *power = processor_powers[cpu];
index ec0b631f7cdd23937596edd5c0d363f64d8d3beb..55df2a23f856c1c7f210c99583be8be197efca65 100644 (file)
 
 DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
 
-static void default_idle(void);
+static void cf_check default_idle(void);
 void (*pm_idle) (void) __read_mostly = default_idle;
 void (*dead_idle) (void) __read_mostly = default_dead_idle;
 
-static void default_idle(void)
+static void cf_check default_idle(void)
 {
     struct cpu_info *info = get_cpu_info();
 
@@ -93,7 +93,7 @@ static void default_idle(void)
         local_irq_enable();
 }
 
-void default_dead_idle(void)
+void cf_check default_dead_idle(void)
 {
     /*
      * When going into S3, without flushing caches modified data may be
index 5d4f8915664f5d0f05dd2bfb28cdbcbc0dcb5acf..1632993f72eeb7ef5d122b99a6b432fb320503b6 100644 (file)
@@ -706,7 +706,7 @@ void hpet_disable_legacy_broadcast(void)
     smp_send_event_check_mask(&cpu_online_map);
 }
 
-void hpet_broadcast_enter(void)
+void cf_check hpet_broadcast_enter(void)
 {
     unsigned int cpu = smp_processor_id();
     struct hpet_event_channel *ch = per_cpu(cpu_bc_channel, cpu);
@@ -737,7 +737,7 @@ void hpet_broadcast_enter(void)
     spin_unlock(&ch->lock);
 }
 
-void hpet_broadcast_exit(void)
+void cf_check hpet_broadcast_exit(void)
 {
     unsigned int cpu = smp_processor_id();
     struct hpet_event_channel *ch = per_cpu(cpu_bc_channel, cpu);
index 0981a8fd64172180a9f5db5cc6326bbd6225859f..3edd7a75d2ef6fcaa904b943276eb1292f3556b9 100644 (file)
@@ -17,8 +17,8 @@ extern uint64_t (*cpuidle_get_tick)(void);
 
 int mwait_idle_init(struct notifier_block *);
 int cpuidle_init_cpu(unsigned int cpu);
-void default_dead_idle(void);
-void acpi_dead_idle(void);
+void cf_check default_dead_idle(void);
+void cf_check acpi_dead_idle(void);
 void play_dead(void);
 void trace_exit_reason(u32 *irq_traced);
 void update_idle_stats(struct acpi_processor_power *,
index 8f9725a95e21eed0ccecfe5ff23a18f09c5fc214..f343fe4740f10d19d84ad8b4481898102cdc3d92 100644 (file)
@@ -91,8 +91,8 @@ void hpet_disable_legacy_replacement_mode(void);
  */
 void hpet_broadcast_init(void);
 void hpet_broadcast_resume(void);
-void hpet_broadcast_enter(void);
-void hpet_broadcast_exit(void);
+void cf_check hpet_broadcast_enter(void);
+void cf_check hpet_broadcast_exit(void);
 int hpet_broadcast_is_available(void);
 void hpet_disable_legacy_broadcast(void);
 
index f06f2bfd8b8fe0826d7354e0dc76b757a56517df..2a57d930ef307d5edf2097e11ebc6186eff0d5f6 100644 (file)
@@ -43,11 +43,11 @@ int hwdom_pit_access(struct ioreq *ioreq);
 
 int cpu_frequency_change(u64 freq);
 
-void pit_broadcast_enter(void);
-void pit_broadcast_exit(void);
+void cf_check pit_broadcast_enter(void);
+void cf_check pit_broadcast_exit(void);
 int pit_broadcast_is_available(void);
 
-uint64_t acpi_pm_tick_to_ns(uint64_t ticks);
+uint64_t cf_check acpi_pm_tick_to_ns(uint64_t ticks);
 
 uint64_t tsc_ticks2ns(uint64_t ticks);
 
index a296704fb1f4767f07b0526c094442f618f757e0..d5ec58a3604a9b760f0e8e6e3fa65c4bfbe230a9 100644 (file)
@@ -545,7 +545,7 @@ static __init int cf_check init_pmtmr_scale(void)
 }
 __initcall(init_pmtmr_scale);
 
-uint64_t acpi_pm_tick_to_ns(uint64_t ticks)
+uint64_t cf_check acpi_pm_tick_to_ns(uint64_t ticks)
 {
     return scale_delta(ticks, &pmt_scale);
 }
@@ -2235,12 +2235,12 @@ static int __init cf_check disable_pit_irq(void)
 }
 __initcall(disable_pit_irq);
 
-void pit_broadcast_enter(void)
+void cf_check pit_broadcast_enter(void)
 {
     cpumask_set_cpu(smp_processor_id(), &pit_broadcast_mask);
 }
 
-void pit_broadcast_exit(void)
+void cf_check pit_broadcast_exit(void)
 {
     int cpu = smp_processor_id();
 
index ad79d0f5d2461cdd63bc569a4f73ac7b2792a989..f5571f5486ab35cd257cd685094005be75ddc5a3 100644 (file)
@@ -26,8 +26,8 @@
 static unsigned int __read_mostly userspace_cmdline_freq;
 static DEFINE_PER_CPU(unsigned int, cpu_set_freq);
 
-static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
-                                      unsigned int event)
+static int cf_check cpufreq_governor_userspace(
+    struct cpufreq_policy *policy, unsigned int event)
 {
     int ret = 0;
     unsigned int cpu;
@@ -81,7 +81,7 @@ int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq)
     return __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
 }
 
-static bool_t __init
+static bool __init cf_check
 cpufreq_userspace_handle_option(const char *name, const char *val)
 {
     if (!strcmp(name, "speed") && val) {
@@ -131,8 +131,8 @@ __initcall(cpufreq_gov_userspace_init);
 /*
  * cpufreq performance governor
  */
-static int cpufreq_governor_performance(struct cpufreq_policy *policy,
-                                      unsigned int event)
+static int cf_check cpufreq_governor_performance(
+    struct cpufreq_policy *policy, unsigned int event)
 {
     int ret = 0;
 
@@ -170,8 +170,8 @@ __initcall(cpufreq_gov_performance_init);
 /*
  * cpufreq powersave governor
  */
-static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
-                                      unsigned int event)
+static int cf_check cpufreq_governor_powersave(
+    struct cpufreq_policy *policy, unsigned int event)
 {
     int ret = 0;