target-arm queue:

* Fix vd == vm overlap in sve_ldff1_z
  * Add support for MTE with KVM guests
  * Add RAZ/WI handling for DBGDTR[TX|RX]
  * Start of conversion of A64 decoder to decodetree
  * Saturate L2CTLR_EL1 core count field rather than overflowing
  * vexpress: Avoid trivial memory leak of 'flashalias'
  * sbsa-ref: switch default cpu core to Neoverse-N1
  * sbsa-ref: use Bochs graphics card instead of VGA
  * MAINTAINERS: Add Marcin Juszkiewicz to sbsa-ref reviewer list
  * docs: Convert u2f.txt to rST
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmRmHvMZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3vqqEACFEcWq3E2gRjwnz8JAEk/0
 jYuYg9jUG6Ev6xY5x31+M4DfK78eXgHYtCxhEcT6FSwpFg/ZXC+bPlZcRlM+8692
 gkp+JJeBA4VRy9e7Uk6GvRWnpGzjnkHTHf4E9PZB8iIvbJY9nFTtMZydn1w0EnMW
 HsetnNLIxrtJaETwUa5mDWh0Bt4t6ZIEB2bJSr3O0fy7uiJ8xvpRMYxqfxvI0h+0
 7xSaG7xb5Dy4LxohMK0CLdj1wy+8uWpYgD6ZneJ2hlqjknvNWa3zdR8bRLNT0aZL
 8ubR1ioFvfi+uA26SNVrdRrGEhqMrTxD0XstFutz0zlOjn0wjo1Ny/ojmGYWuvcU
 aG09UvcecMP8hy+ygTXJ+2D04eH1VGmS1GEwRS3p+fdODsgHy0Ctln8IPK8SuG7q
 67BG/F4GNdkbktHGbZlwduxh30furH8pSSlIJOeTq7d20+atqZ94MWaoW1iQ+t4B
 9gDi3MsKoUKVNEhJPorHlDxvtlQppr0ziL0IVPeYUNJONlSza88hkx34ScA5Rl7+
 5vQYjLkhS1qZQqvd1fNSRNtHeGx2uBeE9eZF/ZCp7bA5rxcRn//LmG7hO7Octuii
 zIVaOektXeShALdJ7dMt4MZh0z1RjVVLf0ouC1HHCg9rlzvB+0I5AhXYacGkmCqW
 wf9S0hvNqdGmJRQhNRonGg==
 =ooCi
 -----END PGP SIGNATURE-----

Merge tag 'pull-target-arm-20230518' of https://git.linaro.org/people/pmaydell/qemu-arm into staging

target-arm queue:
 * Fix vd == vm overlap in sve_ldff1_z
 * Add support for MTE with KVM guests
 * Add RAZ/WI handling for DBGDTR[TX|RX]
 * Start of conversion of A64 decoder to decodetree
 * Saturate L2CTLR_EL1 core count field rather than overflowing
 * vexpress: Avoid trivial memory leak of 'flashalias'
 * sbsa-ref: switch default cpu core to Neoverse-N1
 * sbsa-ref: use Bochs graphics card instead of VGA
 * MAINTAINERS: Add Marcin Juszkiewicz to sbsa-ref reviewer list
 * docs: Convert u2f.txt to rST

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmRmHvMZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3vqqEACFEcWq3E2gRjwnz8JAEk/0
# jYuYg9jUG6Ev6xY5x31+M4DfK78eXgHYtCxhEcT6FSwpFg/ZXC+bPlZcRlM+8692
# gkp+JJeBA4VRy9e7Uk6GvRWnpGzjnkHTHf4E9PZB8iIvbJY9nFTtMZydn1w0EnMW
# HsetnNLIxrtJaETwUa5mDWh0Bt4t6ZIEB2bJSr3O0fy7uiJ8xvpRMYxqfxvI0h+0
# 7xSaG7xb5Dy4LxohMK0CLdj1wy+8uWpYgD6ZneJ2hlqjknvNWa3zdR8bRLNT0aZL
# 8ubR1ioFvfi+uA26SNVrdRrGEhqMrTxD0XstFutz0zlOjn0wjo1Ny/ojmGYWuvcU
# aG09UvcecMP8hy+ygTXJ+2D04eH1VGmS1GEwRS3p+fdODsgHy0Ctln8IPK8SuG7q
# 67BG/F4GNdkbktHGbZlwduxh30furH8pSSlIJOeTq7d20+atqZ94MWaoW1iQ+t4B
# 9gDi3MsKoUKVNEhJPorHlDxvtlQppr0ziL0IVPeYUNJONlSza88hkx34ScA5Rl7+
# 5vQYjLkhS1qZQqvd1fNSRNtHeGx2uBeE9eZF/ZCp7bA5rxcRn//LmG7hO7Octuii
# zIVaOektXeShALdJ7dMt4MZh0z1RjVVLf0ouC1HHCg9rlzvB+0I5AhXYacGkmCqW
# wf9S0hvNqdGmJRQhNRonGg==
# =ooCi
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 18 May 2023 05:49:55 AM PDT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full]

* tag 'pull-target-arm-20230518' of https://git.linaro.org/people/pmaydell/qemu-arm: (29 commits)
  docs: Convert u2f.txt to rST
  hw/arm/vexpress: Avoid trivial memory leak of 'flashalias'
  target/arm: Saturate L2CTLR_EL1 core count field rather than overflowing
  target/arm: Convert ERET, ERETAA, ERETAB to decodetree
  target/arm: Convert BRAA, BRAB, BLRAA, BLRAB to decodetree
  target/arm: Convert BRA[AB]Z, BLR[AB]Z, RETA[AB] to decodetree
  target/arm: Convert BR, BLR, RET to decodetree
  target/arm: Convert conditional branch insns to decodetree
  target/arm: Convert TBZ, TBNZ to decodetree
  target/arm: Convert CBZ, CBNZ to decodetree
  target/arm: Convert unconditional branch immediate to decodetree
  target/arm: Convert Extract instructions to decodetree
  target/arm: Convert Bitfield to decodetree
  target/arm: Convert Move wide (immediate) to decodetree
  target/arm: Convert Logical (immediate) to decodetree
  target/arm: Replace bitmask64 with MAKE_64BIT_MASK
  target/arm: Convert Add/subtract (immediate with tags) to decodetree
  target/arm: Convert Add/subtract (immediate) to decodetree
  target/arm: Split gen_add_CC and gen_sub_CC
  target/arm: Convert PC-rel addressing to decodetree
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-05-18 06:08:30 -07:00
commit 266ccbb27b
20 changed files with 979 additions and 924 deletions

View File

@ -940,6 +940,7 @@ SBSA-REF
M: Radoslaw Biernacki <rad@semihalf.com>
M: Peter Maydell <peter.maydell@linaro.org>
R: Leif Lindholm <quic_llindhol@quicinc.com>
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
L: qemu-arm@nongnu.org
S: Maintained
F: hw/arm/sbsa-ref.c

View File

@ -93,4 +93,5 @@ Emulated Devices
devices/virtio-pmem.rst
devices/vhost-user-rng.rst
devices/canokey.rst
devices/usb-u2f.rst
devices/igb.rst

View File

@ -0,0 +1,93 @@
Universal Second Factor (U2F) USB Key Device
============================================
U2F is an open authentication standard that enables relying parties
exposed to the internet to offer a strong second factor option for end
user authentication.
The second factor is provided by a device implementing the U2F
protocol. In case of a USB U2F security key, it is a USB HID device
that implements the U2F protocol.
QEMU supports both pass-through of a host U2F key device to a VM,
and software emulation of a U2F key.
``u2f-passthru``
----------------
The ``u2f-passthru`` device allows you to connect a real hardware
U2F key on your host to a guest VM. All requests made from the guest
are passed through to the physical security key connected to the
host machine and vice versa.
In addition, the dedicated pass-through allows you to share a single
U2F security key with several guest VMs, which is not possible with a
simple host device assignment pass-through.
You can specify the host U2F key to use with the ``hidraw``
option, which takes the host path to a Linux ``/dev/hidrawN`` device:
.. parsed-literal::
|qemu_system| -usb -device u2f-passthru,hidraw=/dev/hidraw0
If you don't specify the device, the ``u2f-passthru`` device will
autoscan to take the first U2F device it finds on the host (this
requires a working libudev):
.. parsed-literal::
|qemu_system| -usb -device u2f-passthru
``u2f-emulated``
----------------
``u2f-emulated`` is a completely software emulated U2F device.
It uses `libu2f-emu <https://github.com/MattGorko/libu2f-emu>`__
for the U2F key emulation. libu2f-emu
provides a complete implementation of the U2F protocol device part for
all specified transports given by the FIDO Alliance.
To work, an emulated U2F device must have four elements:
* ec x509 certificate
* ec private key
* counter (four bytes value)
* 48 bytes of entropy (random bits)
To use this type of device, these have to be configured, and these
four elements must be passed one way or another.
Assuming that you have a working libu2f-emu installed on the host,
there are three possible ways to configure the ``u2f-emulated`` device:
* ephemeral
* setup directory
* manual
Ephemeral is the simplest way to configure; it lets the device generate
all the elements it needs for a single use of the lifetime of the device.
It is the default if you do not pass any other options to the device.
.. parsed-literal::
|qemu_system| -usb -device u2f-emulated
You can pass the device the path of a setup directory on the host
using the ``dir`` option; the directory must contain these four files:
* ``certificate.pem``: ec x509 certificate
* ``private-key.pem``: ec private key
* ``counter``: counter value
* ``entropy``: 48 bytes of entropy
.. parsed-literal::
|qemu_system| -usb -device u2f-emulated,dir=$dir
You can also manually pass the device the paths to each of these files,
if you don't want them all to be in the same directory, using the options
* ``cert``
* ``priv``
* ``counter``
* ``entropy``
.. parsed-literal::
|qemu_system| -usb -device u2f-emulated,cert=$DIR1/$FILE1,priv=$DIR2/$FILE2,counter=$DIR3/$FILE3,entropy=$DIR4/$FILE4

View File

@ -207,7 +207,7 @@ option or the ``device_add`` monitor command. Available devices are:
USB audio device
``u2f-{emulated,passthru}``
Universal Second Factor device
:doc:`usb-u2f`
``canokey``
An Open-source Secure Key implementing FIDO2, OpenPGP, PIV and more.

View File

@ -1,110 +0,0 @@
QEMU U2F Key Device Documentation.
Contents
1. USB U2F key device
2. Building
3. Using u2f-emulated
4. Using u2f-passthru
5. Libu2f-emu
1. USB U2F key device
U2F is an open authentication standard that enables relying parties
exposed to the internet to offer a strong second factor option for end
user authentication.
The standard brings many advantages to both parties, client and server,
allowing to reduce over-reliance on passwords, it increases authentication
security and simplifies passwords.
The second factor is materialized by a device implementing the U2F
protocol. In case of a USB U2F security key, it is a USB HID device
that implements the U2F protocol.
In QEMU, the USB U2F key device offers a dedicated support of U2F, allowing
guest USB FIDO/U2F security keys operating in two possible modes:
pass-through and emulated.
The pass-through mode consists of passing all requests made from the guest
to the physical security key connected to the host machine and vice versa.
In addition, the dedicated pass-through allows to have a U2F security key
shared on several guests which is not possible with a simple host device
assignment pass-through.
The emulated mode consists of completely emulating the behavior of an
U2F device through software part. Libu2f-emu is used for that.
2. Building
To ensure the build of the u2f-emulated device variant which depends
on libu2f-emu: configuring and building:
./configure --enable-u2f && make
The pass-through mode is built by default on Linux. To take advantage
of the autoscan option it provides, make sure you have a working libudev
installed on the host.
3. Using u2f-emulated
To work, an emulated U2F device must have four elements:
* ec x509 certificate
* ec private key
* counter (four bytes value)
* 48 bytes of entropy (random bits)
To use this type of device, this one has to be configured, and these
four elements must be passed one way or another.
Assuming that you have a working libu2f-emu installed on the host.
There are three possible ways of configurations:
* ephemeral
* setup directory
* manual
Ephemeral is the simplest way to configure, it lets the device generate
all the elements it needs for a single use of the lifetime of the device.
qemu -usb -device u2f-emulated
Setup directory allows to configure the device from a directory containing
four files:
* certificate.pem: ec x509 certificate
* private-key.pem: ec private key
* counter: counter value
* entropy: 48 bytes of entropy
qemu -usb -device u2f-emulated,dir=$dir
Manual allows to configure the device more finely by specifying each
of the elements necessary for the device:
* cert
* priv
* counter
* entropy
qemu -usb -device u2f-emulated,cert=$DIR1/$FILE1,priv=$DIR2/$FILE2,counter=$DIR3/$FILE3,entropy=$DIR4/$FILE4
4. Using u2f-passthru
On the host specify the u2f-passthru device with a suitable hidraw:
qemu -usb -device u2f-passthru,hidraw=/dev/hidraw0
Alternately, the u2f-passthru device can autoscan to take the first
U2F device it finds on the host (this requires a working libudev):
qemu -usb -device u2f-passthru
5. Libu2f-emu
The u2f-emulated device uses libu2f-emu for the U2F key emulation. Libu2f-emu
implements completely the U2F protocol device part for all specified
transport given by the FIDO Alliance.
For more information about libu2f-emu see this page:
https://github.com/MattGorko/libu2f-emu.

View File

@ -648,7 +648,7 @@ static void create_pcie(SBSAMachineState *sms)
}
}
pci_create_simple(pci->bus, -1, "VGA");
pci_create_simple(pci->bus, -1, "bochs-display");
create_smmu(sms, pci->bus);
}
@ -852,7 +852,7 @@ static void sbsa_ref_class_init(ObjectClass *oc, void *data)
mc->init = sbsa_ref_init;
mc->desc = "QEMU 'SBSA Reference' ARM Virtual Machine";
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57");
mc->default_cpu_type = ARM_CPU_TYPE_NAME("neoverse-n1");
mc->max_cpus = 512;
mc->pci_allow_0_address = true;
mc->minimum_page_bits = 12;

View File

@ -173,6 +173,11 @@ struct VexpressMachineClass {
struct VexpressMachineState {
MachineState parent;
MemoryRegion vram;
MemoryRegion sram;
MemoryRegion flashalias;
MemoryRegion lowram;
MemoryRegion a15sram;
bool secure;
bool virt;
};
@ -182,7 +187,7 @@ struct VexpressMachineState {
#define TYPE_VEXPRESS_A15_MACHINE MACHINE_TYPE_NAME("vexpress-a15")
OBJECT_DECLARE_TYPE(VexpressMachineState, VexpressMachineClass, VEXPRESS_MACHINE)
typedef void DBoardInitFn(const VexpressMachineState *machine,
typedef void DBoardInitFn(VexpressMachineState *machine,
ram_addr_t ram_size,
const char *cpu_type,
qemu_irq *pic);
@ -263,14 +268,13 @@ static void init_cpus(MachineState *ms, const char *cpu_type,
}
}
static void a9_daughterboard_init(const VexpressMachineState *vms,
static void a9_daughterboard_init(VexpressMachineState *vms,
ram_addr_t ram_size,
const char *cpu_type,
qemu_irq *pic)
{
MachineState *machine = MACHINE(vms);
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *lowram = g_new(MemoryRegion, 1);
ram_addr_t low_ram_size;
if (ram_size > 0x40000000) {
@ -287,9 +291,9 @@ static void a9_daughterboard_init(const VexpressMachineState *vms,
* address space should in theory be remappable to various
* things including ROM or RAM; we always map the RAM there.
*/
memory_region_init_alias(lowram, NULL, "vexpress.lowmem", machine->ram,
0, low_ram_size);
memory_region_add_subregion(sysmem, 0x0, lowram);
memory_region_init_alias(&vms->lowram, NULL, "vexpress.lowmem",
machine->ram, 0, low_ram_size);
memory_region_add_subregion(sysmem, 0x0, &vms->lowram);
memory_region_add_subregion(sysmem, 0x60000000, machine->ram);
/* 0x1e000000 A9MPCore (SCU) private memory region */
@ -348,14 +352,13 @@ static VEDBoardInfo a9_daughterboard = {
.init = a9_daughterboard_init,
};
static void a15_daughterboard_init(const VexpressMachineState *vms,
static void a15_daughterboard_init(VexpressMachineState *vms,
ram_addr_t ram_size,
const char *cpu_type,
qemu_irq *pic)
{
MachineState *machine = MACHINE(vms);
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *sram = g_new(MemoryRegion, 1);
{
/* We have to use a separate 64 bit variable here to avoid the gcc
@ -386,9 +389,9 @@ static void a15_daughterboard_init(const VexpressMachineState *vms,
/* 0x2b060000: SP805 watchdog: not modelled */
/* 0x2b0a0000: PL341 dynamic memory controller: not modelled */
/* 0x2e000000: system SRAM */
memory_region_init_ram(sram, NULL, "vexpress.a15sram", 0x10000,
memory_region_init_ram(&vms->a15sram, NULL, "vexpress.a15sram", 0x10000,
&error_fatal);
memory_region_add_subregion(sysmem, 0x2e000000, sram);
memory_region_add_subregion(sysmem, 0x2e000000, &vms->a15sram);
/* 0x7ffb0000: DMA330 DMA controller: not modelled */
/* 0x7ffd0000: PL354 static memory controller: not modelled */
@ -547,10 +550,6 @@ static void vexpress_common_init(MachineState *machine)
I2CBus *i2c;
ram_addr_t vram_size, sram_size;
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *vram = g_new(MemoryRegion, 1);
MemoryRegion *sram = g_new(MemoryRegion, 1);
MemoryRegion *flashalias = g_new(MemoryRegion, 1);
MemoryRegion *flash0mem;
const hwaddr *map = daughterboard->motherboard_map;
int i;
@ -662,24 +661,25 @@ static void vexpress_common_init(MachineState *machine)
if (map[VE_NORFLASHALIAS] != -1) {
/* Map flash 0 as an alias into low memory */
MemoryRegion *flash0mem;
flash0mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pflash0), 0);
memory_region_init_alias(flashalias, NULL, "vexpress.flashalias",
memory_region_init_alias(&vms->flashalias, NULL, "vexpress.flashalias",
flash0mem, 0, VEXPRESS_FLASH_SIZE);
memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias);
memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], &vms->flashalias);
}
dinfo = drive_get(IF_PFLASH, 0, 1);
ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1", dinfo);
sram_size = 0x2000000;
memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size,
memory_region_init_ram(&vms->sram, NULL, "vexpress.sram", sram_size,
&error_fatal);
memory_region_add_subregion(sysmem, map[VE_SRAM], sram);
memory_region_add_subregion(sysmem, map[VE_SRAM], &vms->sram);
vram_size = 0x800000;
memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size,
memory_region_init_ram(&vms->vram, NULL, "vexpress.vram", vram_size,
&error_fatal);
memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram);
memory_region_add_subregion(sysmem, map[VE_VIDEORAM], &vms->vram);
/* 0x4e000000 LAN9118 Ethernet */
if (nd_table[0].used) {

View File

@ -2146,7 +2146,7 @@ static void machvirt_init(MachineState *machine)
exit(1);
}
if (vms->mte && (kvm_enabled() || hvf_enabled())) {
if (vms->mte && hvf_enabled()) {
error_report("mach-virt: %s does not support providing "
"MTE to the guest CPU",
current_accel_name());
@ -2216,39 +2216,48 @@ static void machvirt_init(MachineState *machine)
}
if (vms->mte) {
/* Create the memory region only once, but link to all cpus. */
if (!tag_sysmem) {
/*
* The property exists only if MemTag is supported.
* If it is, we must allocate the ram to back that up.
*/
if (!object_property_find(cpuobj, "tag-memory")) {
error_report("MTE requested, but not supported "
"by the guest CPU");
if (tcg_enabled()) {
/* Create the memory region only once, but link to all cpus. */
if (!tag_sysmem) {
/*
* The property exists only if MemTag is supported.
* If it is, we must allocate the ram to back that up.
*/
if (!object_property_find(cpuobj, "tag-memory")) {
error_report("MTE requested, but not supported "
"by the guest CPU");
exit(1);
}
tag_sysmem = g_new(MemoryRegion, 1);
memory_region_init(tag_sysmem, OBJECT(machine),
"tag-memory", UINT64_MAX / 32);
if (vms->secure) {
secure_tag_sysmem = g_new(MemoryRegion, 1);
memory_region_init(secure_tag_sysmem, OBJECT(machine),
"secure-tag-memory",
UINT64_MAX / 32);
/* As with ram, secure-tag takes precedence over tag. */
memory_region_add_subregion_overlap(secure_tag_sysmem,
0, tag_sysmem, -1);
}
}
object_property_set_link(cpuobj, "tag-memory",
OBJECT(tag_sysmem), &error_abort);
if (vms->secure) {
object_property_set_link(cpuobj, "secure-tag-memory",
OBJECT(secure_tag_sysmem),
&error_abort);
}
} else if (kvm_enabled()) {
if (!kvm_arm_mte_supported()) {
error_report("MTE requested, but not supported by KVM");
exit(1);
}
tag_sysmem = g_new(MemoryRegion, 1);
memory_region_init(tag_sysmem, OBJECT(machine),
"tag-memory", UINT64_MAX / 32);
if (vms->secure) {
secure_tag_sysmem = g_new(MemoryRegion, 1);
memory_region_init(secure_tag_sysmem, OBJECT(machine),
"secure-tag-memory", UINT64_MAX / 32);
/* As with ram, secure-tag takes precedence over tag. */
memory_region_add_subregion_overlap(secure_tag_sysmem, 0,
tag_sysmem, -1);
}
}
object_property_set_link(cpuobj, "tag-memory", OBJECT(tag_sysmem),
&error_abort);
if (vms->secure) {
object_property_set_link(cpuobj, "secure-tag-memory",
OBJECT(secure_tag_sysmem),
&error_abort);
kvm_arm_enable_mte(cpuobj, &error_abort);
}
}

View File

@ -15,8 +15,15 @@ static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
ARMCPU *cpu = env_archcpu(env);
/* Number of cores is in [25:24]; otherwise we RAZ */
return (cpu->core_count - 1) << 24;
/*
* Number of cores is in [25:24]; otherwise we RAZ.
* If the board didn't configure the CPUs into clusters,
* we default to "all CPUs in one cluster", which might be
* more than the 4 that the hardware permits and which is
* all you can report in this two-bit field. Saturate to
* 0b11 (== 4 CPUs) rather than overflowing the field.
*/
return MIN(cpu->core_count - 1, 3) << 24;
}
static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {

View File

@ -1480,6 +1480,7 @@ void arm_cpu_post_init(Object *obj)
qdev_prop_allow_set_link_before_realize,
OBJ_PROP_LINK_STRONG);
}
cpu->has_mte = true;
}
#endif
}
@ -1616,7 +1617,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
}
if (cpu->tag_memory) {
error_setg(errp,
"Cannot enable %s when guest CPUs has MTE enabled",
"Cannot enable %s when guest CPUs has tag memory enabled",
current_accel_name());
return;
}
@ -1996,10 +1997,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
}
#ifndef CONFIG_USER_ONLY
if (cpu->tag_memory == NULL && cpu_isar_feature(aa64_mte, cpu)) {
if (!cpu->has_mte && cpu_isar_feature(aa64_mte, cpu)) {
/*
* Disable the MTE feature bits if we do not have tag-memory
* provided by the machine.
* Disable the MTE feature bits if we do not have the feature
* setup by the machine.
*/
cpu->isar.id_aa64pfr1 =
FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0);

View File

@ -935,6 +935,9 @@ struct ArchCPU {
*/
uint32_t psci_conduit;
/* CPU has Memory Tag Extension */
bool has_mte;
/* For v8M, initial value of the Secure VTOR */
uint32_t init_svtor;
/* For v8M, initial value of the Non-secure VTOR */
@ -1053,6 +1056,7 @@ struct ArchCPU {
bool prop_pauth;
bool prop_pauth_impdef;
bool prop_lpa2;
OnOffAuto prop_mte;
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
uint32_t dcz_blocksize;

View File

@ -949,8 +949,10 @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
.access = PL0_R, .accessfn = access_tdcc,
.type = ARM_CP_CONST, .resetvalue = 0 },
/*
* OSDTRRX_EL1/OSDTRTX_EL1 are used for save and restore of DBGDTRRX_EL0.
* It is a component of the Debug Communications Channel, which is not implemented.
* These registers belong to the Debug Communications Channel,
* which is not implemented. However we implement RAZ/WI behaviour
* with trapping to prevent spurious SIGILLs if the guest OS does
* access them as the support cannot be probed for.
*/
{ .name = "OSDTRRX_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 2,
@ -960,6 +962,11 @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
.access = PL1_RW, .accessfn = access_tdcc,
.type = ARM_CP_CONST, .resetvalue = 0 },
/* DBGDTRTX_EL0/DBGDTRRX_EL0 depend on direction */
{ .name = "DBGDTR_EL0", .state = ARM_CP_STATE_BOTH, .cp = 14,
.opc0 = 2, .opc1 = 3, .crn = 0, .crm = 5, .opc2 = 0,
.access = PL0_RW, .accessfn = access_tdcc,
.type = ARM_CP_CONST, .resetvalue = 0 },
/*
* OSECCR_EL1 provides a mechanism for an operating system
* to access the contents of EDECCR. EDECCR is not implemented though,

View File

@ -31,6 +31,7 @@
#include "hw/boards.h"
#include "hw/irq.h"
#include "qemu/log.h"
#include "migration/blocker.h"
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
@ -1064,3 +1065,37 @@ bool kvm_arch_cpu_check_are_resettable(void)
void kvm_arch_accel_class_init(ObjectClass *oc)
{
}
void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
{
static bool tried_to_enable;
static bool succeeded_to_enable;
Error *mte_migration_blocker = NULL;
int ret;
if (!tried_to_enable) {
/*
* MTE on KVM is enabled on a per-VM basis (and retrying doesn't make
* sense), and we only want a single migration blocker as well.
*/
tried_to_enable = true;
ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_MTE, 0);
if (ret) {
error_setg_errno(errp, -ret, "Failed to enable KVM_CAP_ARM_MTE");
return;
}
/* TODO: add proper migration support with MTE enabled */
error_setg(&mte_migration_blocker,
"Live migration disabled due to MTE enabled");
if (migrate_add_blocker(mte_migration_blocker, errp)) {
error_free(mte_migration_blocker);
return;
}
succeeded_to_enable = true;
}
if (succeeded_to_enable) {
object_property_set_bool(cpuobj, "has_mte", true, NULL);
}
}

View File

@ -756,6 +756,11 @@ bool kvm_arm_steal_time_supported(void)
return kvm_check_extension(kvm_state, KVM_CAP_STEAL_TIME);
}
bool kvm_arm_mte_supported(void)
{
return kvm_check_extension(kvm_state, KVM_CAP_ARM_MTE);
}
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
uint32_t kvm_arm_sve_get_vls(CPUState *cs)

View File

@ -313,6 +313,13 @@ bool kvm_arm_pmu_supported(void);
*/
bool kvm_arm_sve_supported(void);
/**
* kvm_arm_mte_supported:
*
* Returns: true if KVM can enable MTE, and false otherwise.
*/
bool kvm_arm_mte_supported(void);
/**
* kvm_arm_get_max_vm_ipa_size:
* @ms: Machine state handle
@ -377,6 +384,8 @@ void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa);
int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
void kvm_arm_enable_mte(Object *cpuobj, Error **errp);
#else
/*
@ -403,6 +412,11 @@ static inline bool kvm_arm_steal_time_supported(void)
return false;
}
static inline bool kvm_arm_mte_supported(void)
{
return false;
}
/*
* These functions should never actually be called without KVM support.
*/
@ -451,6 +465,11 @@ static inline uint32_t kvm_arm_sve_get_vls(CPUState *cs)
g_assert_not_reached();
}
static inline void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
{
g_assert_not_reached();
}
#endif
static inline const char *gic_class_name(void)

152
target/arm/tcg/a64.decode Normal file
View File

@ -0,0 +1,152 @@
# AArch64 A64 allowed instruction decoding
#
# Copyright (c) 2023 Linaro, Ltd
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, see <http://www.gnu.org/licenses/>.
#
# This file is processed by scripts/decodetree.py
#
&r rn
&ri rd imm
&rri_sf rd rn imm sf
&i imm
### Data Processing - Immediate
# PC-rel addressing
%imm_pcrel 5:s19 29:2
@pcrel . .. ..... ................... rd:5 &ri imm=%imm_pcrel
ADR 0 .. 10000 ................... ..... @pcrel
ADRP 1 .. 10000 ................... ..... @pcrel
# Add/subtract (immediate)
%imm12_sh12 10:12 !function=shl_12
@addsub_imm sf:1 .. ...... . imm:12 rn:5 rd:5
@addsub_imm12 sf:1 .. ...... . ............ rn:5 rd:5 imm=%imm12_sh12
ADD_i . 00 100010 0 ............ ..... ..... @addsub_imm
ADD_i . 00 100010 1 ............ ..... ..... @addsub_imm12
ADDS_i . 01 100010 0 ............ ..... ..... @addsub_imm
ADDS_i . 01 100010 1 ............ ..... ..... @addsub_imm12
SUB_i . 10 100010 0 ............ ..... ..... @addsub_imm
SUB_i . 10 100010 1 ............ ..... ..... @addsub_imm12
SUBS_i . 11 100010 0 ............ ..... ..... @addsub_imm
SUBS_i . 11 100010 1 ............ ..... ..... @addsub_imm12
# Add/subtract (immediate with tags)
&rri_tag rd rn uimm6 uimm4
@addsub_imm_tag . .. ...... . uimm6:6 .. uimm4:4 rn:5 rd:5 &rri_tag
ADDG_i 1 00 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
SUBG_i 1 10 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
# Logical (immediate)
&rri_log rd rn sf dbm
@logic_imm_64 1 .. ...... dbm:13 rn:5 rd:5 &rri_log sf=1
@logic_imm_32 0 .. ...... 0 dbm:12 rn:5 rd:5 &rri_log sf=0
AND_i . 00 100100 . ...... ...... ..... ..... @logic_imm_64
AND_i . 00 100100 . ...... ...... ..... ..... @logic_imm_32
ORR_i . 01 100100 . ...... ...... ..... ..... @logic_imm_64
ORR_i . 01 100100 . ...... ...... ..... ..... @logic_imm_32
EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_64
EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_32
ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_64
ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_32
# Move wide (immediate)
&movw rd sf imm hw
@movw_64 1 .. ...... hw:2 imm:16 rd:5 &movw sf=1
@movw_32 0 .. ...... 0 hw:1 imm:16 rd:5 &movw sf=0
MOVN . 00 100101 .. ................ ..... @movw_64
MOVN . 00 100101 .. ................ ..... @movw_32
MOVZ . 10 100101 .. ................ ..... @movw_64
MOVZ . 10 100101 .. ................ ..... @movw_32
MOVK . 11 100101 .. ................ ..... @movw_64
MOVK . 11 100101 .. ................ ..... @movw_32
# Bitfield
&bitfield rd rn sf immr imms
@bitfield_64 1 .. ...... 1 immr:6 imms:6 rn:5 rd:5 &bitfield sf=1
@bitfield_32 0 .. ...... 0 0 immr:5 0 imms:5 rn:5 rd:5 &bitfield sf=0
SBFM . 00 100110 . ...... ...... ..... ..... @bitfield_64
SBFM . 00 100110 . ...... ...... ..... ..... @bitfield_32
BFM . 01 100110 . ...... ...... ..... ..... @bitfield_64
BFM . 01 100110 . ...... ...... ..... ..... @bitfield_32
UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_64
UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_32
# Extract
&extract rd rn rm imm sf
EXTR 1 00 100111 1 0 rm:5 imm:6 rn:5 rd:5 &extract sf=1
EXTR 0 00 100111 0 0 rm:5 0 imm:5 rn:5 rd:5 &extract sf=0
# Branches
%imm26 0:s26 !function=times_4
@branch . ..... .......................... &i imm=%imm26
B 0 00101 .......................... @branch
BL 1 00101 .......................... @branch
%imm19 5:s19 !function=times_4
&cbz rt imm sf nz
CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
%imm14 5:s14 !function=times_4
%imm31_19 31:1 19:5
&tbz rt imm nz bitpos
TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=%imm31_19
B_cond 0101010 0 ................... 0 cond:4 imm=%imm19
BR 1101011 0000 11111 000000 rn:5 00000 &r
BLR 1101011 0001 11111 000000 rn:5 00000 &r
RET 1101011 0010 11111 000000 rn:5 00000 &r
&braz rn m
BRAZ 1101011 0000 11111 00001 m:1 rn:5 11111 &braz # BRAAZ, BRABZ
BLRAZ 1101011 0001 11111 00001 m:1 rn:5 11111 &braz # BLRAAZ, BLRABZ
&reta m
RETA 1101011 0010 11111 00001 m:1 11111 11111 &reta # RETAA, RETAB
&bra rn rm m
BRA 1101011 1000 11111 00001 m:1 rn:5 rm:5 &bra # BRAA, BRAB
BLRA 1101011 1001 11111 00001 m:1 rn:5 rm:5 &bra # BLRAA, BLRAB
ERET 1101011 0100 11111 000000 11111 00000
ERETA 1101011 0100 11111 00001 m:1 11111 11111 &reta # ERETAA, ERETAB
# We don't need to decode DRPS because it always UNDEFs except when
# the processor is in halting debug state (which we don't implement).
# The pattern is listed here as documentation.
# DRPS 1101011 0101 11111 000000 11111 00000

View File

@ -13,6 +13,7 @@ gen = [
decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
decodetree.process('t32.decode', extra_args: '--static-decode=disas_t32'),
decodetree.process('t16.decode', extra_args: ['-w', '16', '--static-decode=disas_t16']),
decodetree.process('a64.decode', extra_args: ['--static-decode=disas_a64']),
]
arm_ss.add(gen)

View File

@ -6727,6 +6727,7 @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
intptr_t reg_off;
SVEHostPage info;
target_ulong addr, in_page;
ARMVectorReg scratch;
/* Skip to the first true predicate. */
reg_off = find_next_active(vg, 0, reg_max, esz);
@ -6736,6 +6737,11 @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
return;
}
/* Protect against overlap between vd and vm. */
if (unlikely(vd == vm)) {
vm = memcpy(&scratch, vm, reg_max);
}
/*
* Probe the first element, allowing faults.
*/

File diff suppressed because it is too large Load Diff

View File

@ -220,6 +220,11 @@ static inline int rsub_8(DisasContext *s, int x)
return 8 - x;
}
static inline int shl_12(DisasContext *s, int x)
{
return x << 12;
}
static inline int neon_3same_fp_size(DisasContext *s, int x)
{
/* Convert 0==fp32, 1==fp16 into a MO_* value */