aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-02-03 13:19:52 +0000
committerPeter Maydell <peter.maydell@linaro.org>2015-02-03 13:19:52 +0000
commit007c99fd0fb4e0f0579872bb71f5de99b5943dc2 (patch)
treea108f897d894220e1599d967f39b1bbbbea53c60
parentd5fbb4c9ed52d97aebe5994d8a857c74c0d95a92 (diff)
parent553ce81c31e49d834b1bf635ab486695a4694333 (diff)
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20150203' into staging
Some bugfixes and cleanups for s390x, both in the new pci code and in old code. # gpg: Signature made Tue 03 Feb 2015 13:01:04 GMT using RSA key ID C6F02FAF # gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>" # gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>" * remotes/cohuck/tags/s390x-20150203: pc-bios/s390-ccw: update binary pc-bios/s390-ccw: fix sparse warnings s390x/ipl: Improved code indentation in s390_ipl_init() s390x/kvm: unknown DIAGNOSE code should give a specification exception s390x/kvm: Fix diag-308 register decoding s390x/pci: fix dma notifications in rpcit instruction s390x/pci: check for invalid function handle s390x/pci: avoid sign extension in stpcifc s390: Plug memory leak on s390_pci_generate_event() error path Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/s390x/ipl.c47
-rw-r--r--hw/s390x/s390-pci-bus.c5
-rw-r--r--hw/s390x/s390-pci-inst.c28
-rw-r--r--pc-bios/s390-ccw.imgbin17752 -> 17752 bytes
-rw-r--r--pc-bios/s390-ccw/bootmap.c4
-rw-r--r--pc-bios/s390-ccw/bootmap.h2
-rw-r--r--pc-bios/s390-ccw/main.c2
-rw-r--r--pc-bios/s390-ccw/s390-ccw.h2
-rw-r--r--pc-bios/s390-ccw/virtio.c2
-rw-r--r--target-s390x/kvm.c4
10 files changed, 52 insertions, 44 deletions
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 3b77c9a227..4ba8409668 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -62,6 +62,7 @@ typedef struct S390IPLState {
static int s390_ipl_init(SysBusDevice *dev)
{
S390IPLState *ipl = S390_IPL(dev);
+ uint64_t pentry = KERN_IMAGE_START;
int kernel_size;
if (!ipl->kernel) {
@@ -94,31 +95,31 @@ static int s390_ipl_init(SysBusDevice *dev)
hw_error("could not load bootloader '%s'\n", bios_name);
}
return 0;
+ }
+
+ kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL,
+ NULL, 1, ELF_MACHINE, 0);
+ if (kernel_size < 0) {
+ kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
+ }
+ if (kernel_size < 0) {
+ fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel);
+ return -1;
+ }
+ /*
+ * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the
+ * kernel parameters here as well. Note: For old kernels (up to 3.2)
+ * we can not rely on the ELF entry point - it was 0x800 (the SALIPL
+ * loader) and it won't work. For this case we force it to 0x10000, too.
+ */
+ if (pentry == KERN_IMAGE_START || pentry == 0x800) {
+ ipl->start_addr = KERN_IMAGE_START;
+ /* Overwrite parameters in the kernel image, which are "rom" */
+ strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);
} else {
- uint64_t pentry = KERN_IMAGE_START;
- kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL,
- NULL, 1, ELF_MACHINE, 0);
- if (kernel_size < 0) {
- kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
- }
- if (kernel_size < 0) {
- fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel);
- return -1;
- }
- /*
- * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the
- * kernel parameters here as well. Note: For old kernels (up to 3.2)
- * we can not rely on the ELF entry point - it was 0x800 (the SALIPL
- * loader) and it won't work. For this case we force it to 0x10000, too.
- */
- if (pentry == KERN_IMAGE_START || pentry == 0x800) {
- ipl->start_addr = KERN_IMAGE_START;
- /* Overwrite parameters in the kernel image, which are "rom" */
- strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);
- } else {
- ipl->start_addr = pentry;
- }
+ ipl->start_addr = pentry;
}
+
if (ipl->initrd) {
ram_addr_t initrd_offset;
int initrd_size;
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 1201b8d57c..dc455a2bb7 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -170,7 +170,7 @@ S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh)
S390pciState *s = S390_PCI_HOST_BRIDGE(
object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
- if (!s) {
+ if (!s || !fh) {
return NULL;
}
@@ -187,7 +187,7 @@ S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh)
static void s390_pci_generate_event(uint8_t cc, uint16_t pec, uint32_t fh,
uint32_t fid, uint64_t faddr, uint32_t e)
{
- SeiContainer *sei_cont = g_malloc0(sizeof(SeiContainer));
+ SeiContainer *sei_cont;
S390pciState *s = S390_PCI_HOST_BRIDGE(
object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
@@ -195,6 +195,7 @@ static void s390_pci_generate_event(uint8_t cc, uint16_t pec, uint32_t fh,
return;
}
+ sei_cont = g_malloc0(sizeof(SeiContainer));
sei_cont->fh = fh;
sei_cont->fid = fid;
sei_cont->cc = cc;
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 5ea13e5d79..9e5bc5b899 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -487,7 +487,7 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
CPUS390XState *env = &cpu->env;
uint32_t fh;
S390PCIBusDevice *pbdev;
- ram_addr_t size;
+ hwaddr start, end;
IOMMUTLBEntry entry;
MemoryRegion *mr;
@@ -504,7 +504,8 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
}
fh = env->regs[r1] >> 32;
- size = env->regs[r2 + 1];
+ start = env->regs[r2];
+ end = start + env->regs[r2 + 1];
pbdev = s390_pci_find_dev_by_fh(fh);
@@ -515,15 +516,18 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
}
mr = pci_device_iommu_address_space(pbdev->pdev)->root;
- entry = mr->iommu_ops->translate(mr, env->regs[r2], 0);
+ while (start < end) {
+ entry = mr->iommu_ops->translate(mr, start, 0);
- if (!entry.translated_addr) {
- setcc(cpu, ZPCI_PCI_LS_ERR);
- goto out;
+ if (!entry.translated_addr) {
+ setcc(cpu, ZPCI_PCI_LS_ERR);
+ goto out;
+ }
+
+ memory_region_notify_iommu(mr, entry);
+ start += entry.addr_mask + 1;
}
- entry.addr_mask = size - 1;
- memory_region_notify_iommu(mr, entry);
setcc(cpu, ZPCI_PCI_LS_OK);
out:
return 0;
@@ -784,10 +788,10 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
stq_p(&fib.aisb, pbdev->routes.adapter.summary_addr);
stq_p(&fib.fmb_addr, pbdev->fmb_addr);
- data = (pbdev->isc << 28) | (pbdev->noi << 16) |
- (pbdev->routes.adapter.ind_offset << 8) | (pbdev->sum << 7) |
- pbdev->routes.adapter.summary_offset;
- stw_p(&fib.data, data);
+ data = ((uint32_t)pbdev->isc << 28) | ((uint32_t)pbdev->noi << 16) |
+ ((uint32_t)pbdev->routes.adapter.ind_offset << 8) |
+ ((uint32_t)pbdev->sum << 7) | pbdev->routes.adapter.summary_offset;
+ stl_p(&fib.data, data);
if (pbdev->fh >> ENABLE_BIT_OFFSET) {
fib.fc |= 0x80;
diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img
index 44873ad181..dbe5a38262 100644
--- a/pc-bios/s390-ccw.img
+++ b/pc-bios/s390-ccw.img
Binary files differ
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 115d8bbac6..b678d5ebb8 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -33,7 +33,7 @@ typedef struct ResetInfo {
uint32_t ipl_continue;
} ResetInfo;
-ResetInfo save;
+static ResetInfo save;
static void jump_to_IPL_2(void)
{
@@ -80,7 +80,7 @@ static void jump_to_IPL_code(uint64_t address)
*/
static unsigned char _bprs[8*1024]; /* guessed "max" ECKD sector size */
-const int max_bprs_entries = sizeof(_bprs) / sizeof(ExtEckdBlockPtr);
+static const int max_bprs_entries = sizeof(_bprs) / sizeof(ExtEckdBlockPtr);
static inline void verify_boot_info(BootInfo *bip)
{
diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h
index 6a4823d544..ab132e3579 100644
--- a/pc-bios/s390-ccw/bootmap.h
+++ b/pc-bios/s390-ccw/bootmap.h
@@ -15,7 +15,7 @@
#include "virtio.h"
typedef uint64_t block_number_t;
-#define NULL_BLOCK_NR 0xffffffffffffffff
+#define NULL_BLOCK_NR 0xffffffffffffffffULL
#define FREE_SPACE_FILLER '\xAA'
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index f9ec2157ad..6f707bbcd4 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -13,7 +13,7 @@
char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
uint64_t boot_value;
-struct subchannel_id blk_schid = { .one = 1 };
+static struct subchannel_id blk_schid = { .one = 1 };
/*
* Priniciples of Operations (SA22-7832-09) chapter 17 requires that
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 2b773deafa..ceb7418a50 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -51,6 +51,8 @@ void disabled_wait(void);
/* main.c */
void virtio_panic(const char *string);
void write_subsystem_identification(void);
+extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
+extern uint64_t boot_value;
/* sclp-ascii.c */
void sclp_print(const char *string);
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index c0540d1cd4..4dc91a7c43 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -11,7 +11,7 @@
#include "s390-ccw.h"
#include "virtio.h"
-struct vring block;
+static struct vring block;
static char chsc_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index dcd75055c1..6f2d5b4924 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -1046,7 +1046,7 @@ static void kvm_handle_diag_308(S390CPU *cpu, struct kvm_run *run)
uint64_t r1, r3;
cpu_synchronize_state(CPU(cpu));
- r1 = (run->s390_sieic.ipa & 0x00f0) >> 8;
+ r1 = (run->s390_sieic.ipa & 0x00f0) >> 4;
r3 = run->s390_sieic.ipa & 0x000f;
handle_diag_308(&cpu->env, r1, r3);
}
@@ -1091,7 +1091,7 @@ static int handle_diag(S390CPU *cpu, struct kvm_run *run, uint32_t ipb)
break;
default:
DPRINTF("KVM: unknown DIAG: 0x%x\n", func_code);
- r = -1;
+ enter_pgmcheck(cpu, PGM_SPECIFICATION);
break;
}