dirty-log.cc 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include "kvmxx.hh"
  2. #include "exception.hh"
  3. #include "memmap.hh"
  4. #include "identity.hh"
  5. #include <thread>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. namespace {
  9. void delay_loop(unsigned n)
  10. {
  11. for (unsigned i = 0; i < n; ++i) {
  12. asm volatile("pause");
  13. }
  14. }
  15. void write_mem(volatile bool& running, volatile int* shared_var)
  16. {
  17. while (running) {
  18. ++*shared_var;
  19. delay_loop(1000);
  20. }
  21. }
  22. void check_dirty_log(mem_slot& slot,
  23. volatile bool& running,
  24. volatile int* shared_var,
  25. int& nr_fail)
  26. {
  27. uint64_t shared_var_gpa = reinterpret_cast<uint64_t>(shared_var);
  28. slot.set_dirty_logging(true);
  29. slot.update_dirty_log();
  30. for (int i = 0; i < 10000000; ++i) {
  31. int sample1 = *shared_var;
  32. delay_loop(600);
  33. int sample2 = *shared_var;
  34. slot.update_dirty_log();
  35. if (!slot.is_dirty(shared_var_gpa) && sample1 != sample2) {
  36. ++nr_fail;
  37. }
  38. }
  39. running = false;
  40. slot.set_dirty_logging(false);
  41. }
  42. }
  43. int test_main(int ac, char **av)
  44. {
  45. kvm::system sys;
  46. kvm::vm vm(sys);
  47. mem_map memmap(vm);
  48. void* logged_slot_virt;
  49. int ret = posix_memalign(&logged_slot_virt, 4096, 4096);
  50. if (ret) {
  51. throw errno_exception(ret);
  52. }
  53. volatile int* shared_var = static_cast<volatile int*>(logged_slot_virt);
  54. identity::hole hole(logged_slot_virt, 4096);
  55. identity::vm ident_vm(vm, memmap, hole);
  56. kvm::vcpu vcpu(vm, 0);
  57. bool running = true;
  58. int nr_fail = 0;
  59. mem_slot logged_slot(memmap,
  60. reinterpret_cast<uintptr_t>(logged_slot_virt),
  61. 4096, logged_slot_virt);
  62. std::thread host_poll_thread(check_dirty_log, std::ref(logged_slot),
  63. std::ref(running),
  64. shared_var, std::ref(nr_fail));
  65. identity::vcpu guest_write_thread(vcpu,
  66. std::bind(write_mem,
  67. std::ref(running),
  68. shared_var));
  69. vcpu.run();
  70. host_poll_thread.join();
  71. printf("Dirty bitmap failures: %d\n", nr_fail);
  72. return nr_fail == 0 ? 0 : 1;
  73. }
  74. int main(int ac, char** av)
  75. {
  76. return try_main(test_main, ac, av);
  77. }