Commit e441570f8abd131ec39ca6e81aaaf0d4ade8572f

Authored by balrog
1 parent 8ce0f869

use target_mmap() to allocate idt, gdt and ldt (Kirill A. Shutemov).

env->*dt.base should fit target address space, so we should use
target_mmap to allocate them.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5666 c046a42c-6fe2-441c-8c8c-71466251a162
linux-user/main.c
@@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
23 #include <string.h> 23 #include <string.h>
24 #include <errno.h> 24 #include <errno.h>
25 #include <unistd.h> 25 #include <unistd.h>
  26 +#include <sys/mman.h>
26 27
27 #include "qemu.h" 28 #include "qemu.h"
28 #include "qemu-common.h" 29 #include "qemu-common.h"
@@ -282,9 +283,8 @@ static void write_dt(void *ptr, unsigned long addr, unsigned long limit, @@ -282,9 +283,8 @@ static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
282 p[1] = tswap32(e2); 283 p[1] = tswap32(e2);
283 } 284 }
284 285
  286 +static uint64_t *idt_table;
285 #ifdef TARGET_X86_64 287 #ifdef TARGET_X86_64
286 -static uint64_t idt_table[512];  
287 -  
288 static void set_gate64(void *ptr, unsigned int type, unsigned int dpl, 288 static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
289 uint64_t addr, unsigned int sel) 289 uint64_t addr, unsigned int sel)
290 { 290 {
@@ -303,8 +303,6 @@ static void set_idt(int n, unsigned int dpl) @@ -303,8 +303,6 @@ static void set_idt(int n, unsigned int dpl)
303 set_gate64(idt_table + n * 2, 0, dpl, 0, 0); 303 set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
304 } 304 }
305 #else 305 #else
306 -static uint64_t idt_table[256];  
307 -  
308 static void set_gate(void *ptr, unsigned int type, unsigned int dpl, 306 static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
309 uint32_t addr, unsigned int sel) 307 uint32_t addr, unsigned int sel)
310 { 308 {
@@ -2465,8 +2463,15 @@ int main(int argc, char **argv) @@ -2465,8 +2463,15 @@ int main(int argc, char **argv)
2465 #endif 2463 #endif
2466 2464
2467 /* linux interrupt setup */ 2465 /* linux interrupt setup */
2468 - env->idt.base = h2g(idt_table);  
2469 - env->idt.limit = sizeof(idt_table) - 1; 2466 +#ifndef TARGET_ABI32
  2467 + env->idt.limit = 511;
  2468 +#else
  2469 + env->idt.limit = 255;
  2470 +#endif
  2471 + env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
  2472 + PROT_READ|PROT_WRITE,
  2473 + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
  2474 + idt_table = g2h(env->idt.base);
2470 set_idt(0, 0); 2475 set_idt(0, 0);
2471 set_idt(1, 0); 2476 set_idt(1, 0);
2472 set_idt(2, 0); 2477 set_idt(2, 0);
@@ -2492,9 +2497,11 @@ int main(int argc, char **argv) @@ -2492,9 +2497,11 @@ int main(int argc, char **argv)
2492 /* linux segment setup */ 2497 /* linux segment setup */
2493 { 2498 {
2494 uint64_t *gdt_table; 2499 uint64_t *gdt_table;
2495 - gdt_table = qemu_mallocz(sizeof(uint64_t) * TARGET_GDT_ENTRIES);  
2496 - env->gdt.base = h2g((unsigned long)gdt_table); 2500 + env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
  2501 + PROT_READ|PROT_WRITE,
  2502 + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2497 env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1; 2503 env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
  2504 + gdt_table = g2h(env->gdt.base);
2498 #ifdef TARGET_ABI32 2505 #ifdef TARGET_ABI32
2499 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, 2506 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
2500 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | 2507 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
linux-user/syscall.c
@@ -2565,12 +2565,16 @@ static abi_long write_ldt(CPUX86State *env, @@ -2565,12 +2565,16 @@ static abi_long write_ldt(CPUX86State *env,
2565 } 2565 }
2566 /* allocate the LDT */ 2566 /* allocate the LDT */
2567 if (!ldt_table) { 2567 if (!ldt_table) {
2568 - ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);  
2569 - if (!ldt_table) 2568 + env->ldt.base = target_mmap(0,
  2569 + TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
  2570 + PROT_READ|PROT_WRITE,
  2571 + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
  2572 + if (env->ldt.base == -1)
2570 return -TARGET_ENOMEM; 2573 return -TARGET_ENOMEM;
2571 - memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);  
2572 - env->ldt.base = h2g((unsigned long)ldt_table); 2574 + memset(g2h(env->ldt.base), 0,
  2575 + TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2573 env->ldt.limit = 0xffff; 2576 env->ldt.limit = 0xffff;
  2577 + ldt_table = g2h(env->ldt.base);
2574 } 2578 }
2575 2579
2576 /* NOTE: same code as Linux kernel */ 2580 /* NOTE: same code as Linux kernel */