Revision 94a6b54f
b/cpu-all.h | ||
---|---|---|
854 | 854 |
|
855 | 855 |
/* memory API */ |
856 | 856 |
|
857 |
extern ram_addr_t phys_ram_size; |
|
858 | 857 |
extern int phys_ram_fd; |
859 |
extern uint8_t *phys_ram_base; |
|
860 | 858 |
extern uint8_t *phys_ram_dirty; |
861 | 859 |
extern ram_addr_t ram_size; |
860 |
extern ram_addr_t last_ram_offset; |
|
862 | 861 |
|
863 | 862 |
/* physical memory access */ |
864 | 863 |
|
b/exec-all.h | ||
---|---|---|
370 | 370 |
|
371 | 371 |
extern uint32_t kqemu_comm_base; |
372 | 372 |
|
373 |
extern ram_addr_t kqemu_phys_ram_size; |
|
374 |
extern uint8_t *kqemu_phys_ram_base; |
|
375 |
|
|
373 | 376 |
static inline int kqemu_is_ok(CPUState *env) |
374 | 377 |
{ |
375 | 378 |
return(env->kqemu_enabled && |
b/exec.c | ||
---|---|---|
107 | 107 |
uint8_t *code_gen_ptr; |
108 | 108 |
|
109 | 109 |
#if !defined(CONFIG_USER_ONLY) |
110 |
ram_addr_t phys_ram_size; |
|
111 | 110 |
int phys_ram_fd; |
112 |
uint8_t *phys_ram_base; |
|
113 | 111 |
uint8_t *phys_ram_dirty; |
114 | 112 |
static int in_migration; |
115 |
static ram_addr_t phys_ram_alloc_offset = 0; |
|
113 |
|
|
114 |
typedef struct RAMBlock { |
|
115 |
uint8_t *host; |
|
116 |
ram_addr_t offset; |
|
117 |
ram_addr_t length; |
|
118 |
struct RAMBlock *next; |
|
119 |
} RAMBlock; |
|
120 |
|
|
121 |
static RAMBlock *ram_blocks; |
|
122 |
/* TODO: When we implement (and use) ram deallocation (e.g. for hotplug) |
|
123 |
then we can no longet assume contiguous ram offsets, and external uses |
|
124 |
of this variable will break. */ |
|
125 |
ram_addr_t last_ram_offset; |
|
116 | 126 |
#endif |
117 | 127 |
|
118 | 128 |
CPUState *first_cpu; |
... | ... | |
411 | 421 |
code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE; |
412 | 422 |
#else |
413 | 423 |
/* XXX: needs ajustments */ |
414 |
code_gen_buffer_size = (unsigned long)(phys_ram_size / 4);
|
|
424 |
code_gen_buffer_size = (unsigned long)(ram_size / 4); |
|
415 | 425 |
#endif |
416 | 426 |
} |
417 | 427 |
if (code_gen_buffer_size < MIN_CODE_GEN_BUFFER_SIZE) |
... | ... | |
2419 | 2429 |
kvm_uncoalesce_mmio_region(addr, size); |
2420 | 2430 |
} |
2421 | 2431 |
|
2432 |
#ifdef USE_KQEMU |
|
2422 | 2433 |
/* XXX: better than nothing */ |
2423 |
ram_addr_t qemu_ram_alloc(ram_addr_t size)
|
|
2434 |
static ram_addr_t kqemu_ram_alloc(ram_addr_t size)
|
|
2424 | 2435 |
{ |
2425 | 2436 |
ram_addr_t addr; |
2426 |
if ((phys_ram_alloc_offset + size) > phys_ram_size) {
|
|
2437 |
if ((last_ram_offset + size) > kqemu_phys_ram_size) {
|
|
2427 | 2438 |
fprintf(stderr, "Not enough memory (requested_size = %" PRIu64 ", max memory = %" PRIu64 ")\n", |
2428 |
(uint64_t)size, (uint64_t)phys_ram_size); |
|
2439 |
(uint64_t)size, (uint64_t)kqemu_phys_ram_size);
|
|
2429 | 2440 |
abort(); |
2430 | 2441 |
} |
2431 |
addr = phys_ram_alloc_offset;
|
|
2432 |
phys_ram_alloc_offset = TARGET_PAGE_ALIGN(phys_ram_alloc_offset + size);
|
|
2442 |
addr = last_ram_offset;
|
|
2443 |
last_ram_offset = TARGET_PAGE_ALIGN(last_ram_offset + size);
|
|
2433 | 2444 |
return addr; |
2434 | 2445 |
} |
2446 |
#endif |
|
2447 |
|
|
2448 |
ram_addr_t qemu_ram_alloc(ram_addr_t size) |
|
2449 |
{ |
|
2450 |
RAMBlock *new_block; |
|
2451 |
|
|
2452 |
#ifdef USE_KQEMU |
|
2453 |
if (kqemu_phys_ram_base) { |
|
2454 |
return kqemu_ram_alloc(size); |
|
2455 |
} |
|
2456 |
#endif |
|
2457 |
|
|
2458 |
size = TARGET_PAGE_ALIGN(size); |
|
2459 |
new_block = qemu_malloc(sizeof(*new_block)); |
|
2460 |
|
|
2461 |
new_block->host = qemu_vmalloc(size); |
|
2462 |
new_block->offset = last_ram_offset; |
|
2463 |
new_block->length = size; |
|
2464 |
|
|
2465 |
new_block->next = ram_blocks; |
|
2466 |
ram_blocks = new_block; |
|
2467 |
|
|
2468 |
phys_ram_dirty = qemu_realloc(phys_ram_dirty, |
|
2469 |
(last_ram_offset + size) >> TARGET_PAGE_BITS); |
|
2470 |
memset(phys_ram_dirty + (last_ram_offset >> TARGET_PAGE_BITS), |
|
2471 |
0xff, size >> TARGET_PAGE_BITS); |
|
2472 |
|
|
2473 |
last_ram_offset += size; |
|
2474 |
|
|
2475 |
return new_block->offset; |
|
2476 |
} |
|
2435 | 2477 |
|
2436 | 2478 |
void qemu_ram_free(ram_addr_t addr) |
2437 | 2479 |
{ |
2480 |
/* TODO: implement this. */ |
|
2438 | 2481 |
} |
2439 | 2482 |
|
2440 | 2483 |
/* Return a host pointer to ram allocated with qemu_ram_alloc. |
... | ... | |
2447 | 2490 |
*/ |
2448 | 2491 |
void *qemu_get_ram_ptr(ram_addr_t addr) |
2449 | 2492 |
{ |
2450 |
return phys_ram_base + addr; |
|
2493 |
RAMBlock *prev; |
|
2494 |
RAMBlock **prevp; |
|
2495 |
RAMBlock *block; |
|
2496 |
|
|
2497 |
#ifdef USE_KQEMU |
|
2498 |
if (kqemu_phys_ram_base) { |
|
2499 |
return kqemu_phys_ram_base + addr; |
|
2500 |
} |
|
2501 |
#endif |
|
2502 |
|
|
2503 |
prev = NULL; |
|
2504 |
prevp = &ram_blocks; |
|
2505 |
block = ram_blocks; |
|
2506 |
while (block && (block->offset > addr |
|
2507 |
|| block->offset + block->length <= addr)) { |
|
2508 |
if (prev) |
|
2509 |
prevp = &prev->next; |
|
2510 |
prev = block; |
|
2511 |
block = block->next; |
|
2512 |
} |
|
2513 |
if (!block) { |
|
2514 |
fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr); |
|
2515 |
abort(); |
|
2516 |
} |
|
2517 |
/* Move this entry to to start of the list. */ |
|
2518 |
if (prev) { |
|
2519 |
prev->next = block->next; |
|
2520 |
block->next = *prevp; |
|
2521 |
*prevp = block; |
|
2522 |
} |
|
2523 |
return block->host + (addr - block->offset); |
|
2451 | 2524 |
} |
2452 | 2525 |
|
2453 | 2526 |
/* Some of the softmmu routines need to translate from a host pointer |
2454 | 2527 |
(typically a TLB entry) back to a ram offset. */ |
2455 | 2528 |
ram_addr_t qemu_ram_addr_from_host(void *ptr) |
2456 | 2529 |
{ |
2457 |
return (uint8_t *)ptr - phys_ram_base; |
|
2530 |
RAMBlock *prev; |
|
2531 |
RAMBlock **prevp; |
|
2532 |
RAMBlock *block; |
|
2533 |
uint8_t *host = ptr; |
|
2534 |
|
|
2535 |
#ifdef USE_KQEMU |
|
2536 |
if (kqemu_phys_ram_base) { |
|
2537 |
return host - kqemu_phys_ram_base; |
|
2538 |
} |
|
2539 |
#endif |
|
2540 |
|
|
2541 |
prev = NULL; |
|
2542 |
prevp = &ram_blocks; |
|
2543 |
block = ram_blocks; |
|
2544 |
while (block && (block->host > host |
|
2545 |
|| block->host + block->length <= host)) { |
|
2546 |
if (prev) |
|
2547 |
prevp = &prev->next; |
|
2548 |
prev = block; |
|
2549 |
block = block->next; |
|
2550 |
} |
|
2551 |
if (!block) { |
|
2552 |
fprintf(stderr, "Bad ram pointer %p\n", ptr); |
|
2553 |
abort(); |
|
2554 |
} |
|
2555 |
return block->offset + (host - block->host); |
|
2458 | 2556 |
} |
2459 | 2557 |
|
2460 | 2558 |
static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr) |
... | ... | |
2895 | 2993 |
|
2896 | 2994 |
io_mem_watch = cpu_register_io_memory(0, watch_mem_read, |
2897 | 2995 |
watch_mem_write, NULL); |
2898 |
/* alloc dirty bits array */ |
|
2899 |
phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS); |
|
2900 |
memset(phys_ram_dirty, 0xff, phys_ram_size >> TARGET_PAGE_BITS); |
|
2996 |
#ifdef USE_KQEMU |
|
2997 |
if (kqemu_phys_ram_base) { |
|
2998 |
/* alloc dirty bits array */ |
|
2999 |
phys_ram_dirty = qemu_vmalloc(kqemu_phys_ram_size >> TARGET_PAGE_BITS); |
|
3000 |
memset(phys_ram_dirty, 0xff, kqemu_phys_ram_size >> TARGET_PAGE_BITS); |
|
3001 |
} |
|
3002 |
#endif |
|
2901 | 3003 |
} |
2902 | 3004 |
|
2903 | 3005 |
/* mem_read and mem_write are arrays of functions containing the |
b/kqemu.c | ||
---|---|---|
91 | 91 |
uint8_t *modified_ram_pages_table; |
92 | 92 |
int qpi_io_memory; |
93 | 93 |
uint32_t kqemu_comm_base; /* physical address of the QPI communication page */ |
94 |
ram_addr_t kqemu_phys_ram_size; |
|
95 |
uint8_t *kqemu_phys_ram_base; |
|
94 | 96 |
|
95 | 97 |
#define cpuid(index, eax, ebx, ecx, edx) \ |
96 | 98 |
asm volatile ("cpuid" \ |
... | ... | |
214 | 216 |
sizeof(uint64_t)); |
215 | 217 |
if (!modified_ram_pages) |
216 | 218 |
goto fail; |
217 |
modified_ram_pages_table = qemu_mallocz(phys_ram_size >> TARGET_PAGE_BITS); |
|
219 |
modified_ram_pages_table = |
|
220 |
qemu_mallocz(kqemu_phys_ram_size >> TARGET_PAGE_BITS); |
|
218 | 221 |
if (!modified_ram_pages_table) |
219 | 222 |
goto fail; |
220 | 223 |
|
221 | 224 |
memset(&kinit, 0, sizeof(kinit)); /* set the paddings to zero */ |
222 |
kinit.ram_base = phys_ram_base; |
|
223 |
kinit.ram_size = phys_ram_size; |
|
225 |
kinit.ram_base = kqemu_phys_ram_base;
|
|
226 |
kinit.ram_size = kqemu_phys_ram_size;
|
|
224 | 227 |
kinit.ram_dirty = phys_ram_dirty; |
225 | 228 |
kinit.pages_to_flush = pages_to_flush; |
226 | 229 |
kinit.ram_pages_to_update = ram_pages_to_update; |
b/vl.c | ||
---|---|---|
3094 | 3094 |
int ret; |
3095 | 3095 |
ram_addr_t i; |
3096 | 3096 |
|
3097 |
if (qemu_get_be32(f) != phys_ram_size)
|
|
3097 |
if (qemu_get_be32(f) != last_ram_offset)
|
|
3098 | 3098 |
return -EINVAL; |
3099 |
for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
|
|
3099 |
for(i = 0; i < last_ram_offset; i+= TARGET_PAGE_SIZE) {
|
|
3100 | 3100 |
ret = ram_get_page(f, qemu_get_ram_ptr(i), TARGET_PAGE_SIZE); |
3101 | 3101 |
if (ret) |
3102 | 3102 |
return ret; |
... | ... | |
3182 | 3182 |
ram_addr_t addr = 0; |
3183 | 3183 |
int found = 0; |
3184 | 3184 |
|
3185 |
while (addr < phys_ram_size) {
|
|
3185 |
while (addr < last_ram_offset) {
|
|
3186 | 3186 |
if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) { |
3187 | 3187 |
uint8_t *p; |
3188 | 3188 |
|
... | ... | |
3204 | 3204 |
break; |
3205 | 3205 |
} |
3206 | 3206 |
addr += TARGET_PAGE_SIZE; |
3207 |
current_addr = (saved_addr + addr) % phys_ram_size;
|
|
3207 |
current_addr = (saved_addr + addr) % last_ram_offset;
|
|
3208 | 3208 |
} |
3209 | 3209 |
|
3210 | 3210 |
return found; |
... | ... | |
3217 | 3217 |
ram_addr_t addr; |
3218 | 3218 |
ram_addr_t count = 0; |
3219 | 3219 |
|
3220 |
for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) {
|
|
3220 |
for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
|
|
3221 | 3221 |
if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) |
3222 | 3222 |
count++; |
3223 | 3223 |
} |
... | ... | |
3231 | 3231 |
|
3232 | 3232 |
if (stage == 1) { |
3233 | 3233 |
/* Make sure all dirty bits are set */ |
3234 |
for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) {
|
|
3234 |
for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
|
|
3235 | 3235 |
if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) |
3236 | 3236 |
cpu_physical_memory_set_dirty(addr); |
3237 | 3237 |
} |
... | ... | |
3239 | 3239 |
/* Enable dirty memory tracking */ |
3240 | 3240 |
cpu_physical_memory_set_dirty_tracking(1); |
3241 | 3241 |
|
3242 |
qemu_put_be64(f, phys_ram_size | RAM_SAVE_FLAG_MEM_SIZE);
|
|
3242 |
qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
|
|
3243 | 3243 |
} |
3244 | 3244 |
|
3245 | 3245 |
while (!qemu_file_rate_limit(f)) { |
... | ... | |
3272 | 3272 |
|
3273 | 3273 |
if (ram_decompress_open(s, f) < 0) |
3274 | 3274 |
return -EINVAL; |
3275 |
for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
|
|
3275 |
for(i = 0; i < last_ram_offset; i+= BDRV_HASH_BLOCK_SIZE) {
|
|
3276 | 3276 |
if (ram_decompress_buf(s, buf, 1) < 0) { |
3277 | 3277 |
fprintf(stderr, "Error while reading ram block header\n"); |
3278 | 3278 |
goto error; |
... | ... | |
3303 | 3303 |
return ram_load_v1(f, opaque); |
3304 | 3304 |
|
3305 | 3305 |
if (version_id == 2) { |
3306 |
if (qemu_get_be32(f) != phys_ram_size)
|
|
3306 |
if (qemu_get_be32(f) != last_ram_offset)
|
|
3307 | 3307 |
return -EINVAL; |
3308 | 3308 |
return ram_load_dead(f, opaque); |
3309 | 3309 |
} |
... | ... | |
3318 | 3318 |
addr &= TARGET_PAGE_MASK; |
3319 | 3319 |
|
3320 | 3320 |
if (flags & RAM_SAVE_FLAG_MEM_SIZE) { |
3321 |
if (addr != phys_ram_size)
|
|
3321 |
if (addr != last_ram_offset)
|
|
3322 | 3322 |
return -EINVAL; |
3323 | 3323 |
} |
3324 | 3324 |
|
... | ... | |
5132 | 5132 |
exit(1); |
5133 | 5133 |
|
5134 | 5134 |
/* init the memory */ |
5135 |
phys_ram_size = machine->ram_require & ~RAMSIZE_FIXED; |
|
5136 |
|
|
5137 |
if (machine->ram_require & RAMSIZE_FIXED) { |
|
5138 |
if (ram_size > 0) { |
|
5139 |
if (ram_size < phys_ram_size) { |
|
5140 |
fprintf(stderr, "Machine `%s' requires %llu bytes of memory\n", |
|
5141 |
machine->name, (unsigned long long) phys_ram_size); |
|
5142 |
exit(-1); |
|
5143 |
} |
|
5144 |
|
|
5145 |
phys_ram_size = ram_size; |
|
5146 |
} else |
|
5147 |
ram_size = phys_ram_size; |
|
5148 |
} else { |
|
5149 |
if (ram_size == 0) |
|
5150 |
ram_size = DEFAULT_RAM_SIZE * 1024 * 1024; |
|
5151 |
|
|
5152 |
phys_ram_size += ram_size; |
|
5153 |
} |
|
5135 |
if (ram_size == 0) |
|
5136 |
ram_size = DEFAULT_RAM_SIZE * 1024 * 1024; |
|
5154 | 5137 |
|
5155 |
phys_ram_base = qemu_vmalloc(phys_ram_size); |
|
5156 |
if (!phys_ram_base) { |
|
5157 |
fprintf(stderr, "Could not allocate physical memory\n"); |
|
5158 |
exit(1); |
|
5138 |
#ifdef USE_KQEMU |
|
5139 |
/* FIXME: This is a nasty hack because kqemu can't cope with dynamic |
|
5140 |
guest ram allocation. It needs to go away. */ |
|
5141 |
if (kqemu_allowed) { |
|
5142 |
kqemu_phys_ram_size = ram_size + VGA_RAM_SIZE + 4 * 1024 * 1024; |
|
5143 |
kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size); |
|
5144 |
if (!kqemu_phys_ram_base) { |
|
5145 |
fprintf(stderr, "Could not allocate physical memory\n"); |
|
5146 |
exit(1); |
|
5147 |
} |
|
5159 | 5148 |
} |
5149 |
#endif |
|
5160 | 5150 |
|
5161 | 5151 |
/* init the dynamic translator */ |
5162 | 5152 |
cpu_exec_init_all(tb_size * 1024 * 1024); |
Also available in: Unified diff