Skip to content

Commit

Permalink
s390-ccw-virtio: allow for systems larger that 7.999TB
Browse files Browse the repository at this point in the history
KVM does not allow memory regions > KVM_MEM_MAX_NR_PAGES, basically
limiting the memory per slot to 8TB-4k. As memory slots on s390/kvm must
be a multiple of 1MB we need start a new memory region if we cross
8TB-1M.

With that (and optimistic overcommitment in the kernel) I was able to
start a 24TB guest on a 1TB system.

Signed-off-by: Christian Borntraeger <[email protected]>
Message-Id: <[email protected]>
Reviewed-by: David Hildenbrand <[email protected]>
[CH: 1UL -> 1ULL in KVM_MEM_MAX_NR_PAGES; build fix on 32 bit hosts]
Signed-off-by: Cornelia Huck <[email protected]>
  • Loading branch information
borntraeger authored and cohuck committed Dec 15, 2017
1 parent 35b4df6 commit bb22305
Showing 1 changed file with 27 additions and 3 deletions.
30 changes: 27 additions & 3 deletions hw/s390x/s390-virtio-ccw.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,38 @@ static void virtio_ccw_register_hcalls(void)
virtio_ccw_hcall_early_printk);
}

/*
* KVM does only support memory slots up to KVM_MEM_MAX_NR_PAGES pages
* as the dirty bitmap must be managed by bitops that take an int as
* position indicator. If we have a guest beyond that we will split off
* new subregions. The split must happen on a segment boundary (1MB).
*/
#define KVM_MEM_MAX_NR_PAGES ((1ULL << 31) - 1)
#define SEG_MSK (~0xfffffULL)
#define KVM_SLOT_MAX_BYTES ((KVM_MEM_MAX_NR_PAGES * TARGET_PAGE_SIZE) & SEG_MSK)
static void s390_memory_init(ram_addr_t mem_size)
{
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);
ram_addr_t chunk, offset = 0;
unsigned int number = 0;
gchar *name;

/* allocate RAM for core */
memory_region_allocate_system_memory(ram, NULL, "s390.ram", mem_size);
memory_region_add_subregion(sysmem, 0, ram);
name = g_strdup_printf("s390.ram");
while (mem_size) {
MemoryRegion *ram = g_new(MemoryRegion, 1);
uint64_t size = mem_size;

/* KVM does not allow memslots >= 8 TB */
chunk = MIN(size, KVM_SLOT_MAX_BYTES);
memory_region_allocate_system_memory(ram, NULL, name, chunk);
memory_region_add_subregion(sysmem, offset, ram);
mem_size -= chunk;
offset += chunk;
g_free(name);
name = g_strdup_printf("s390.ram.%u", ++number);
}
g_free(name);

/* Initialize storage key device */
s390_skeys_init();
Expand Down

0 comments on commit bb22305

Please sign in to comment.