Revision 5579c7f3
b/cpu-all.h | ||
---|---|---|
908 | 908 |
void qemu_ram_free(ram_addr_t addr); |
909 | 909 |
/* This should only be used for ram local to a device. */ |
910 | 910 |
void *qemu_get_ram_ptr(ram_addr_t addr); |
911 |
/* This should not be used by devices. */ |
|
912 |
ram_addr_t qemu_ram_addr_from_host(void *ptr); |
|
913 |
|
|
911 | 914 |
int cpu_register_io_memory(int io_index, |
912 | 915 |
CPUReadMemoryFunc **mem_read, |
913 | 916 |
CPUWriteMemoryFunc **mem_write, |
b/exec-all.h | ||
---|---|---|
316 | 316 |
static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr) |
317 | 317 |
{ |
318 | 318 |
int mmu_idx, page_index, pd; |
319 |
void *p; |
|
319 | 320 |
|
320 | 321 |
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
321 | 322 |
mmu_idx = cpu_mmu_index(env1); |
... | ... | |
331 | 332 |
cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr); |
332 | 333 |
#endif |
333 | 334 |
} |
334 |
return addr + env1->tlb_table[mmu_idx][page_index].addend - (unsigned long)phys_ram_base; |
|
335 |
p = (void *)(unsigned long)addr |
|
336 |
+ env1->tlb_table[mmu_idx][page_index].addend; |
|
337 |
return qemu_ram_addr_from_host(p); |
|
335 | 338 |
} |
336 | 339 |
|
337 | 340 |
/* Deterministic execution requires that IO only be performed on the last |
b/exec.c | ||
---|---|---|
1835 | 1835 |
} |
1836 | 1836 |
} |
1837 | 1837 |
|
1838 |
/* Note: start and end must be within the same ram block. */ |
|
1838 | 1839 |
void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, |
1839 | 1840 |
int dirty_flags) |
1840 | 1841 |
{ |
... | ... | |
1869 | 1870 |
|
1870 | 1871 |
/* we modify the TLB cache so that the dirty bit will be set again |
1871 | 1872 |
when accessing the range */ |
1872 |
start1 = start + (unsigned long)phys_ram_base; |
|
1873 |
start1 = (unsigned long)qemu_get_ram_ptr(start); |
|
1874 |
/* Chek that we don't span multiple blocks - this breaks the |
|
1875 |
address comparisons below. */ |
|
1876 |
if ((unsigned long)qemu_get_ram_ptr(end - 1) - start1 |
|
1877 |
!= (end - 1) - start) { |
|
1878 |
abort(); |
|
1879 |
} |
|
1880 |
|
|
1873 | 1881 |
for(env = first_cpu; env != NULL; env = env->next_cpu) { |
1874 | 1882 |
for(i = 0; i < CPU_TLB_SIZE; i++) |
1875 | 1883 |
tlb_reset_dirty_range(&env->tlb_table[0][i], start1, length); |
... | ... | |
1910 | 1918 |
static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry) |
1911 | 1919 |
{ |
1912 | 1920 |
ram_addr_t ram_addr; |
1921 |
void *p; |
|
1913 | 1922 |
|
1914 | 1923 |
if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) { |
1915 |
ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + |
|
1916 |
tlb_entry->addend - (unsigned long)phys_ram_base; |
|
1924 |
p = (void *)(unsigned long)((tlb_entry->addr_write & TARGET_PAGE_MASK) |
|
1925 |
+ tlb_entry->addend); |
|
1926 |
ram_addr = qemu_ram_addr_from_host(p); |
|
1917 | 1927 |
if (!cpu_physical_memory_is_dirty(ram_addr)) { |
1918 | 1928 |
tlb_entry->addr_write |= TLB_NOTDIRTY; |
1919 | 1929 |
} |
... | ... | |
2005 | 2015 |
/* IO memory case (romd handled later) */ |
2006 | 2016 |
address |= TLB_MMIO; |
2007 | 2017 |
} |
2008 |
addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK);
|
|
2018 |
addend = (unsigned long)qemu_get_ram_ptr(pd & TARGET_PAGE_MASK);
|
|
2009 | 2019 |
if ((pd & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) { |
2010 | 2020 |
/* Normal RAM. */ |
2011 | 2021 |
iotlb = pd & TARGET_PAGE_MASK; |
... | ... | |
2428 | 2438 |
} |
2429 | 2439 |
|
2430 | 2440 |
/* Return a host pointer to ram allocated with qemu_ram_alloc. |
2431 |
This may only be used if you actually allocated the ram, and |
|
2432 |
aready know how but the ram block is. */ |
|
2441 |
With the exception of the softmmu code in this file, this should |
|
2442 |
only be used for local memory (e.g. video ram) that the device owns, |
|
2443 |
and knows it isn't going to access beyond the end of the block. |
|
2444 |
|
|
2445 |
It should not be used for general purpose DMA. |
|
2446 |
Use cpu_physical_memory_map/cpu_physical_memory_rw instead. |
|
2447 |
*/ |
|
2433 | 2448 |
void *qemu_get_ram_ptr(ram_addr_t addr) |
2434 | 2449 |
{ |
2435 | 2450 |
return phys_ram_base + addr; |
2436 | 2451 |
} |
2437 | 2452 |
|
2453 |
/* Some of the softmmu routines need to translate from a host pointer |
|
2454 |
(typically a TLB entry) back to a ram offset. */ |
|
2455 |
ram_addr_t qemu_ram_addr_from_host(void *ptr) |
|
2456 |
{ |
|
2457 |
return (uint8_t *)ptr - phys_ram_base; |
|
2458 |
} |
|
2459 |
|
|
2438 | 2460 |
static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr) |
2439 | 2461 |
{ |
2440 | 2462 |
#ifdef DEBUG_UNASSIGNED |
... | ... | |
2521 | 2543 |
dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS]; |
2522 | 2544 |
#endif |
2523 | 2545 |
} |
2524 |
stb_p(phys_ram_base + ram_addr, val);
|
|
2546 |
stb_p(qemu_get_ram_ptr(ram_addr), val);
|
|
2525 | 2547 |
#ifdef USE_KQEMU |
2526 | 2548 |
if (cpu_single_env->kqemu_enabled && |
2527 | 2549 |
(dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK) |
... | ... | |
2546 | 2568 |
dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS]; |
2547 | 2569 |
#endif |
2548 | 2570 |
} |
2549 |
stw_p(phys_ram_base + ram_addr, val);
|
|
2571 |
stw_p(qemu_get_ram_ptr(ram_addr), val);
|
|
2550 | 2572 |
#ifdef USE_KQEMU |
2551 | 2573 |
if (cpu_single_env->kqemu_enabled && |
2552 | 2574 |
(dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK) |
... | ... | |
2571 | 2593 |
dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS]; |
2572 | 2594 |
#endif |
2573 | 2595 |
} |
2574 |
stl_p(phys_ram_base + ram_addr, val);
|
|
2596 |
stl_p(qemu_get_ram_ptr(ram_addr), val);
|
|
2575 | 2597 |
#ifdef USE_KQEMU |
2576 | 2598 |
if (cpu_single_env->kqemu_enabled && |
2577 | 2599 |
(dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK) |
... | ... | |
3030 | 3052 |
unsigned long addr1; |
3031 | 3053 |
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); |
3032 | 3054 |
/* RAM case */ |
3033 |
ptr = phys_ram_base + addr1;
|
|
3055 |
ptr = qemu_get_ram_ptr(addr1);
|
|
3034 | 3056 |
memcpy(ptr, buf, l); |
3035 | 3057 |
if (!cpu_physical_memory_is_dirty(addr1)) { |
3036 | 3058 |
/* invalidate code */ |
... | ... | |
3066 | 3088 |
} |
3067 | 3089 |
} else { |
3068 | 3090 |
/* RAM case */ |
3069 |
ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
|
|
3091 |
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
|
|
3070 | 3092 |
(addr & ~TARGET_PAGE_MASK); |
3071 | 3093 |
memcpy(buf, ptr, l); |
3072 | 3094 |
} |
... | ... | |
3107 | 3129 |
unsigned long addr1; |
3108 | 3130 |
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); |
3109 | 3131 |
/* ROM/RAM case */ |
3110 |
ptr = phys_ram_base + addr1;
|
|
3132 |
ptr = qemu_get_ram_ptr(addr1);
|
|
3111 | 3133 |
memcpy(ptr, buf, l); |
3112 | 3134 |
} |
3113 | 3135 |
len -= l; |
... | ... | |
3207 | 3229 |
ptr = bounce.buffer; |
3208 | 3230 |
} else { |
3209 | 3231 |
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); |
3210 |
ptr = phys_ram_base + addr1;
|
|
3232 |
ptr = qemu_get_ram_ptr(addr1);
|
|
3211 | 3233 |
} |
3212 | 3234 |
if (!done) { |
3213 | 3235 |
ret = ptr; |
... | ... | |
3232 | 3254 |
{ |
3233 | 3255 |
if (buffer != bounce.buffer) { |
3234 | 3256 |
if (is_write) { |
3235 |
unsigned long addr1 = (uint8_t *)buffer - phys_ram_base;
|
|
3257 |
ram_addr_t addr1 = qemu_ram_addr_from_host(buffer);
|
|
3236 | 3258 |
while (access_len) { |
3237 | 3259 |
unsigned l; |
3238 | 3260 |
l = TARGET_PAGE_SIZE; |
... | ... | |
3284 | 3306 |
val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); |
3285 | 3307 |
} else { |
3286 | 3308 |
/* RAM case */ |
3287 |
ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
|
|
3309 |
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
|
|
3288 | 3310 |
(addr & ~TARGET_PAGE_MASK); |
3289 | 3311 |
val = ldl_p(ptr); |
3290 | 3312 |
} |
... | ... | |
3322 | 3344 |
#endif |
3323 | 3345 |
} else { |
3324 | 3346 |
/* RAM case */ |
3325 |
ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
|
|
3347 |
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
|
|
3326 | 3348 |
(addr & ~TARGET_PAGE_MASK); |
3327 | 3349 |
val = ldq_p(ptr); |
3328 | 3350 |
} |
... | ... | |
3369 | 3391 |
io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val); |
3370 | 3392 |
} else { |
3371 | 3393 |
unsigned long addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); |
3372 |
ptr = phys_ram_base + addr1;
|
|
3394 |
ptr = qemu_get_ram_ptr(addr1);
|
|
3373 | 3395 |
stl_p(ptr, val); |
3374 | 3396 |
|
3375 | 3397 |
if (unlikely(in_migration)) { |
... | ... | |
3410 | 3432 |
io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val >> 32); |
3411 | 3433 |
#endif |
3412 | 3434 |
} else { |
3413 |
ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
|
|
3435 |
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
|
|
3414 | 3436 |
(addr & ~TARGET_PAGE_MASK); |
3415 | 3437 |
stq_p(ptr, val); |
3416 | 3438 |
} |
... | ... | |
3440 | 3462 |
unsigned long addr1; |
3441 | 3463 |
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); |
3442 | 3464 |
/* RAM case */ |
3443 |
ptr = phys_ram_base + addr1;
|
|
3465 |
ptr = qemu_get_ram_ptr(addr1);
|
|
3444 | 3466 |
stl_p(ptr, val); |
3445 | 3467 |
if (!cpu_physical_memory_is_dirty(addr1)) { |
3446 | 3468 |
/* invalidate code */ |
b/kvm-all.c | ||
---|---|---|
101 | 101 |
mem.slot = slot->slot; |
102 | 102 |
mem.guest_phys_addr = slot->start_addr; |
103 | 103 |
mem.memory_size = slot->memory_size; |
104 |
mem.userspace_addr = (unsigned long)phys_ram_base + slot->phys_offset;
|
|
104 |
mem.userspace_addr = (unsigned long)qemu_get_ram_ptr(slot->phys_offset);
|
|
105 | 105 |
mem.flags = slot->flags; |
106 | 106 |
|
107 | 107 |
return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); |
... | ... | |
329 | 329 |
|
330 | 330 |
/* initially, KVM allocated its own memory and we had to jump through |
331 | 331 |
* hooks to make phys_ram_base point to this. Modern versions of KVM |
332 |
* just use a user allocated buffer so we can use phys_ram_base
|
|
332 |
* just use a user allocated buffer so we can use regular pages
|
|
333 | 333 |
* unmodified. Make sure we have a sufficiently modern version of KVM. |
334 | 334 |
*/ |
335 | 335 |
ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_USER_MEMORY); |
b/vl.c | ||
---|---|---|
3097 | 3097 |
if (qemu_get_be32(f) != phys_ram_size) |
3098 | 3098 |
return -EINVAL; |
3099 | 3099 |
for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) { |
3100 |
ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
|
|
3100 |
ret = ram_get_page(f, qemu_get_ram_ptr(i), TARGET_PAGE_SIZE);
|
|
3101 | 3101 |
if (ret) |
3102 | 3102 |
return ret; |
3103 | 3103 |
} |
... | ... | |
3184 | 3184 |
|
3185 | 3185 |
while (addr < phys_ram_size) { |
3186 | 3186 |
if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) { |
3187 |
uint8_t ch;
|
|
3187 |
uint8_t *p;
|
|
3188 | 3188 |
|
3189 | 3189 |
cpu_physical_memory_reset_dirty(current_addr, |
3190 | 3190 |
current_addr + TARGET_PAGE_SIZE, |
3191 | 3191 |
MIGRATION_DIRTY_FLAG); |
3192 | 3192 |
|
3193 |
ch = *(phys_ram_base + current_addr);
|
|
3193 |
p = qemu_get_ram_ptr(current_addr);
|
|
3194 | 3194 |
|
3195 |
if (is_dup_page(phys_ram_base + current_addr, ch)) {
|
|
3195 |
if (is_dup_page(p, *p)) {
|
|
3196 | 3196 |
qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS); |
3197 |
qemu_put_byte(f, ch);
|
|
3197 |
qemu_put_byte(f, *p);
|
|
3198 | 3198 |
} else { |
3199 | 3199 |
qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE); |
3200 |
qemu_put_buffer(f, phys_ram_base + current_addr, TARGET_PAGE_SIZE);
|
|
3200 |
qemu_put_buffer(f, p, TARGET_PAGE_SIZE); |
|
3201 | 3201 |
} |
3202 | 3202 |
|
3203 | 3203 |
found = 1; |
... | ... | |
3278 | 3278 |
goto error; |
3279 | 3279 |
} |
3280 | 3280 |
if (buf[0] == 0) { |
3281 |
if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) { |
|
3281 |
if (ram_decompress_buf(s, qemu_get_ram_ptr(i), |
|
3282 |
BDRV_HASH_BLOCK_SIZE) < 0) { |
|
3282 | 3283 |
fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i); |
3283 | 3284 |
goto error; |
3284 | 3285 |
} |
... | ... | |
3328 | 3329 |
|
3329 | 3330 |
if (flags & RAM_SAVE_FLAG_COMPRESS) { |
3330 | 3331 |
uint8_t ch = qemu_get_byte(f); |
3331 |
memset(phys_ram_base + addr, ch, TARGET_PAGE_SIZE);
|
|
3332 |
memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
|
|
3332 | 3333 |
} else if (flags & RAM_SAVE_FLAG_PAGE) |
3333 |
qemu_get_buffer(f, phys_ram_base + addr, TARGET_PAGE_SIZE);
|
|
3334 |
qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
|
|
3334 | 3335 |
} while (!(flags & RAM_SAVE_FLAG_EOS)); |
3335 | 3336 |
|
3336 | 3337 |
return 0; |
Also available in: Unified diff