@@ -113,7 +113,8 @@ $(TEST_DIR)/debug.elf: $(cstart.o) $(TEST_DIR)/debug.o
$(TEST_DIR)/memory.elf: $(cstart.o) $(TEST_DIR)/memory.o
-$(TEST_DIR)/hyperv_synic.elf: $(cstart.o) $(TEST_DIR)/hyperv_synic.o
+$(TEST_DIR)/hyperv_synic.elf: $(cstart.o) $(TEST_DIR)/hyperv.o \
+ $(TEST_DIR)/hyperv_synic.o
arch_clean:
$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
@@ -408,27 +408,4 @@
#define MSR_VM_IGNNE 0xc0010115
#define MSR_VM_HSAVE_PA 0xc0010117
-/* Define synthetic interrupt controller model specific registers. */
-#define HV_X64_MSR_SCONTROL 0x40000080
-#define HV_X64_MSR_SVERSION 0x40000081
-#define HV_X64_MSR_SIEFP 0x40000082
-#define HV_X64_MSR_SIMP 0x40000083
-#define HV_X64_MSR_EOM 0x40000084
-#define HV_X64_MSR_SINT0 0x40000090
-#define HV_X64_MSR_SINT1 0x40000091
-#define HV_X64_MSR_SINT2 0x40000092
-#define HV_X64_MSR_SINT3 0x40000093
-#define HV_X64_MSR_SINT4 0x40000094
-#define HV_X64_MSR_SINT5 0x40000095
-#define HV_X64_MSR_SINT6 0x40000096
-#define HV_X64_MSR_SINT7 0x40000097
-#define HV_X64_MSR_SINT8 0x40000098
-#define HV_X64_MSR_SINT9 0x40000099
-#define HV_X64_MSR_SINT10 0x4000009A
-#define HV_X64_MSR_SINT11 0x4000009B
-#define HV_X64_MSR_SINT12 0x4000009C
-#define HV_X64_MSR_SINT13 0x4000009D
-#define HV_X64_MSR_SINT14 0x4000009E
-#define HV_X64_MSR_SINT15 0x4000009F
-
#endif /* _ASM_X86_MSR_INDEX_H */
new file mode 100644
@@ -0,0 +1,24 @@
+#include "hyperv.h"
+
+static void synic_ctl(u8 ctl, u8 vcpu_id, u8 sint)
+{
+ outl((ctl << 16)|((vcpu_id) << 8)|sint, 0x3000);
+}
+
+void synic_sint_create(int vcpu, int sint, int vec, bool auto_eoi)
+{
+ wrmsr(HV_X64_MSR_SINT0 + sint,
+ (u64)vec | ((auto_eoi) ? HV_SYNIC_SINT_AUTO_EOI : 0));
+ synic_ctl(HV_TEST_DEV_SINT_ROUTE_CREATE, vcpu, sint);
+}
+
+void synic_sint_set(int vcpu, int sint)
+{
+ synic_ctl(HV_TEST_DEV_SINT_ROUTE_SET_SINT, vcpu, sint);
+}
+
+void synic_sint_destroy(int vcpu, int sint)
+{
+ wrmsr(HV_X64_MSR_SINT0 + sint, 0xFF|HV_SYNIC_SINT_MASKED);
+ synic_ctl(HV_TEST_DEV_SINT_ROUTE_DESTROY, vcpu, sint);
+}
new file mode 100644
@@ -0,0 +1,58 @@
+#ifndef __HYPERV_H
+#define __HYPERV_H
+
+#include "libcflat.h"
+#include "processor.h"
+#include "io.h"
+
+#define HYPERV_CPUID_FEATURES 0x40000003
+
+#define HV_X64_MSR_SYNIC_AVAILABLE (1 << 2)
+
+/* Define synthetic interrupt controller model specific registers. */
+#define HV_X64_MSR_SCONTROL 0x40000080
+#define HV_X64_MSR_SVERSION 0x40000081
+#define HV_X64_MSR_SIEFP 0x40000082
+#define HV_X64_MSR_SIMP 0x40000083
+#define HV_X64_MSR_EOM 0x40000084
+#define HV_X64_MSR_SINT0 0x40000090
+#define HV_X64_MSR_SINT1 0x40000091
+#define HV_X64_MSR_SINT2 0x40000092
+#define HV_X64_MSR_SINT3 0x40000093
+#define HV_X64_MSR_SINT4 0x40000094
+#define HV_X64_MSR_SINT5 0x40000095
+#define HV_X64_MSR_SINT6 0x40000096
+#define HV_X64_MSR_SINT7 0x40000097
+#define HV_X64_MSR_SINT8 0x40000098
+#define HV_X64_MSR_SINT9 0x40000099
+#define HV_X64_MSR_SINT10 0x4000009A
+#define HV_X64_MSR_SINT11 0x4000009B
+#define HV_X64_MSR_SINT12 0x4000009C
+#define HV_X64_MSR_SINT13 0x4000009D
+#define HV_X64_MSR_SINT14 0x4000009E
+#define HV_X64_MSR_SINT15 0x4000009F
+
+#define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIMP_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIEFP_ENABLE (1ULL << 0)
+#define HV_SYNIC_SINT_MASKED (1ULL << 16)
+#define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17)
+#define HV_SYNIC_SINT_VECTOR_MASK (0xFF)
+#define HV_SYNIC_SINT_COUNT 16
+
+enum {
+ HV_TEST_DEV_SINT_ROUTE_CREATE = 1,
+ HV_TEST_DEV_SINT_ROUTE_DESTROY,
+ HV_TEST_DEV_SINT_ROUTE_SET_SINT
+};
+
+static inline bool synic_supported(void)
+{
+ return cpuid(HYPERV_CPUID_FEATURES).a & HV_X64_MSR_SYNIC_AVAILABLE;
+}
+
+void synic_sint_create(int vcpu, int sint, int vec, bool auto_eoi);
+void synic_sint_set(int vcpu, int sint);
+void synic_sint_destroy(int vcpu, int sint);
+
+#endif
@@ -8,32 +8,13 @@
#include "io.h"
#include "smp.h"
#include "atomic.h"
+#include "hyperv.h"
#define MAX_CPUS 4
-#define HYPERV_CPUID_FEATURES 0x40000003
-#define HV_X64_MSR_SYNIC_AVAILABLE (1 << 2)
-#define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
-#define HV_SYNIC_SIMP_ENABLE (1ULL << 0)
-#define HV_SYNIC_SIEFP_ENABLE (1ULL << 0)
-#define HV_SYNIC_SINT_MASKED (1ULL << 16)
-#define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17)
-#define HV_SYNIC_SINT_VECTOR_MASK (0xFF)
-#define HV_SYNIC_SINT_COUNT 16
-
-enum {
- HV_TEST_DEV_SINT_ROUTE_CREATE = 1,
- HV_TEST_DEV_SINT_ROUTE_DESTROY,
- HV_TEST_DEV_SINT_ROUTE_SET_SINT
-};
static atomic_t isr_enter_count[MAX_CPUS];
static atomic_t cpus_comp_count;
-static bool synic_supported(void)
-{
- return cpuid(HYPERV_CPUID_FEATURES).a & HV_X64_MSR_SYNIC_AVAILABLE;
-}
-
static void synic_sint_auto_eoi_isr(isr_regs_t *regs)
{
atomic_inc(&isr_enter_count[smp_id()]);
@@ -45,11 +26,6 @@ static void synic_sint_isr(isr_regs_t *regs)
eoi();
}
-static void synic_ctl(u8 ctl, u8 vcpu_id, u8 sint)
-{
- outl((ctl << 16)|((vcpu_id) << 8)|sint, 0x3000);
-}
-
struct sint_vec_entry {
int vec;
bool auto_eoi;
@@ -86,7 +62,7 @@ static void synic_prepare_sint_vecs(void)
}
}
-static void synic_sints_prepare(u8 vcpu)
+static void synic_sints_prepare(int vcpu)
{
bool auto_eoi;
int i, vec;
@@ -94,9 +70,7 @@ static void synic_sints_prepare(u8 vcpu)
for (i = 0; i < HV_SYNIC_SINT_COUNT; i++) {
vec = sint_vecs[i].vec;
auto_eoi = sint_vecs[i].auto_eoi;
- wrmsr(HV_X64_MSR_SINT0 + i,
- (u64)vec | ((auto_eoi) ? HV_SYNIC_SINT_AUTO_EOI : 0));
- synic_ctl(HV_TEST_DEV_SINT_ROUTE_CREATE, vcpu, i);
+ synic_sint_create(vcpu, i, vec, auto_eoi);
}
}
@@ -132,13 +106,13 @@ ret:
atomic_inc(&cpus_comp_count);
}
-static void synic_sints_test(u8 dst_vcpu)
+static void synic_sints_test(int dst_vcpu)
{
int i;
atomic_set(&isr_enter_count[dst_vcpu], 0);
for (i = 0; i < HV_SYNIC_SINT_COUNT; i++) {
- synic_ctl(HV_TEST_DEV_SINT_ROUTE_SET_SINT, dst_vcpu, i);
+ synic_sint_set(dst_vcpu, i);
}
while (atomic_read(&isr_enter_count[dst_vcpu]) != HV_SYNIC_SINT_COUNT) {
@@ -148,7 +122,7 @@ static void synic_sints_test(u8 dst_vcpu)
static void synic_test(void *ctx)
{
- u8 dst_vcpu = (ulong)ctx;
+ int dst_vcpu = (ulong)ctx;
irq_enable();
synic_sints_test(dst_vcpu);
@@ -157,12 +131,12 @@ static void synic_test(void *ctx)
static void synic_test_cleanup(void *ctx)
{
- u8 vcpu = smp_id();
+ int vcpu = smp_id();
int i;
irq_enable();
for (i = 0; i < HV_SYNIC_SINT_COUNT; i++) {
- synic_ctl(HV_TEST_DEV_SINT_ROUTE_DESTROY, vcpu, i);
+ synic_sint_destroy(vcpu, i);
wrmsr(HV_X64_MSR_SINT0 + i, 0xFF|HV_SYNIC_SINT_MASKED);
}
This code will be used as shared between hyperv_synic and hyperv_stimer tests. Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com> CC: Paolo Bonzini <pbonzini@redhat.com> CC: Marcelo Tosatti <mtosatti@redhat.com> CC: Roman Kagan <rkagan@virtuozzo.com> CC: Denis V. Lunev <den@openvz.org> CC: qemu-devel@nongnu.org --- config/config-x86-common.mak | 3 ++- lib/x86/msr.h | 23 ------------------ x86/hyperv.c | 24 ++++++++++++++++++ x86/hyperv.h | 58 ++++++++++++++++++++++++++++++++++++++++++++ x86/hyperv_synic.c | 42 ++++++-------------------------- 5 files changed, 92 insertions(+), 58 deletions(-) create mode 100644 x86/hyperv.c create mode 100644 x86/hyperv.h