aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/s390x/s390-skeys.c2
-rw-r--r--hw/s390x/s390-stattrib-kvm.c4
-rw-r--r--hw/s390x/s390-virtio-ccw.c22
-rw-r--r--hw/s390x/sclp.c17
-rw-r--r--include/hw/boards.h7
-rw-r--r--softmmu/vl.c3
6 files changed, 40 insertions, 15 deletions
diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
index 5da6e52..a9a4ae7 100644
--- a/hw/s390x/s390-skeys.c
+++ b/hw/s390x/s390-skeys.c
@@ -176,7 +176,7 @@ static void qemu_s390_skeys_init(Object *obj)
QEMUS390SKeysState *skeys = QEMU_S390_SKEYS(obj);
MachineState *machine = MACHINE(qdev_get_machine());
- skeys->key_count = machine->maxram_size / TARGET_PAGE_SIZE;
+ skeys->key_count = machine->ram_size / TARGET_PAGE_SIZE;
skeys->keydata = g_malloc0(skeys->key_count);
}
diff --git a/hw/s390x/s390-stattrib-kvm.c b/hw/s390x/s390-stattrib-kvm.c
index c7e1f35..f89d8d9 100644
--- a/hw/s390x/s390-stattrib-kvm.c
+++ b/hw/s390x/s390-stattrib-kvm.c
@@ -85,7 +85,7 @@ static int kvm_s390_stattrib_set_stattr(S390StAttribState *sa,
{
KVMS390StAttribState *sas = KVM_S390_STATTRIB(sa);
MachineState *machine = MACHINE(qdev_get_machine());
- unsigned long max = machine->maxram_size / TARGET_PAGE_SIZE;
+ unsigned long max = machine->ram_size / TARGET_PAGE_SIZE;
if (start_gfn + count > max) {
error_report("Out of memory bounds when setting storage attributes");
@@ -104,7 +104,7 @@ static void kvm_s390_stattrib_synchronize(S390StAttribState *sa)
{
KVMS390StAttribState *sas = KVM_S390_STATTRIB(sa);
MachineState *machine = MACHINE(qdev_get_machine());
- unsigned long max = machine->maxram_size / TARGET_PAGE_SIZE;
+ unsigned long max = machine->ram_size / TARGET_PAGE_SIZE;
/* We do not need to reach the maximum buffer size allowed */
unsigned long cx, len = KVM_S390_SKEYS_MAX / 2;
int r;
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 895498c..0fa00a9 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -26,6 +26,7 @@
#include "qemu/ctype.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
+#include "qemu/qemu-print.h"
#include "s390-pci-bus.h"
#include "sysemu/reset.h"
#include "hw/s390x/storage-keys.h"
@@ -439,6 +440,26 @@ static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
s390_cpu_restart(S390_CPU(cs));
}
+static ram_addr_t s390_fixup_ram_size(ram_addr_t sz)
+{
+ /* same logic as in sclp.c */
+ int increment_size = 20;
+ ram_addr_t newsz;
+
+ while ((sz >> increment_size) > MAX_STORAGE_INCREMENTS) {
+ increment_size++;
+ }
+ newsz = sz >> increment_size << increment_size;
+
+ if (sz != newsz) {
+ qemu_printf("Ram size %" PRIu64 "MB was fixed up to %" PRIu64
+ "MB to match machine restrictions. Consider updating "
+ "the guest definition.\n", (uint64_t) (sz / MiB),
+ (uint64_t) (newsz / MiB));
+ }
+ return newsz;
+}
+
static void ccw_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -668,6 +689,7 @@ static void ccw_machine_4_2_instance_options(MachineState *machine)
static void ccw_machine_4_2_class_options(MachineClass *mc)
{
ccw_machine_5_0_class_options(mc);
+ mc->fixup_ram_size = s390_fixup_ram_size;
compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
}
DEFINE_CCW_MACHINE(4_2, "4.2", false);
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index af0bfbc..f0c35aa 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -327,27 +327,20 @@ out:
static void sclp_memory_init(SCLPDevice *sclp)
{
MachineState *machine = MACHINE(qdev_get_machine());
+ MachineClass *machine_class = MACHINE_GET_CLASS(qdev_get_machine());
ram_addr_t initial_mem = machine->ram_size;
int increment_size = 20;
/* The storage increment size is a multiple of 1M and is a power of 2.
- * The number of storage increments must be MAX_STORAGE_INCREMENTS or fewer.
+ * For some machine types, the number of storage increments must be
+ * MAX_STORAGE_INCREMENTS or fewer.
* The variable 'increment_size' is an exponent of 2 that can be
* used to calculate the size (in bytes) of an increment. */
- while ((initial_mem >> increment_size) > MAX_STORAGE_INCREMENTS) {
+ while (machine_class->fixup_ram_size != NULL &&
+ (initial_mem >> increment_size) > MAX_STORAGE_INCREMENTS) {
increment_size++;
}
sclp->increment_size = increment_size;
-
- /* The core memory area needs to be aligned with the increment size.
- * In effect, this can cause the user-specified memory size to be rounded
- * down to align with the nearest increment boundary. */
- initial_mem = initial_mem >> increment_size << increment_size;
-
- machine->ram_size = initial_mem;
- machine->maxram_size = initial_mem;
- /* let's propagate the changed ram size into the global variable. */
- ram_size = initial_mem;
}
static void sclp_init(Object *obj)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 236d239..fd4d62b 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -152,6 +152,12 @@ typedef struct {
* It also will be used as a way to optin into "-m" option support.
* If it's not set by board, '-m' will be ignored and generic code will
* not create default RAM MemoryRegion.
+ * @fixup_ram_size:
+ * Amends user provided ram size (with -m option) using machine
+ * specific algorithm. To be used by old machine types for compat
+ * purposes only.
+ * Applies only to default memory backend, i.e., explicit memory backend
+ * wasn't used.
*/
struct MachineClass {
/*< private >*/
@@ -218,6 +224,7 @@ struct MachineClass {
unsigned cpu_index);
const CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
int64_t (*get_default_cpu_node_id)(const MachineState *ms, int idx);
+ ram_addr_t (*fixup_ram_size)(ram_addr_t size);
};
/**
diff --git a/softmmu/vl.c b/softmmu/vl.c
index a331fb5..a0c1a87 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2600,6 +2600,9 @@ static bool set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size,
}
sz = QEMU_ALIGN_UP(sz, 8192);
+ if (mc->fixup_ram_size) {
+ sz = mc->fixup_ram_size(sz);
+ }
ram_size = sz;
if (ram_size != sz) {
error_report("ram size too large");