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.
|