Revision 04b16653 exec.c
b/exec.c | ||
---|---|---|
2701 | 2701 |
return fs.f_bsize; |
2702 | 2702 |
} |
2703 | 2703 |
|
2704 |
static void *file_ram_alloc(ram_addr_t memory, const char *path) |
|
2704 |
static void *file_ram_alloc(RAMBlock *block, |
|
2705 |
ram_addr_t memory, |
|
2706 |
const char *path) |
|
2705 | 2707 |
{ |
2706 | 2708 |
char *filename; |
2707 | 2709 |
void *area; |
... | ... | |
2764 | 2766 |
close(fd); |
2765 | 2767 |
return (NULL); |
2766 | 2768 |
} |
2769 |
block->fd = fd; |
|
2767 | 2770 |
return area; |
2768 | 2771 |
} |
2769 | 2772 |
#endif |
2770 | 2773 |
|
2771 | 2774 |
static ram_addr_t find_ram_offset(ram_addr_t size) |
2772 | 2775 |
{ |
2776 |
RAMBlock *block, *next_block; |
|
2777 |
ram_addr_t offset, mingap = ULONG_MAX; |
|
2778 |
|
|
2779 |
if (QLIST_EMPTY(&ram_list.blocks)) |
|
2780 |
return 0; |
|
2781 |
|
|
2782 |
QLIST_FOREACH(block, &ram_list.blocks, next) { |
|
2783 |
ram_addr_t end, next = ULONG_MAX; |
|
2784 |
|
|
2785 |
end = block->offset + block->length; |
|
2786 |
|
|
2787 |
QLIST_FOREACH(next_block, &ram_list.blocks, next) { |
|
2788 |
if (next_block->offset >= end) { |
|
2789 |
next = MIN(next, next_block->offset); |
|
2790 |
} |
|
2791 |
} |
|
2792 |
if (next - end >= size && next - end < mingap) { |
|
2793 |
offset = end; |
|
2794 |
mingap = next - end; |
|
2795 |
} |
|
2796 |
} |
|
2797 |
return offset; |
|
2798 |
} |
|
2799 |
|
|
2800 |
static ram_addr_t last_ram_offset(void) |
|
2801 |
{ |
|
2773 | 2802 |
RAMBlock *block; |
2774 | 2803 |
ram_addr_t last = 0; |
2775 | 2804 |
|
... | ... | |
2812 | 2841 |
|
2813 | 2842 |
if (mem_path) { |
2814 | 2843 |
#if defined (__linux__) && !defined(TARGET_S390X) |
2815 |
new_block->host = file_ram_alloc(size, mem_path); |
|
2844 |
new_block->host = file_ram_alloc(new_block, size, mem_path);
|
|
2816 | 2845 |
if (!new_block->host) { |
2817 | 2846 |
new_block->host = qemu_vmalloc(size); |
2818 | 2847 |
#ifdef MADV_MERGEABLE |
... | ... | |
2842 | 2871 |
QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next); |
2843 | 2872 |
|
2844 | 2873 |
ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty, |
2845 |
(new_block->offset + size) >> TARGET_PAGE_BITS);
|
|
2874 |
last_ram_offset() >> TARGET_PAGE_BITS);
|
|
2846 | 2875 |
memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS), |
2847 | 2876 |
0xff, size >> TARGET_PAGE_BITS); |
2848 | 2877 |
|
... | ... | |
2854 | 2883 |
|
2855 | 2884 |
void qemu_ram_free(ram_addr_t addr) |
2856 | 2885 |
{ |
2857 |
/* TODO: implement this. */ |
|
2886 |
RAMBlock *block; |
|
2887 |
|
|
2888 |
QLIST_FOREACH(block, &ram_list.blocks, next) { |
|
2889 |
if (addr == block->offset) { |
|
2890 |
QLIST_REMOVE(block, next); |
|
2891 |
if (mem_path) { |
|
2892 |
#if defined (__linux__) && !defined(TARGET_S390X) |
|
2893 |
if (block->fd) { |
|
2894 |
munmap(block->host, block->length); |
|
2895 |
close(block->fd); |
|
2896 |
} else { |
|
2897 |
qemu_vfree(block->host); |
|
2898 |
} |
|
2899 |
#endif |
|
2900 |
} else { |
|
2901 |
#if defined(TARGET_S390X) && defined(CONFIG_KVM) |
|
2902 |
munmap(block->host, block->length); |
|
2903 |
#else |
|
2904 |
qemu_vfree(block->host); |
|
2905 |
#endif |
|
2906 |
} |
|
2907 |
qemu_free(block); |
|
2908 |
return; |
|
2909 |
} |
|
2910 |
} |
|
2911 |
|
|
2858 | 2912 |
} |
2859 | 2913 |
|
2860 | 2914 |
/* Return a host pointer to ram allocated with qemu_ram_alloc. |
Also available in: Unified diff