@@ -60,11 +60,23 @@
#define HV_SYNIC_SINT_VECTOR_MASK (0xFF)
#define HV_SYNIC_SINT_COUNT 16
-#define HV_STIMER_ENABLE (1ULL << 0)
-#define HV_STIMER_PERIODIC (1ULL << 1)
-#define HV_STIMER_LAZY (1ULL << 2)
-#define HV_STIMER_AUTOENABLE (1ULL << 3)
-#define HV_STIMER_SINT(config) (__u8)(((config) >> 16) & 0x0F)
+/*
+ * Synthetic timer configuration.
+ */
+union hv_stimer_config {
+ u64 as_uint64;
+ struct {
+ u64 enable:1;
+ u64 periodic:1;
+ u64 lazy:1;
+ u64 auto_enable:1;
+ u64 apic_vector:8;
+ u64 direct_mode:1;
+ u64 reserved_z0:3;
+ u64 sintx:4;
+ u64 reserved_z1:44;
+ };
+};
#define HV_SYNIC_STIMER_COUNT (4)
@@ -163,20 +163,15 @@ static void stimer_start(struct stimer *timer,
bool auto_enable, bool periodic,
u64 tick_100ns)
{
- u64 config, count;
+ u64 count;
+ union hv_stimer_config config = {.as_uint64 = 0};
atomic_set(&timer->fire_count, 0);
- config = 0;
- if (periodic) {
- config |= HV_STIMER_PERIODIC;
- }
-
- config |= ((u8)(timer->sint & 0xFF)) << 16;
- config |= HV_STIMER_ENABLE;
- if (auto_enable) {
- config |= HV_STIMER_AUTOENABLE;
- }
+ config.periodic = periodic;
+ config.enable = 1;
+ config.auto_enable = auto_enable;
+ config.sintx = timer->sint;
if (periodic) {
count = tick_100ns;
@@ -186,9 +181,9 @@ static void stimer_start(struct stimer *timer,
if (!auto_enable) {
wrmsr(HV_X64_MSR_STIMER0_COUNT + timer->index*2, count);
- wrmsr(HV_X64_MSR_STIMER0_CONFIG + timer->index*2, config);
+ wrmsr(HV_X64_MSR_STIMER0_CONFIG + timer->index*2, config.as_uint64);
} else {
- wrmsr(HV_X64_MSR_STIMER0_CONFIG + timer->index*2, config);
+ wrmsr(HV_X64_MSR_STIMER0_CONFIG + timer->index*2, config.as_uint64);
wrmsr(HV_X64_MSR_STIMER0_COUNT + timer->index*2, count);
}
}
As a preparation to enabling direct synthetic timers properly define hv_stimer_config. Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> --- x86/hyperv.h | 22 +++++++++++++++++----- x86/hyperv_stimer.c | 21 ++++++++------------- 2 files changed, 25 insertions(+), 18 deletions(-)