segments.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include "lg.h"
  2. static int desc_ok(const struct desc_struct *gdt)
  3. {
  4. /* MBZ=0, P=1, DT=1 */
  5. return ((gdt->b & 0x00209000) == 0x00009000);
  6. }
  7. static int segment_present(const struct desc_struct *gdt)
  8. {
  9. return gdt->b & 0x8000;
  10. }
  11. static int ignored_gdt(unsigned int num)
  12. {
  13. return (num == GDT_ENTRY_TSS
  14. || num == GDT_ENTRY_LGUEST_CS
  15. || num == GDT_ENTRY_LGUEST_DS
  16. || num == GDT_ENTRY_DOUBLEFAULT_TSS);
  17. }
  18. /* We don't allow removal of CS, DS or SS; it doesn't make sense. */
  19. static void check_segment_use(struct lguest *lg, unsigned int desc)
  20. {
  21. if (lg->regs->gs / 8 == desc)
  22. lg->regs->gs = 0;
  23. if (lg->regs->fs / 8 == desc)
  24. lg->regs->fs = 0;
  25. if (lg->regs->es / 8 == desc)
  26. lg->regs->es = 0;
  27. if (lg->regs->ds / 8 == desc
  28. || lg->regs->cs / 8 == desc
  29. || lg->regs->ss / 8 == desc)
  30. kill_guest(lg, "Removed live GDT entry %u", desc);
  31. }
  32. static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end)
  33. {
  34. unsigned int i;
  35. for (i = start; i < end; i++) {
  36. /* We never copy these ones to real gdt */
  37. if (ignored_gdt(i))
  38. continue;
  39. /* We could fault in switch_to_guest if they are using
  40. * a removed segment. */
  41. if (!segment_present(&lg->gdt[i])) {
  42. check_segment_use(lg, i);
  43. continue;
  44. }
  45. if (!desc_ok(&lg->gdt[i]))
  46. kill_guest(lg, "Bad GDT descriptor %i", i);
  47. /* DPL 0 presumably means "for use by guest". */
  48. if ((lg->gdt[i].b & 0x00006000) == 0)
  49. lg->gdt[i].b |= (GUEST_PL << 13);
  50. /* Set accessed bit, since gdt isn't writable. */
  51. lg->gdt[i].b |= 0x00000100;
  52. }
  53. }
  54. void setup_default_gdt_entries(struct lguest_ro_state *state)
  55. {
  56. struct desc_struct *gdt = state->guest_gdt;
  57. unsigned long tss = (unsigned long)&state->guest_tss;
  58. /* Hypervisor segments. */
  59. gdt[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
  60. gdt[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
  61. /* This is the one which we *cannot* copy from guest, since tss
  62. is depended on this lguest_ro_state, ie. this cpu. */
  63. gdt[GDT_ENTRY_TSS].a = 0x00000067 | (tss << 16);
  64. gdt[GDT_ENTRY_TSS].b = 0x00008900 | (tss & 0xFF000000)
  65. | ((tss >> 16) & 0x000000FF);
  66. }
  67. void setup_guest_gdt(struct lguest *lg)
  68. {
  69. lg->gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT;
  70. lg->gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT;
  71. lg->gdt[GDT_ENTRY_KERNEL_CS].b |= (GUEST_PL << 13);
  72. lg->gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13);
  73. }
  74. /* This is a fast version for the common case where only the three TLS entries
  75. * have changed. */
  76. void copy_gdt_tls(const struct lguest *lg, struct desc_struct *gdt)
  77. {
  78. unsigned int i;
  79. for (i = GDT_ENTRY_TLS_MIN; i <= GDT_ENTRY_TLS_MAX; i++)
  80. gdt[i] = lg->gdt[i];
  81. }
  82. void copy_gdt(const struct lguest *lg, struct desc_struct *gdt)
  83. {
  84. unsigned int i;
  85. for (i = 0; i < GDT_ENTRIES; i++)
  86. if (!ignored_gdt(i))
  87. gdt[i] = lg->gdt[i];
  88. }
  89. void load_guest_gdt(struct lguest *lg, unsigned long table, u32 num)
  90. {
  91. if (num > ARRAY_SIZE(lg->gdt))
  92. kill_guest(lg, "too many gdt entries %i", num);
  93. lgread(lg, lg->gdt, table, num * sizeof(lg->gdt[0]));
  94. fixup_gdt_table(lg, 0, ARRAY_SIZE(lg->gdt));
  95. lg->changed |= CHANGED_GDT;
  96. }
  97. void guest_load_tls(struct lguest *lg, unsigned long gtls)
  98. {
  99. struct desc_struct *tls = &lg->gdt[GDT_ENTRY_TLS_MIN];
  100. lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES);
  101. fixup_gdt_table(lg, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1);
  102. lg->changed |= CHANGED_GDT_TLS;
  103. }