mirror of https://gitee.com/openkylin/qemu.git
target-arm queue:
* various MAINTAINERS file updates * hw/block/onenand: use qemu_log_mask() for reporting * hw/block/onenand: Fix off-by-one error allowing out-of-bounds read on the n800 and n810 machine models * target/arm: fix smc incorrectly trapping to EL3 when secure is off * hw/arm/stm32f205: Fix the UART and Timer region size * target/arm: read ID registers for KVM guests so they can be used to gate "is feature X present" checks -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJb8t08AAoJEDwlJe0UNgzecFIP/Are0UdNt9Tr0K1OCE4XjFCn HtupNyE/woN4IOa1lQrCig8C2xvL6BHqPerf/NZc3z4NXUDpzr3/dJvb66aw3ilB GZhMRFoaFaPgD9uKojLO9ym09WjNjfb3/5J7CacPJaQCwwqXHUiuV6kZDVP3wM2m SBWBblNadNx+uU9LFpBmO+Dk2MShh1nt2ujVRqHVo1/AUZvyZZZrBuXvqM3ykdGx eboNBSN6TuyaFwOcofZbN+UsS0Eu8XlRvBwEFaIH9UcKR8nfj7l4HLBDTMSfi1ms KFp2mZjFGOuDcUnyshl2MmfZG76mmKTac2O2WFZ7ESMp8N21YksEe9y6hrhLuzYS CoUc1evzo8q9cmxNlnWCyWL2UYJKM+hPxUICg5IktDtqNmMuNJvhWgHN3j++Gahd KWWJQCC1xIVxfLFyfB6B/VcFTLybLGPHe3S4F4VYhmFJAnR3kq/2MlhHwmIqeAfh l9NaSHp+pTAILE2OQLnCmVBsUHBYQxz7QV5jSK8Pd9m0v2zlipIv9CAaXPpA8oV4 O5erkaw+qjErX9v30ASbtKt5yyUOHbZwK/imo6SDi6jz9W92sCgHFC/P2UdcSUmO ai00NfS3zG3NxYP4GK7Km1PD8WrxCDl7N+oEgjGYbyZJIQFokakNVgM1/uSnVi2N mFXg3ArAtH8IrW8OAJSH =t7Fy -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20181119' into staging target-arm queue: * various MAINTAINERS file updates * hw/block/onenand: use qemu_log_mask() for reporting * hw/block/onenand: Fix off-by-one error allowing out-of-bounds read on the n800 and n810 machine models * target/arm: fix smc incorrectly trapping to EL3 when secure is off * hw/arm/stm32f205: Fix the UART and Timer region size * target/arm: read ID registers for KVM guests so they can be used to gate "is feature X present" checks # gpg: Signature made Mon 19 Nov 2018 15:56:44 GMT # gpg: using RSA key 3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20181119: MAINTAINERS: list myself as maintainer for various Arm boards hw/block/onenand: use qemu_log_mask() for reporting hw/block/onenand: Fix off-by-one error allowing out-of-bounds read target/arm: fix smc incorrectly trapping to EL3 when secure is off hw/arm/stm32f205: Fix the UART and Timer region size MAINTAINERS: Add entries for missing ARM boards target/arm: Fill in ARMISARegisters for kvm32 target/arm: Introduce read_sys_reg32 for kvm32 target/arm: Fill in ARMISARegisters for kvm64 target/arm: Install ARMISARegisters from kvm host Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
d304cf014b
106
MAINTAINERS
106
MAINTAINERS
|
@ -442,8 +442,9 @@ ARM Machines
|
|||
------------
|
||||
Allwinner-a10
|
||||
M: Beniamino Galvani <b.galvani@gmail.com>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: hw/*/allwinner*
|
||||
F: include/hw/*/allwinner*
|
||||
F: hw/arm/cubieboard.c
|
||||
|
@ -502,40 +503,46 @@ F: tests/test-arm-mptimer.c
|
|||
|
||||
Exynos
|
||||
M: Igor Mitsyanko <i.mitsyanko@gmail.com>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: hw/*/exynos*
|
||||
F: include/hw/arm/exynos4210.h
|
||||
|
||||
Calxeda Highbank
|
||||
M: Rob Herring <robh@kernel.org>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: hw/arm/highbank.c
|
||||
F: hw/net/xgmac.c
|
||||
|
||||
Canon DIGIC
|
||||
M: Antony Pavlov <antonynpavlov@gmail.com>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: include/hw/arm/digic.h
|
||||
F: hw/*/digic*
|
||||
|
||||
Gumstix
|
||||
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
L: qemu-devel@nongnu.org
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: hw/arm/gumstix.c
|
||||
|
||||
i.MX31
|
||||
i.MX31 (kzm)
|
||||
M: Peter Chubb <peter.chubb@nicta.com.au>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Odd fixes
|
||||
F: hw/*/imx*
|
||||
F: include/hw/*/imx*
|
||||
S: Odd Fixes
|
||||
F: hw/arm/kzm.c
|
||||
F: include/hw/arm/fsl-imx31.h
|
||||
F: hw/*/imx_*
|
||||
F: hw/*/*imx31*
|
||||
F: include/hw/*/imx_*
|
||||
F: include/hw/*/*imx31*
|
||||
|
||||
Integrator CP
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
|
@ -544,6 +551,28 @@ S: Maintained
|
|||
F: hw/arm/integratorcp.c
|
||||
F: hw/misc/arm_integrator_debug.c
|
||||
|
||||
MCIMX6UL EVK / i.MX6ul
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
R: Jean-Christophe Dubois <jcd@tribudubois.net>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: hw/arm/mcimx6ul-evk.c
|
||||
F: hw/arm/fsl-imx6ul.c
|
||||
F: hw/misc/imx6ul_ccm.c
|
||||
F: include/hw/arm/fsl-imx6ul.h
|
||||
F: include/hw/misc/imx6ul_ccm.h
|
||||
|
||||
MCIMX7D SABRE / i.MX7
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
R: Andrey Smirnov <andrew.smirnov@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: hw/arm/mcimx7d-sabre.c
|
||||
F: hw/arm/fsl-imx7.c
|
||||
F: include/hw/arm/fsl-imx7.h
|
||||
F: hw/pci-host/designware.c
|
||||
F: include/hw/pci-host/designware.h
|
||||
|
||||
MPS2
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
|
@ -561,22 +590,36 @@ F: include/hw/misc/iotkit-sysinfo.h
|
|||
|
||||
Musicpal
|
||||
M: Jan Kiszka <jan.kiszka@web.de>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: hw/arm/musicpal.c
|
||||
|
||||
nSeries
|
||||
M: Andrzej Zaborowski <balrogg@gmail.com>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: hw/arm/nseries.c
|
||||
|
||||
Palm
|
||||
M: Andrzej Zaborowski <balrogg@gmail.com>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: hw/arm/palm.c
|
||||
|
||||
Raspberry Pi
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
R: Andrew Baumann <Andrew.Baumann@microsoft.com>
|
||||
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: hw/arm/raspi_platform.h
|
||||
F: hw/*/bcm283*
|
||||
F: include/hw/arm/raspi*
|
||||
F: include/hw/*/bcm283*
|
||||
|
||||
Real View
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
|
@ -588,8 +631,9 @@ F: include/hw/intc/realview_gic.h
|
|||
|
||||
PXA2XX
|
||||
M: Andrzej Zaborowski <balrogg@gmail.com>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: hw/arm/mainstone.c
|
||||
F: hw/arm/spitz.c
|
||||
F: hw/arm/tosa.c
|
||||
|
@ -598,6 +642,19 @@ F: hw/*/pxa2xx*
|
|||
F: hw/misc/mst_fpga.c
|
||||
F: include/hw/arm/pxa.h
|
||||
|
||||
SABRELITE / i.MX6
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
R: Jean-Christophe Dubois <jcd@tribudubois.net>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: hw/arm/sabrelite.c
|
||||
F: hw/arm/fsl-imx6.c
|
||||
F: hw/misc/imx6_src.c
|
||||
F: hw/ssi/imx_spi.c
|
||||
F: include/hw/arm/fsl-imx6.h
|
||||
F: include/hw/misc/imx6_src.h
|
||||
F: include/hw/ssi/imx_spi.h
|
||||
|
||||
Sharp SL-5500 (Collie) PDA
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
|
@ -611,6 +668,12 @@ L: qemu-arm@nongnu.org
|
|||
S: Maintained
|
||||
F: hw/*/stellaris*
|
||||
|
||||
Versatile Express
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/vexpress.c
|
||||
|
||||
Versatile PB
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
|
@ -618,9 +681,17 @@ S: Maintained
|
|||
F: hw/*/versatile*
|
||||
F: hw/misc/arm_sysctl.c
|
||||
|
||||
Virt
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/virt*
|
||||
F: include/hw/arm/virt.h
|
||||
|
||||
Xilinx Zynq
|
||||
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
M: Alistair Francis <alistair@alistair23.me>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/*/xilinx_*
|
||||
|
@ -632,6 +703,7 @@ X: hw/ssi/xilinx_*
|
|||
Xilinx ZynqMP
|
||||
M: Alistair Francis <alistair@alistair23.me>
|
||||
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/*/xlnx*.c
|
||||
|
@ -645,6 +717,7 @@ F: hw/arm/virt-acpi-build.c
|
|||
|
||||
STM32F205
|
||||
M: Alistair Francis <alistair@alistair23.me>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
S: Maintained
|
||||
F: hw/arm/stm32f205_soc.c
|
||||
F: hw/misc/stm32f2xx_syscfg.c
|
||||
|
@ -656,11 +729,13 @@ F: include/hw/*/stm32*.h
|
|||
|
||||
Netduino 2
|
||||
M: Alistair Francis <alistair@alistair23.me>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
S: Maintained
|
||||
F: hw/arm/netduino2.c
|
||||
|
||||
SmartFusion2
|
||||
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
S: Maintained
|
||||
F: hw/arm/msf2-soc.c
|
||||
F: hw/misc/msf2-sysreg.c
|
||||
|
@ -673,11 +748,13 @@ F: include/hw/ssi/mss-spi.h
|
|||
|
||||
Emcraft M2S-FG484
|
||||
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
S: Maintained
|
||||
F: hw/arm/msf2-som.c
|
||||
|
||||
ASPEED BMCs
|
||||
M: Cédric Le Goater <clg@kaod.org>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
R: Andrew Jeffery <andrew@aj.id.au>
|
||||
R: Joel Stanley <joel@jms.id.au>
|
||||
L: qemu-arm@nongnu.org
|
||||
|
@ -689,6 +766,7 @@ F: include/hw/net/ftgmac100.h
|
|||
|
||||
NRF51
|
||||
M: Joel Stanley <joel@jms.id.au>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/nrf51_soc.c
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "exec/memory.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/log.h"
|
||||
|
||||
/* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
|
||||
#define PAGE_SHIFT 11
|
||||
|
@ -594,8 +595,8 @@ static void onenand_command(OneNANDState *s)
|
|||
default:
|
||||
s->status |= ONEN_ERR_CMD;
|
||||
s->intstatus |= ONEN_INT;
|
||||
fprintf(stderr, "%s: unknown OneNAND command %x\n",
|
||||
__func__, s->command);
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "unknown OneNAND command %x\n",
|
||||
s->command);
|
||||
}
|
||||
|
||||
onenand_intr_update(s);
|
||||
|
@ -608,7 +609,7 @@ static uint64_t onenand_read(void *opaque, hwaddr addr,
|
|||
int offset = addr >> s->shift;
|
||||
|
||||
switch (offset) {
|
||||
case 0x0000 ... 0xc000:
|
||||
case 0x0000 ... 0xbffe:
|
||||
return lduw_le_p(s->boot[0] + addr);
|
||||
|
||||
case 0xf000: /* Manufacturer ID */
|
||||
|
@ -657,12 +658,13 @@ static uint64_t onenand_read(void *opaque, hwaddr addr,
|
|||
case 0xff02: /* ECC Result of spare area data */
|
||||
case 0xff03: /* ECC Result of main area data */
|
||||
case 0xff04: /* ECC Result of spare area data */
|
||||
hw_error("%s: implement ECC\n", __func__);
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"onenand: ECC result registers unimplemented\n");
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: unknown OneNAND register %x\n",
|
||||
__func__, offset);
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "read of unknown OneNAND register 0x%x\n",
|
||||
offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -706,8 +708,9 @@ static void onenand_write(void *opaque, hwaddr addr,
|
|||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: unknown OneNAND boot command %"PRIx64"\n",
|
||||
__func__, value);
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"unknown OneNAND boot command %" PRIx64 "\n",
|
||||
value);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -757,8 +760,9 @@ static void onenand_write(void *opaque, hwaddr addr,
|
|||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: unknown OneNAND register %x\n",
|
||||
__func__, offset);
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"write to unknown OneNAND register 0x%x\n",
|
||||
offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ static void stm32f2xx_usart_init(Object *obj)
|
|||
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
|
||||
|
||||
memory_region_init_io(&s->mmio, obj, &stm32f2xx_usart_ops, s,
|
||||
TYPE_STM32F2XX_USART, 0x2000);
|
||||
TYPE_STM32F2XX_USART, 0x400);
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
|
||||
}
|
||||
|
||||
|
|
|
@ -308,7 +308,7 @@ static void stm32f2xx_timer_init(Object *obj)
|
|||
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
|
||||
|
||||
memory_region_init_io(&s->iomem, obj, &stm32f2xx_timer_ops, s,
|
||||
"stm32f2xx_timer", 0x4000);
|
||||
"stm32f2xx_timer", 0x400);
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
|
||||
|
||||
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, stm32f2xx_timer_interrupt, s);
|
||||
|
|
|
@ -158,6 +158,7 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
|
|||
|
||||
cpu->kvm_target = arm_host_cpu_features.target;
|
||||
cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;
|
||||
cpu->isar = arm_host_cpu_features.isar;
|
||||
env->features = arm_host_cpu_features.features;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,14 @@ static inline void set_feature(uint64_t *features, int feature)
|
|||
*features |= 1ULL << feature;
|
||||
}
|
||||
|
||||
static int read_sys_reg32(int fd, uint32_t *pret, uint64_t id)
|
||||
{
|
||||
struct kvm_one_reg idreg = { .id = id, .addr = (uintptr_t)pret };
|
||||
|
||||
assert((id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32);
|
||||
return ioctl(fd, KVM_GET_ONE_REG, &idreg);
|
||||
}
|
||||
|
||||
bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||
{
|
||||
/* Identify the feature bits corresponding to the host CPU, and
|
||||
|
@ -35,9 +43,10 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
|||
* we have to create a scratch VM, create a single CPU inside it,
|
||||
* and then query that CPU for the relevant ID registers.
|
||||
*/
|
||||
int i, ret, fdarray[3];
|
||||
uint32_t midr, id_pfr0, mvfr1;
|
||||
int err = 0, fdarray[3];
|
||||
uint32_t midr, id_pfr0;
|
||||
uint64_t features = 0;
|
||||
|
||||
/* Old kernels may not know about the PREFERRED_TARGET ioctl: however
|
||||
* we know these will only support creating one kind of guest CPU,
|
||||
* which is its preferred CPU type.
|
||||
|
@ -47,23 +56,6 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
|||
QEMU_KVM_ARM_TARGET_NONE
|
||||
};
|
||||
struct kvm_vcpu_init init;
|
||||
struct kvm_one_reg idregs[] = {
|
||||
{
|
||||
.id = KVM_REG_ARM | KVM_REG_SIZE_U32
|
||||
| ENCODE_CP_REG(15, 0, 0, 0, 0, 0, 0),
|
||||
.addr = (uintptr_t)&midr,
|
||||
},
|
||||
{
|
||||
.id = KVM_REG_ARM | KVM_REG_SIZE_U32
|
||||
| ENCODE_CP_REG(15, 0, 0, 0, 1, 0, 0),
|
||||
.addr = (uintptr_t)&id_pfr0,
|
||||
},
|
||||
{
|
||||
.id = KVM_REG_ARM | KVM_REG_SIZE_U32
|
||||
| KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR1,
|
||||
.addr = (uintptr_t)&mvfr1,
|
||||
},
|
||||
};
|
||||
|
||||
if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
|
||||
return false;
|
||||
|
@ -77,16 +69,45 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
|||
*/
|
||||
ahcf->dtb_compatible = "arm,arm-v7";
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(idregs); i++) {
|
||||
ret = ioctl(fdarray[2], KVM_GET_ONE_REG, &idregs[i]);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
err |= read_sys_reg32(fdarray[2], &midr, ARM_CP15_REG32(0, 0, 0, 0));
|
||||
err |= read_sys_reg32(fdarray[2], &id_pfr0, ARM_CP15_REG32(0, 0, 1, 0));
|
||||
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0,
|
||||
ARM_CP15_REG32(0, 0, 2, 0));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1,
|
||||
ARM_CP15_REG32(0, 0, 2, 1));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar2,
|
||||
ARM_CP15_REG32(0, 0, 2, 2));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar3,
|
||||
ARM_CP15_REG32(0, 0, 2, 3));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar4,
|
||||
ARM_CP15_REG32(0, 0, 2, 4));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5,
|
||||
ARM_CP15_REG32(0, 0, 2, 5));
|
||||
if (read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6,
|
||||
ARM_CP15_REG32(0, 0, 2, 7))) {
|
||||
/*
|
||||
* Older kernels don't support reading ID_ISAR6. This register was
|
||||
* only introduced in ARMv8, so we can assume that it is zero on a
|
||||
* CPU that a kernel this old is running on.
|
||||
*/
|
||||
ahcf->isar.id_isar6 = 0;
|
||||
}
|
||||
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0,
|
||||
KVM_REG_ARM | KVM_REG_SIZE_U32 |
|
||||
KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR0);
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr1,
|
||||
KVM_REG_ARM | KVM_REG_SIZE_U32 |
|
||||
KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR1);
|
||||
/*
|
||||
* FIXME: There is not yet a way to read MVFR2.
|
||||
* Fortunately there is not yet anything in there that affects migration.
|
||||
*/
|
||||
|
||||
kvm_arm_destroy_scratch_host_vcpu(fdarray);
|
||||
|
||||
if (ret) {
|
||||
if (err < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -104,13 +125,13 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
|||
if (extract32(id_pfr0, 12, 4) == 1) {
|
||||
set_feature(&features, ARM_FEATURE_THUMB2EE);
|
||||
}
|
||||
if (extract32(mvfr1, 20, 4) == 1) {
|
||||
if (extract32(ahcf->isar.mvfr1, 20, 4) == 1) {
|
||||
set_feature(&features, ARM_FEATURE_VFP_FP16);
|
||||
}
|
||||
if (extract32(mvfr1, 12, 4) == 1) {
|
||||
if (extract32(ahcf->isar.mvfr1, 12, 4) == 1) {
|
||||
set_feature(&features, ARM_FEATURE_NEON);
|
||||
}
|
||||
if (extract32(mvfr1, 28, 4) == 1) {
|
||||
if (extract32(ahcf->isar.mvfr1, 28, 4) == 1) {
|
||||
/* FMAC support implies VFPv4 */
|
||||
set_feature(&features, ARM_FEATURE_VFP4);
|
||||
}
|
||||
|
|
|
@ -456,17 +456,40 @@ static inline void unset_feature(uint64_t *features, int feature)
|
|||
*features &= ~(1ULL << feature);
|
||||
}
|
||||
|
||||
static int read_sys_reg32(int fd, uint32_t *pret, uint64_t id)
|
||||
{
|
||||
uint64_t ret;
|
||||
struct kvm_one_reg idreg = { .id = id, .addr = (uintptr_t)&ret };
|
||||
int err;
|
||||
|
||||
assert((id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64);
|
||||
err = ioctl(fd, KVM_GET_ONE_REG, &idreg);
|
||||
if (err < 0) {
|
||||
return -1;
|
||||
}
|
||||
*pret = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_sys_reg64(int fd, uint64_t *pret, uint64_t id)
|
||||
{
|
||||
struct kvm_one_reg idreg = { .id = id, .addr = (uintptr_t)pret };
|
||||
|
||||
assert((id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64);
|
||||
return ioctl(fd, KVM_GET_ONE_REG, &idreg);
|
||||
}
|
||||
|
||||
bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||
{
|
||||
/* Identify the feature bits corresponding to the host CPU, and
|
||||
* fill out the ARMHostCPUClass fields accordingly. To do this
|
||||
* we have to create a scratch VM, create a single CPU inside it,
|
||||
* and then query that CPU for the relevant ID registers.
|
||||
* For AArch64 we currently don't care about ID registers at
|
||||
* all; we just want to know the CPU type.
|
||||
*/
|
||||
int fdarray[3];
|
||||
uint64_t features = 0;
|
||||
int err;
|
||||
|
||||
/* Old kernels may not know about the PREFERRED_TARGET ioctl: however
|
||||
* we know these will only support creating one kind of guest CPU,
|
||||
* which is its preferred CPU type. Fortunately these old kernels
|
||||
|
@ -487,8 +510,71 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
|||
ahcf->target = init.target;
|
||||
ahcf->dtb_compatible = "arm,arm-v8";
|
||||
|
||||
err = read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr0,
|
||||
ARM64_SYS_REG(3, 0, 0, 4, 0));
|
||||
if (unlikely(err < 0)) {
|
||||
/*
|
||||
* Before v4.15, the kernel only exposed a limited number of system
|
||||
* registers, not including any of the interesting AArch64 ID regs.
|
||||
* For the most part we could leave these fields as zero with minimal
|
||||
* effect, since this does not affect the values seen by the guest.
|
||||
*
|
||||
* However, it could cause problems down the line for QEMU,
|
||||
* so provide a minimal v8.0 default.
|
||||
*
|
||||
* ??? Could read MIDR and use knowledge from cpu64.c.
|
||||
* ??? Could map a page of memory into our temp guest and
|
||||
* run the tiniest of hand-crafted kernels to extract
|
||||
* the values seen by the guest.
|
||||
* ??? Either of these sounds like too much effort just
|
||||
* to work around running a modern host kernel.
|
||||
*/
|
||||
ahcf->isar.id_aa64pfr0 = 0x00000011; /* EL1&0, AArch64 only */
|
||||
err = 0;
|
||||
} else {
|
||||
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr1,
|
||||
ARM64_SYS_REG(3, 0, 0, 4, 1));
|
||||
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar0,
|
||||
ARM64_SYS_REG(3, 0, 0, 6, 0));
|
||||
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1,
|
||||
ARM64_SYS_REG(3, 0, 0, 6, 1));
|
||||
|
||||
/*
|
||||
* Note that if AArch32 support is not present in the host,
|
||||
* the AArch32 sysregs are present to be read, but will
|
||||
* return UNKNOWN values. This is neither better nor worse
|
||||
* than skipping the reads and leaving 0, as we must avoid
|
||||
* considering the values in every case.
|
||||
*/
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0,
|
||||
ARM64_SYS_REG(3, 0, 0, 2, 0));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1,
|
||||
ARM64_SYS_REG(3, 0, 0, 2, 1));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar2,
|
||||
ARM64_SYS_REG(3, 0, 0, 2, 2));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar3,
|
||||
ARM64_SYS_REG(3, 0, 0, 2, 3));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar4,
|
||||
ARM64_SYS_REG(3, 0, 0, 2, 4));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5,
|
||||
ARM64_SYS_REG(3, 0, 0, 2, 5));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6,
|
||||
ARM64_SYS_REG(3, 0, 0, 2, 7));
|
||||
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0,
|
||||
ARM64_SYS_REG(3, 0, 0, 3, 0));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr1,
|
||||
ARM64_SYS_REG(3, 0, 0, 3, 1));
|
||||
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2,
|
||||
ARM64_SYS_REG(3, 0, 0, 3, 2));
|
||||
}
|
||||
|
||||
kvm_arm_destroy_scratch_host_vcpu(fdarray);
|
||||
|
||||
if (err < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We can assume any KVM supporting CPU is at least a v8
|
||||
* with VFPv4+Neon; this in turn implies most of the other
|
||||
* feature bits.
|
||||
|
|
|
@ -183,6 +183,7 @@ void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
|
|||
* by asking the host kernel)
|
||||
*/
|
||||
typedef struct ARMHostCPUFeatures {
|
||||
ARMISARegisters isar;
|
||||
uint64_t features;
|
||||
uint32_t target;
|
||||
const char *dtb_compatible;
|
||||
|
|
|
@ -939,7 +939,38 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
|
|||
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||
int cur_el = arm_current_el(env);
|
||||
bool secure = arm_is_secure(env);
|
||||
bool smd = env->cp15.scr_el3 & SCR_SMD;
|
||||
bool smd_flag = env->cp15.scr_el3 & SCR_SMD;
|
||||
|
||||
/*
|
||||
* SMC behaviour is summarized in the following table.
|
||||
* This helper handles the "Trap to EL2" and "Undef insn" cases.
|
||||
* The "Trap to EL3" and "PSCI call" cases are handled in the exception
|
||||
* helper.
|
||||
*
|
||||
* -> ARM_FEATURE_EL3 and !SMD
|
||||
* HCR_TSC && NS EL1 !HCR_TSC || !NS EL1
|
||||
*
|
||||
* Conduit SMC, valid call Trap to EL2 PSCI Call
|
||||
* Conduit SMC, inval call Trap to EL2 Trap to EL3
|
||||
* Conduit not SMC Trap to EL2 Trap to EL3
|
||||
*
|
||||
*
|
||||
* -> ARM_FEATURE_EL3 and SMD
|
||||
* HCR_TSC && NS EL1 !HCR_TSC || !NS EL1
|
||||
*
|
||||
* Conduit SMC, valid call Trap to EL2 PSCI Call
|
||||
* Conduit SMC, inval call Trap to EL2 Undef insn
|
||||
* Conduit not SMC Trap to EL2 Undef insn
|
||||
*
|
||||
*
|
||||
* -> !ARM_FEATURE_EL3
|
||||
* HCR_TSC && NS EL1 !HCR_TSC || !NS EL1
|
||||
*
|
||||
* Conduit SMC, valid call Trap to EL2 PSCI Call
|
||||
* Conduit SMC, inval call Trap to EL2 Undef insn
|
||||
* Conduit not SMC Undef insn Undef insn
|
||||
*/
|
||||
|
||||
/* On ARMv8 with EL3 AArch64, SMD applies to both S and NS state.
|
||||
* On ARMv8 with EL3 AArch32, or ARMv7 with the Virtualization
|
||||
* extensions, SMD only applies to NS state.
|
||||
|
@ -947,7 +978,8 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
|
|||
* doesn't exist, but we forbid the guest to set it to 1 in scr_write(),
|
||||
* so we need not special case this here.
|
||||
*/
|
||||
bool undef = arm_feature(env, ARM_FEATURE_AARCH64) ? smd : smd && !secure;
|
||||
bool smd = arm_feature(env, ARM_FEATURE_AARCH64) ? smd_flag
|
||||
: smd_flag && !secure;
|
||||
|
||||
if (!arm_feature(env, ARM_FEATURE_EL3) &&
|
||||
cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
|
||||
|
@ -957,21 +989,27 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
|
|||
* to forbid its EL1 from making PSCI calls into QEMU's
|
||||
* "firmware" via HCR.TSC, so for these purposes treat
|
||||
* PSCI-via-SMC as implying an EL3.
|
||||
* This handles the very last line of the previous table.
|
||||
*/
|
||||
undef = true;
|
||||
} else if (!secure && cur_el == 1 && (env->cp15.hcr_el2 & HCR_TSC)) {
|
||||
raise_exception(env, EXCP_UDEF, syn_uncategorized(),
|
||||
exception_target_el(env));
|
||||
}
|
||||
|
||||
if (!secure && cur_el == 1 && (env->cp15.hcr_el2 & HCR_TSC)) {
|
||||
/* In NS EL1, HCR controlled routing to EL2 has priority over SMD.
|
||||
* We also want an EL2 guest to be able to forbid its EL1 from
|
||||
* making PSCI calls into QEMU's "firmware" via HCR.TSC.
|
||||
* This handles all the "Trap to EL2" cases of the previous table.
|
||||
*/
|
||||
raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
|
||||
}
|
||||
|
||||
/* If PSCI is enabled and this looks like a valid PSCI call then
|
||||
* suppress the UNDEF -- we'll catch the SMC exception and
|
||||
* implement the PSCI call behaviour there.
|
||||
/* Catch the two remaining "Undef insn" cases of the previous table:
|
||||
* - PSCI conduit is SMC but we don't have a valid PCSI call,
|
||||
* - We don't have EL3 or SMD is set.
|
||||
*/
|
||||
if (undef && !arm_is_psci_call(cpu, EXCP_SMC)) {
|
||||
if (!arm_is_psci_call(cpu, EXCP_SMC) &&
|
||||
(smd || !arm_feature(env, ARM_FEATURE_EL3))) {
|
||||
raise_exception(env, EXCP_UDEF, syn_uncategorized(),
|
||||
exception_target_el(env));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue