@@ -144,6 +144,19 @@ config INTEL_VMX
If your system includes a processor with Intel VT-x support, say Y.
If in doubt, say Y.
+menu "Emulated HVM devices support"
+ visible if EXPERT
+ depends on HVM
+
+config X86_HVM_PMTIMER
+ bool "ACPI PM timer emulation support"
+ default y
+ help
+ Build driver that emulates ACPI PM timer for HVM guests.
+
+ If unsure, say Y.
+endmenu
+
config XEN_SHSTK
bool "Supervisor Shadow Stacks"
depends on HAS_AS_CET_SS
@@ -744,8 +744,16 @@ static bool emulation_flags_ok(const struct domain *d, uint32_t emflags)
{
#ifdef CONFIG_HVM
/* This doesn't catch !CONFIG_HVM case but it is better than nothing */
- BUILD_BUG_ON(X86_EMU_ALL != XEN_X86_EMU_ALL);
+ BUILD_BUG_ON((X86_EMU_ALL & ~X86_EMU_PM) !=
+ (XEN_X86_EMU_ALL & ~XEN_X86_EMU_PM));
#endif
+#ifdef CONFIG_X86_HVM_PMTIMER
+ BUILD_BUG_ON(X86_EMU_PM != XEN_X86_EMU_PM);
+#endif
+
+ /* emflags contain non-supported bits */
+ if ( (emflags & X86_EMU_ALL) != emflags )
+ return false;
if ( is_hvm_domain(d) )
{
@@ -18,7 +18,7 @@ obj-y += irq.o
obj-y += monitor.o
obj-y += mtrr.o
obj-y += nestedhvm.o
-obj-y += pmtimer.o
+obj-$(CONFIG_X86_HVM_PMTIMER) += pmtimer.o
obj-y += quirks.o
obj-y += rtc.o
obj-y += save.o
@@ -150,8 +150,13 @@ void acpi_mmcfg_init(void);
/* Incremented whenever we transition through S3. Value is 1 during boot. */
extern uint32_t system_reset_counter;
+#ifdef CONFIG_X86_HVM_PMTIMER
void hvm_acpi_power_button(struct domain *d);
void hvm_acpi_sleep_button(struct domain *d);
+#else
+static inline void hvm_acpi_power_button(struct domain *d) {}
+static inline void hvm_acpi_sleep_button(struct domain *d) {}
+#endif
/* suspend/resume */
void save_rest_processor_state(void);
@@ -463,7 +463,6 @@ struct arch_domain
#ifdef CONFIG_HVM
#define X86_EMU_LAPIC XEN_X86_EMU_LAPIC
#define X86_EMU_HPET XEN_X86_EMU_HPET
-#define X86_EMU_PM XEN_X86_EMU_PM
#define X86_EMU_RTC XEN_X86_EMU_RTC
#define X86_EMU_IOAPIC XEN_X86_EMU_IOAPIC
#define X86_EMU_PIC XEN_X86_EMU_PIC
@@ -474,7 +473,6 @@ struct arch_domain
#else
#define X86_EMU_LAPIC 0
#define X86_EMU_HPET 0
-#define X86_EMU_PM 0
#define X86_EMU_RTC 0
#define X86_EMU_IOAPIC 0
#define X86_EMU_PIC 0
@@ -484,6 +482,12 @@ struct arch_domain
#define X86_EMU_VPCI 0
#endif
+#ifdef CONFIG_X86_HVM_PMTIMER
+#define X86_EMU_PM XEN_X86_EMU_PM
+#else
+#define X86_EMU_PM 0
+#endif
+
#define X86_EMU_PIT XEN_X86_EMU_PIT
/* This must match XEN_X86_EMU_ALL in xen.h */
@@ -80,8 +80,10 @@ struct hvm_domain {
* in public header files.
* Internally, however, we will be using hvm_hw_acpi.
*/
+#ifdef CONFIG_X86_HVM_PMTIMER
#define hvm_hw_acpi hvm_hw_pmtimer
struct hvm_hw_acpi acpi;
+#endif
/* VCPU which is current target for 8259 interrupts. */
struct vcpu *i8259_target;
@@ -187,10 +187,20 @@ void rtc_deinit(struct domain *d);
void rtc_reset(struct domain *d);
void rtc_update_clock(struct domain *d);
+#ifdef CONFIG_X86_HVM_PMTIMER
void pmtimer_init(struct vcpu *v);
void pmtimer_deinit(struct domain *d);
void pmtimer_reset(struct domain *d);
int pmtimer_change_ioport(struct domain *d, uint64_t version);
+#else
+static inline void pmtimer_init(struct vcpu *v) {}
+static inline void pmtimer_deinit(struct domain *d) {}
+static inline void pmtimer_reset(struct domain *d) {}
+static inline int pmtimer_change_ioport(struct domain *d, uint64_t version)
+{
+ return -ENODEV;
+}
+#endif
void hpet_init(struct domain *d);
void hpet_deinit(struct domain *d);