diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-09-30 14:21:56 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-09-30 14:21:56 +0100 |
commit | 95e9d74fe4281f7ad79a5a7511400541729aa44a (patch) | |
tree | 1fc2502eea4b4a9add852b4d41b784a65ef9cd6b /hw | |
parent | 786d36ad416c6c199b18b78cc31eddfb784fe15d (diff) | |
parent | c5b9ce518c0551d0198bcddadc82e03de9ac8de9 (diff) | |
download | qemu-95e9d74fe4281f7ad79a5a7511400541729aa44a.zip qemu-95e9d74fe4281f7ad79a5a7511400541729aa44a.tar.gz qemu-95e9d74fe4281f7ad79a5a7511400541729aa44a.tar.bz2 |
Merge remote-tracking branch 'remotes/borntraeger/tags/s390x-20190930' into staging
- do not abuse memory_region_allocate_system_memory and split the memory
according to KVM memslots in KVM code instead (Paolo, Igor)
- change splitting to split at 4TB (Christian)
- do not claim s390 (31bit) support in configure (Thomas)
- sclp error checking (Janosch, Claudio)
- new s390 pci maintainer (Matt, Collin)
- fix s390 pci (again) (Matt)
# gpg: Signature made Mon 30 Sep 2019 12:52:51 BST
# gpg: using RSA key 117BBC80B5A61C7C
# gpg: Good signature from "Christian Borntraeger (IBM) <borntraeger@de.ibm.com>" [full]
# Primary key fingerprint: F922 9381 A334 08F9 DBAB FBCA 117B BC80 B5A6 1C7C
* remotes/borntraeger/tags/s390x-20190930:
s390/kvm: split kvm mem slots at 4TB
s390: do not call memory_region_allocate_system_memory() multiple times
kvm: split too big memory section on several memslots
kvm: clear dirty bitmaps from all overlapping memslots
kvm: extract kvm_log_clear_one_slot
configure: Remove s390 (31-bit mode) from the list of supported CPUs
s390x: sclp: Report insufficient SCCB length
s390x: sclp: fix error handling for oversize control blocks
s390x: sclp: boundary check
s390x: sclp: refactor invalid command check
s390: PCI: fix IOMMU region init
MAINTAINERS: Update S390 PCI Maintainer
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/s390x/event-facility.c | 3 | ||||
-rw-r--r-- | hw/s390x/s390-pci-bus.c | 7 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-ccw.c | 30 | ||||
-rw-r--r-- | hw/s390x/sclp.c | 37 |
4 files changed, 43 insertions, 34 deletions
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index 797ecbb..6620569 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -377,9 +377,6 @@ static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code) case SCLP_CMD_WRITE_EVENT_MASK: write_event_mask(ef, sccb); break; - default: - sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND); - break; } } diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index 963a41c..2d2f4a7 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -695,10 +695,15 @@ static const MemoryRegionOps s390_msi_ctrl_ops = { void s390_pci_iommu_enable(S390PCIIOMMU *iommu) { + /* + * The iommu region is initialized against a 0-mapped address space, + * so the smallest IOMMU region we can define runs from 0 to the end + * of the PCI address space. + */ char *name = g_strdup_printf("iommu-s390-%04x", iommu->pbdev->uid); memory_region_init_iommu(&iommu->iommu_mr, sizeof(iommu->iommu_mr), TYPE_S390_IOMMU_MEMORY_REGION, OBJECT(&iommu->mr), - name, iommu->pal - iommu->pba + 1); + name, iommu->pal + 1); iommu->enabled = true; memory_region_add_subregion(&iommu->mr, 0, MEMORY_REGION(&iommu->iommu_mr)); g_free(name); diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 8bfb668..18ad279 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -154,39 +154,15 @@ 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(); - ram_addr_t chunk, offset = 0; - unsigned int number = 0; + MemoryRegion *ram = g_new(MemoryRegion, 1); Error *local_err = NULL; - gchar *name; /* allocate RAM for core */ - 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); + memory_region_allocate_system_memory(ram, NULL, "s390.ram", mem_size); + memory_region_add_subregion(sysmem, 0, ram); /* * Configure the maximum page size. As no memory devices were created diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c index fac7c3b..f57ce7b 100644 --- a/hw/s390x/sclp.c +++ b/hw/s390x/sclp.c @@ -68,6 +68,12 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb) read_info->ibc_val = cpu_to_be32(s390_get_ibc_val()); + if (be16_to_cpu(sccb->h.length) < + (sizeof(ReadInfo) + cpu_count * sizeof(CPUEntry))) { + sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH); + return; + } + /* Configuration Characteristic (Extension) */ s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR, read_info->conf_char); @@ -118,6 +124,12 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb) cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries)); cpu_info->nr_standby = cpu_to_be16(0); + if (be16_to_cpu(sccb->h.length) < + (sizeof(ReadCpuInfo) + cpu_count * sizeof(CPUEntry))) { + sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH); + return; + } + /* The standby offset is 16-byte for each CPU */ cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured + cpu_info->nr_configured*sizeof(CPUEntry)); @@ -213,14 +225,33 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code) cpu_physical_memory_read(sccb, &work_sccb, sccb_len); /* Valid sccb sizes */ - if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader) || - be16_to_cpu(work_sccb.h.length) > SCCB_SIZE) { + if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader)) { r = -PGM_SPECIFICATION; goto out; } - sclp_c->execute(sclp, &work_sccb, code); + switch (code & SCLP_CMD_CODE_MASK) { + case SCLP_CMDW_READ_SCP_INFO: + case SCLP_CMDW_READ_SCP_INFO_FORCED: + case SCLP_CMDW_READ_CPU_INFO: + case SCLP_CMDW_CONFIGURE_IOA: + case SCLP_CMDW_DECONFIGURE_IOA: + case SCLP_CMD_READ_EVENT_DATA: + case SCLP_CMD_WRITE_EVENT_DATA: + case SCLP_CMD_WRITE_EVENT_MASK: + break; + default: + work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND); + goto out_write; + } + + if ((sccb + be16_to_cpu(work_sccb.h.length)) > ((sccb & PAGE_MASK) + PAGE_SIZE)) { + work_sccb.h.response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION); + goto out_write; + } + sclp_c->execute(sclp, &work_sccb, code); +out_write: cpu_physical_memory_write(sccb, &work_sccb, be16_to_cpu(work_sccb.h.length)); |