summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/s390-virtio.c20
-rw-r--r--target-s390x/op_helper.c8
2 files changed, 21 insertions, 7 deletions
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 698ff6f345..3eba7ea1e8 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -131,7 +131,7 @@ int s390_virtio_hypercall(CPUState *env, uint64_t mem, uint64_t hypercall)
}
/* PC hardware initialisation */
-static void s390_init(ram_addr_t ram_size,
+static void s390_init(ram_addr_t my_ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
@@ -143,19 +143,29 @@ static void s390_init(ram_addr_t ram_size,
ram_addr_t kernel_size = 0;
ram_addr_t initrd_offset;
ram_addr_t initrd_size = 0;
+ int shift = 0;
uint8_t *storage_keys;
int i;
+ /* s390x ram size detection needs a 16bit multiplier + an increment. So
+ guests > 64GB can be specified in 2MB steps etc. */
+ while ((my_ram_size >> (20 + shift)) > 65535) {
+ shift++;
+ }
+ my_ram_size = my_ram_size >> (20 + shift) << (20 + shift);
+
+ /* lets propagate the changed ram size into the global variable. */
+ ram_size = my_ram_size;
/* get a BUS */
- s390_bus = s390_virtio_bus_init(&ram_size);
+ s390_bus = s390_virtio_bus_init(&my_ram_size);
/* allocate RAM */
- ram_addr = qemu_ram_alloc(NULL, "s390.ram", ram_size);
- cpu_register_physical_memory(0, ram_size, ram_addr);
+ ram_addr = qemu_ram_alloc(NULL, "s390.ram", my_ram_size);
+ cpu_register_physical_memory(0, my_ram_size, ram_addr);
/* allocate storage keys */
- storage_keys = qemu_mallocz(ram_size / TARGET_PAGE_SIZE);
+ storage_keys = qemu_mallocz(my_ram_size / TARGET_PAGE_SIZE);
/* init CPUs */
if (cpu_model == NULL) {
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index 9153940540..49760a40a2 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -2361,6 +2361,7 @@ static void ext_interrupt(CPUState *env, int type, uint32_t param,
int sclp_service_call(CPUState *env, uint32_t sccb, uint64_t code)
{
int r = 0;
+ int shift = 0;
#ifdef DEBUG_HELPER
printf("sclp(0x%x, 0x%" PRIx64 ")\n", sccb, code);
@@ -2375,8 +2376,11 @@ int sclp_service_call(CPUState *env, uint32_t sccb, uint64_t code)
switch(code) {
case SCLP_CMDW_READ_SCP_INFO:
case SCLP_CMDW_READ_SCP_INFO_FORCED:
- stw_phys(sccb + SCP_MEM_CODE, ram_size >> 20);
- stb_phys(sccb + SCP_INCREMENT, 1);
+ while ((ram_size >> (20 + shift)) > 65535) {
+ shift++;
+ }
+ stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift));
+ stb_phys(sccb + SCP_INCREMENT, 1 << shift);
stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
if (kvm_enabled()) {