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 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 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 26 static void sint_disable(u8 sint) 27 { 28 wrmsr(HV_X64_MSR_SINT0 + sint, 0xff | HV_SYNIC_SINT_MASKED); 29 } 30 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 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 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 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 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 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 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