hyperv.c 1.7 KB

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