diff options
Diffstat (limited to 'drivers/lguest/segments.c')
-rw-r--r-- | drivers/lguest/segments.c | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c index 9e189cbec7dd..ec6aa3f1c36b 100644 --- a/drivers/lguest/segments.c +++ b/drivers/lguest/segments.c | |||
@@ -58,7 +58,7 @@ static int ignored_gdt(unsigned int num) | |||
58 | * Protection Fault in the Switcher when it restores a Guest segment register | 58 | * Protection Fault in the Switcher when it restores a Guest segment register |
59 | * which tries to use that entry. Then we kill the Guest for causing such a | 59 | * which tries to use that entry. Then we kill the Guest for causing such a |
60 | * mess: the message will be "unhandled trap 256". */ | 60 | * mess: the message will be "unhandled trap 256". */ |
61 | static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end) | 61 | static void fixup_gdt_table(struct lg_cpu *cpu, unsigned start, unsigned end) |
62 | { | 62 | { |
63 | unsigned int i; | 63 | unsigned int i; |
64 | 64 | ||
@@ -71,14 +71,14 @@ static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end) | |||
71 | /* Segment descriptors contain a privilege level: the Guest is | 71 | /* Segment descriptors contain a privilege level: the Guest is |
72 | * sometimes careless and leaves this as 0, even though it's | 72 | * sometimes careless and leaves this as 0, even though it's |
73 | * running at privilege level 1. If so, we fix it here. */ | 73 | * running at privilege level 1. If so, we fix it here. */ |
74 | if ((lg->arch.gdt[i].b & 0x00006000) == 0) | 74 | if ((cpu->arch.gdt[i].b & 0x00006000) == 0) |
75 | lg->arch.gdt[i].b |= (GUEST_PL << 13); | 75 | cpu->arch.gdt[i].b |= (GUEST_PL << 13); |
76 | 76 | ||
77 | /* Each descriptor has an "accessed" bit. If we don't set it | 77 | /* Each descriptor has an "accessed" bit. If we don't set it |
78 | * now, the CPU will try to set it when the Guest first loads | 78 | * now, the CPU will try to set it when the Guest first loads |
79 | * that entry into a segment register. But the GDT isn't | 79 | * that entry into a segment register. But the GDT isn't |
80 | * writable by the Guest, so bad things can happen. */ | 80 | * writable by the Guest, so bad things can happen. */ |
81 | lg->arch.gdt[i].b |= 0x00000100; | 81 | cpu->arch.gdt[i].b |= 0x00000100; |
82 | } | 82 | } |
83 | } | 83 | } |
84 | 84 | ||
@@ -109,31 +109,31 @@ void setup_default_gdt_entries(struct lguest_ro_state *state) | |||
109 | 109 | ||
110 | /* This routine sets up the initial Guest GDT for booting. All entries start | 110 | /* This routine sets up the initial Guest GDT for booting. All entries start |
111 | * as 0 (unusable). */ | 111 | * as 0 (unusable). */ |
112 | void setup_guest_gdt(struct lguest *lg) | 112 | void setup_guest_gdt(struct lg_cpu *cpu) |
113 | { | 113 | { |
114 | /* Start with full 0-4G segments... */ | 114 | /* Start with full 0-4G segments... */ |
115 | lg->arch.gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT; | 115 | cpu->arch.gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT; |
116 | lg->arch.gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT; | 116 | cpu->arch.gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT; |
117 | /* ...except the Guest is allowed to use them, so set the privilege | 117 | /* ...except the Guest is allowed to use them, so set the privilege |
118 | * level appropriately in the flags. */ | 118 | * level appropriately in the flags. */ |
119 | lg->arch.gdt[GDT_ENTRY_KERNEL_CS].b |= (GUEST_PL << 13); | 119 | cpu->arch.gdt[GDT_ENTRY_KERNEL_CS].b |= (GUEST_PL << 13); |
120 | lg->arch.gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13); | 120 | cpu->arch.gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13); |
121 | } | 121 | } |
122 | 122 | ||
123 | /*H:650 An optimization of copy_gdt(), for just the three "thead-local storage" | 123 | /*H:650 An optimization of copy_gdt(), for just the three "thead-local storage" |
124 | * entries. */ | 124 | * entries. */ |
125 | void copy_gdt_tls(const struct lguest *lg, struct desc_struct *gdt) | 125 | void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt) |
126 | { | 126 | { |
127 | unsigned int i; | 127 | unsigned int i; |
128 | 128 | ||
129 | for (i = GDT_ENTRY_TLS_MIN; i <= GDT_ENTRY_TLS_MAX; i++) | 129 | for (i = GDT_ENTRY_TLS_MIN; i <= GDT_ENTRY_TLS_MAX; i++) |
130 | gdt[i] = lg->arch.gdt[i]; | 130 | gdt[i] = cpu->arch.gdt[i]; |
131 | } | 131 | } |
132 | 132 | ||
133 | /*H:640 When the Guest is run on a different CPU, or the GDT entries have | 133 | /*H:640 When the Guest is run on a different CPU, or the GDT entries have |
134 | * changed, copy_gdt() is called to copy the Guest's GDT entries across to this | 134 | * changed, copy_gdt() is called to copy the Guest's GDT entries across to this |
135 | * CPU's GDT. */ | 135 | * CPU's GDT. */ |
136 | void copy_gdt(const struct lguest *lg, struct desc_struct *gdt) | 136 | void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt) |
137 | { | 137 | { |
138 | unsigned int i; | 138 | unsigned int i; |
139 | 139 | ||
@@ -141,38 +141,38 @@ void copy_gdt(const struct lguest *lg, struct desc_struct *gdt) | |||
141 | * replaced. See ignored_gdt() above. */ | 141 | * replaced. See ignored_gdt() above. */ |
142 | for (i = 0; i < GDT_ENTRIES; i++) | 142 | for (i = 0; i < GDT_ENTRIES; i++) |
143 | if (!ignored_gdt(i)) | 143 | if (!ignored_gdt(i)) |
144 | gdt[i] = lg->arch.gdt[i]; | 144 | gdt[i] = cpu->arch.gdt[i]; |
145 | } | 145 | } |
146 | 146 | ||
147 | /*H:620 This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT). | 147 | /*H:620 This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT). |
148 | * We copy it from the Guest and tweak the entries. */ | 148 | * We copy it from the Guest and tweak the entries. */ |
149 | void load_guest_gdt(struct lguest *lg, unsigned long table, u32 num) | 149 | void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, u32 num) |
150 | { | 150 | { |
151 | /* We assume the Guest has the same number of GDT entries as the | 151 | /* We assume the Guest has the same number of GDT entries as the |
152 | * Host, otherwise we'd have to dynamically allocate the Guest GDT. */ | 152 | * Host, otherwise we'd have to dynamically allocate the Guest GDT. */ |
153 | if (num > ARRAY_SIZE(lg->arch.gdt)) | 153 | if (num > ARRAY_SIZE(cpu->arch.gdt)) |
154 | kill_guest(lg, "too many gdt entries %i", num); | 154 | kill_guest(cpu, "too many gdt entries %i", num); |
155 | 155 | ||
156 | /* We read the whole thing in, then fix it up. */ | 156 | /* We read the whole thing in, then fix it up. */ |
157 | __lgread(lg, lg->arch.gdt, table, num * sizeof(lg->arch.gdt[0])); | 157 | __lgread(cpu, cpu->arch.gdt, table, num * sizeof(cpu->arch.gdt[0])); |
158 | fixup_gdt_table(lg, 0, ARRAY_SIZE(lg->arch.gdt)); | 158 | fixup_gdt_table(cpu, 0, ARRAY_SIZE(cpu->arch.gdt)); |
159 | /* Mark that the GDT changed so the core knows it has to copy it again, | 159 | /* Mark that the GDT changed so the core knows it has to copy it again, |
160 | * even if the Guest is run on the same CPU. */ | 160 | * even if the Guest is run on the same CPU. */ |
161 | lg->changed |= CHANGED_GDT; | 161 | cpu->changed |= CHANGED_GDT; |
162 | } | 162 | } |
163 | 163 | ||
164 | /* This is the fast-track version for just changing the three TLS entries. | 164 | /* This is the fast-track version for just changing the three TLS entries. |
165 | * Remember that this happens on every context switch, so it's worth | 165 | * Remember that this happens on every context switch, so it's worth |
166 | * optimizing. But wouldn't it be neater to have a single hypercall to cover | 166 | * optimizing. But wouldn't it be neater to have a single hypercall to cover |
167 | * both cases? */ | 167 | * both cases? */ |
168 | void guest_load_tls(struct lguest *lg, unsigned long gtls) | 168 | void guest_load_tls(struct lg_cpu *cpu, unsigned long gtls) |
169 | { | 169 | { |
170 | struct desc_struct *tls = &lg->arch.gdt[GDT_ENTRY_TLS_MIN]; | 170 | struct desc_struct *tls = &cpu->arch.gdt[GDT_ENTRY_TLS_MIN]; |
171 | 171 | ||
172 | __lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES); | 172 | __lgread(cpu, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES); |
173 | fixup_gdt_table(lg, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1); | 173 | fixup_gdt_table(cpu, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1); |
174 | /* Note that just the TLS entries have changed. */ | 174 | /* Note that just the TLS entries have changed. */ |
175 | lg->changed |= CHANGED_GDT_TLS; | 175 | cpu->changed |= CHANGED_GDT_TLS; |
176 | } | 176 | } |
177 | /*:*/ | 177 | /*:*/ |
178 | 178 | ||