xref: /kvm-unit-tests/x86/hyperv.c (revision faf6f82fc7ae3fe72dd0945865ad4f3ed75da7f9)
1 #include "hyperv.h"
2 #include "asm/io.h"
3 #include "smp.h"
4 
5 enum {
6     HV_TEST_DEV_SINT_ROUTE_CREATE = 1,
7     HV_TEST_DEV_SINT_ROUTE_DESTROY,
8     HV_TEST_DEV_SINT_ROUTE_SET_SINT,
9     HV_TEST_DEV_MSG_CONN_CREATE,
10     HV_TEST_DEV_MSG_CONN_DESTROY,
11     HV_TEST_DEV_EVT_CONN_CREATE,
12     HV_TEST_DEV_EVT_CONN_DESTROY,
13 };
14 
synic_ctl(u32 ctl,u32 vcpu_id,u32 sint,u32 conn_id)15 static void synic_ctl(u32 ctl, u32 vcpu_id, u32 sint, u32 conn_id)
16 {
17     outl((conn_id << 24) | (ctl << 16) | (vcpu_id << 8) | sint, 0x3000);
18 }
19 
sint_enable(u8 sint,u8 vec,bool auto_eoi)20 static void sint_enable(u8 sint, u8 vec, bool auto_eoi)
21 {
22     wrmsr(HV_X64_MSR_SINT0 + sint,
23           (u64)vec | (auto_eoi ? HV_SYNIC_SINT_AUTO_EOI : 0));
24 }
25 
sint_disable(u8 sint)26 static void sint_disable(u8 sint)
27 {
28     wrmsr(HV_X64_MSR_SINT0 + sint, 0xff | HV_SYNIC_SINT_MASKED);
29 }
30 
synic_sint_create(u8 sint,u8 vec,bool auto_eoi)31 void synic_sint_create(u8 sint, u8 vec, bool auto_eoi)
32 {
33     synic_ctl(HV_TEST_DEV_SINT_ROUTE_CREATE, smp_id(), sint, 0);
34     sint_enable(sint, vec, auto_eoi);
35 }
36 
synic_sint_set(u8 vcpu,u8 sint)37 void synic_sint_set(u8 vcpu, u8 sint)
38 {
39     synic_ctl(HV_TEST_DEV_SINT_ROUTE_SET_SINT, vcpu, sint, 0);
40 }
41 
synic_sint_destroy(u8 sint)42 void synic_sint_destroy(u8 sint)
43 {
44     sint_disable(sint);
45     synic_ctl(HV_TEST_DEV_SINT_ROUTE_DESTROY, smp_id(), sint, 0);
46 }
47 
msg_conn_create(u8 sint,u8 vec,u8 conn_id)48 void msg_conn_create(u8 sint, u8 vec, u8 conn_id)
49 {
50     synic_ctl(HV_TEST_DEV_MSG_CONN_CREATE, smp_id(), sint, conn_id);
51     sint_enable(sint, vec, true);
52 }
53 
msg_conn_destroy(u8 sint,u8 conn_id)54 void msg_conn_destroy(u8 sint, u8 conn_id)
55 {
56     sint_disable(sint);
57     synic_ctl(HV_TEST_DEV_MSG_CONN_DESTROY, 0, 0, conn_id);
58 }
59 
evt_conn_create(u8 sint,u8 vec,u8 conn_id)60 void evt_conn_create(u8 sint, u8 vec, u8 conn_id)
61 {
62     synic_ctl(HV_TEST_DEV_EVT_CONN_CREATE, smp_id(), sint, conn_id);
63     sint_enable(sint, vec, true);
64 }
65 
evt_conn_destroy(u8 sint,u8 conn_id)66 void evt_conn_destroy(u8 sint, u8 conn_id)
67 {
68     sint_disable(sint);
69     synic_ctl(HV_TEST_DEV_EVT_CONN_DESTROY, 0, 0, conn_id);
70 }
71