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:
Peter Maydell 2018-11-19 15:58:17 +00:00
commit d304cf014b
9 changed files with 293 additions and 64 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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.

View File

@ -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;

View File

@ -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));
}