1
target-arm queue: Eric's SMMUv3 patchset, and an array
1
The following changes since commit b7c359c748a2e3ccb97a184b9739feb2cd48de2f:
2
of minor bugfixes and improvements from various others.
3
2
4
thanks
3
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.0-pull-request' into staging (2020-01-23 14:38:43 +0000)
5
-- PMM
6
7
The following changes since commit c8b7e627b4269a3bc3ae41d9f420547a47e6d9b9:
8
9
Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-05-04' into staging (2018-05-04 14:42:46 +0100)
10
4
11
are available in the Git repository at:
5
are available in the Git repository at:
12
6
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180504
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200123
14
8
15
for you to fetch changes up to 5680740c92993e9b3f3e011f2a2c394070e33f56:
9
for you to fetch changes up to 53c75ad8e72dc3a5102de7ed21e4990969cb0a19:
16
10
17
hw/arm/virt: Introduce the iommu option (2018-05-04 18:05:52 +0100)
11
hw/arm/exynos4210: Connect serial port DMA busy signals with pl330 (2020-01-23 15:22:42 +0000)
18
12
19
----------------------------------------------------------------
13
----------------------------------------------------------------
20
target-arm queue:
14
target-arm queue:
21
* Emulate the SMMUv3 (IOMMU); one will be created in the 'virt' board
15
* fix bug in PAuth emulation
22
if the commandline includes "-machine iommu=smmuv3"
16
* add PMU to Cortex-R5, Cortex-R5F
23
* target/arm: Implement v8M VLLDM and VLSTM
17
* qemu-nbd: Convert documentation to rST
24
* hw/arm: Don't fail qtest due to missing SD card in -nodefaults mode
18
* qemu-block-drivers: Convert documentation to rST
25
* Some fixes to silence Coverity false-positives
19
* Fix Exynos4210 UART DMA support
26
* arm: boot: set boot_info starting from first_cpu
20
* Various minor code cleanups
27
(fixes a technical bug not visible in practice)
28
* hw/net/smc91c111: Convert away from old_mmio
29
* hw/usb/tusb6010: Convert away from old_mmio
30
* hw/char/cmsdk-apb-uart.c: Accept more input after character read
31
* target/arm: Make MPUIR write-ignored on OMAP, StrongARM
32
* hw/arm/virt: Add linux,pci-domain property
33
21
34
----------------------------------------------------------------
22
----------------------------------------------------------------
35
Eric Auger (11):
23
Andrew Jones (1):
36
hw/arm/smmu-common: smmu base device and datatypes
24
target/arm/arch_dump: Add SVE notes
37
hw/arm/smmu-common: IOMMU memory region and address space setup
38
hw/arm/smmu-common: VMSAv8-64 page table walk
39
hw/arm/smmuv3: Wired IRQ and GERROR helpers
40
hw/arm/smmuv3: Queue helpers
41
hw/arm/smmuv3: Implement MMIO write operations
42
hw/arm/smmuv3: Event queue recording helper
43
hw/arm/smmuv3: Implement translate callback
44
hw/arm/smmuv3: Abort on vfio or vhost case
45
target/arm/kvm: Translate the MSI doorbell in kvm_arch_fixup_msi_route
46
hw/arm/virt: Introduce the iommu option
47
25
48
Igor Mammedov (1):
26
Clement Deschamps (1):
49
arm: boot: set boot_info starting from first_cpu
27
target/arm: add PMU feature to cortex-r5 and cortex-r5f
50
28
51
Jan Kiszka (1):
29
Guenter Roeck (8):
52
hw/arm/virt: Add linux,pci-domain property
30
dma/pl330: Convert to support tracing
31
hw/core/or-irq: Increase limit of or-lines to 48
32
hw/arm/exynos4210: Fix DMA initialization
33
hw/char/exynos4210_uart: Convert to support tracing
34
hw/char/exynos4210_uart: Implement post_load function
35
hw/char/exynos4210_uart: Implement Rx FIFO level triggers and timeouts
36
hw/char/exynos4210_uart: Add receive DMA support
37
hw/arm/exynos4210: Connect serial port DMA busy signals with pl330
53
38
54
Mathew Maidment (1):
39
Keqian Zhu (2):
55
target/arm: Correct MPUIR privilege level in register_cp_regs_for_features() conditional case
40
hw/acpi: Remove extra indent in ACPI GED hotplug cb
56
41
hw/arm: Use helper function to trigger hotplug handler plug
57
Patrick Oppenlander (1):
58
hw/char/cmsdk-apb-uart.c: Accept more input after character read
59
42
60
Peter Maydell (3):
43
Peter Maydell (3):
61
hw/usb/tusb6010: Convert away from old_mmio
44
qemu-nbd: Convert invocation documentation to rST
62
hw/net/smc91c111: Convert away from old_mmio
45
docs: Create stub system manual
63
target/arm: Implement v8M VLLDM and VLSTM
46
qemu-block-drivers: Convert to rST
64
47
65
Prem Mallappa (3):
48
Philippe Mathieu-Daudé (1):
66
hw/arm/smmuv3: Skeleton
49
hw/misc/stm32f4xx_syscfg: Fix copy/paste error
67
hw/arm/virt: Add SMMUv3 to the virt board
68
hw/arm/virt-acpi-build: Add smmuv3 node in IORT table
69
50
70
Richard Henderson (2):
51
Richard Henderson (3):
71
target/arm: Tidy conditions in handle_vec_simd_shri
52
tests/tcg/aarch64: Fix compilation parameters for pauth-%
72
target/arm: Tidy condition in disas_simd_two_reg_misc
53
tests/tcg/aarch64: Add pauth-3
54
tests/tcg/aarch64: Add pauth-4
73
55
74
Thomas Huth (1):
56
Vincent Dehors (1):
75
hw/arm: Don't fail qtest due to missing SD card in -nodefaults mode
57
target/arm: Fix PAuth sbox functions
76
58
77
hw/arm/Makefile.objs | 1 +
59
Makefile | 37 +-
78
hw/arm/smmu-internal.h | 99 +++
60
tests/tcg/aarch64/Makefile.softmmu-target | 5 +-
79
hw/arm/smmuv3-internal.h | 621 ++++++++++++++++++
61
tests/tcg/aarch64/Makefile.target | 3 +-
80
include/hw/acpi/acpi-defs.h | 15 +
62
include/elf.h | 1 +
81
include/hw/arm/smmu-common.h | 145 +++++
63
include/hw/arm/exynos4210.h | 4 +
82
include/hw/arm/smmuv3.h | 87 +++
64
include/hw/or-irq.h | 2 +-
83
include/hw/arm/virt.h | 10 +
65
target/arm/cpu.h | 25 +
84
hw/arm/boot.c | 2 +-
66
hw/acpi/generic_event_device.c | 2 +-
85
hw/arm/omap1.c | 8 +-
67
hw/arm/exynos4210.c | 77 ++-
86
hw/arm/omap2.c | 8 +-
68
hw/arm/virt.c | 6 +-
87
hw/arm/pxa2xx.c | 15 +-
69
hw/char/exynos4210_uart.c | 245 +++++---
88
hw/arm/smmu-common.c | 372 +++++++++++
70
hw/dma/pl330.c | 88 +--
89
hw/arm/smmuv3.c | 1191 +++++++++++++++++++++++++++++++++++
71
hw/misc/stm32f4xx_syscfg.c | 2 +-
90
hw/arm/virt-acpi-build.c | 55 +-
72
target/arm/arch_dump.c | 124 +++-
91
hw/arm/virt.c | 101 ++-
73
target/arm/cpu.c | 1 +
92
hw/char/cmsdk-apb-uart.c | 1 +
74
target/arm/kvm64.c | 24 -
93
hw/net/smc91c111.c | 54 +-
75
target/arm/pauth_helper.c | 4 +-
94
hw/usb/tusb6010.c | 40 +-
76
tests/tcg/aarch64/pauth-1.c | 2 -
95
target/arm/helper.c | 2 +-
77
tests/tcg/aarch64/pauth-2.c | 2 -
96
target/arm/kvm.c | 38 +-
78
tests/tcg/aarch64/pauth-4.c | 25 +
97
target/arm/translate-a64.c | 12 +-
79
tests/tcg/aarch64/system/pauth-3.c | 40 ++
98
target/arm/translate.c | 17 +-
80
MAINTAINERS | 1 +
99
default-configs/aarch64-softmmu.mak | 1 +
81
docs/index.html.in | 1 +
100
hw/arm/trace-events | 37 ++
82
docs/interop/conf.py | 4 +-
101
target/arm/trace-events | 3 +
83
docs/interop/index.rst | 1 +
102
25 files changed, 2868 insertions(+), 67 deletions(-)
84
docs/interop/qemu-nbd.rst | 263 ++++++++
103
create mode 100644 hw/arm/smmu-internal.h
85
docs/interop/qemu-option-trace.rst.inc | 30 +
104
create mode 100644 hw/arm/smmuv3-internal.h
86
docs/qemu-block-drivers.texi | 889 ---------------------------
105
create mode 100644 include/hw/arm/smmu-common.h
87
docs/system/conf.py | 22 +
106
create mode 100644 include/hw/arm/smmuv3.h
88
docs/system/index.rst | 17 +
107
create mode 100644 hw/arm/smmu-common.c
89
docs/system/qemu-block-drivers.rst | 985 ++++++++++++++++++++++++++++++
108
create mode 100644 hw/arm/smmuv3.c
90
hw/char/trace-events | 20 +
91
hw/dma/trace-events | 24 +
92
qemu-doc.texi | 18 -
93
qemu-nbd.texi | 214 -------
94
qemu-option-trace.texi | 4 +
95
qemu-options.hx | 2 +-
96
37 files changed, 1897 insertions(+), 1317 deletions(-)
97
create mode 100644 tests/tcg/aarch64/pauth-4.c
98
create mode 100644 tests/tcg/aarch64/system/pauth-3.c
99
create mode 100644 docs/interop/qemu-nbd.rst
100
create mode 100644 docs/interop/qemu-option-trace.rst.inc
101
delete mode 100644 docs/qemu-block-drivers.texi
102
create mode 100644 docs/system/conf.py
103
create mode 100644 docs/system/index.rst
104
create mode 100644 docs/system/qemu-block-drivers.rst
105
delete mode 100644 qemu-nbd.texi
109
106
diff view generated by jsdifflib
1
From: Patrick Oppenlander <patrick.oppenlander@gmail.com>
1
From: Clement Deschamps <clement.deschamps@greensocs.com>
2
2
3
The character frontend needs to be notified that the uart receive buffer
3
The PMU is not optional on cortex-r5 and cortex-r5f (see
4
is empty and ready to handle another character.
4
the "Features" chapter of the Technical Reference Manual).
5
5
6
Previously, the uart only worked correctly when receiving one character
6
Signed-off-by: Clement Deschamps <clement.deschamps@greensocs.com>
7
at a time.
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
8
Message-id: 20200114105918.2366370-1-clement.deschamps@greensocs.com
9
Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
10
Message-id: CAEg67GkRTw=cXei3o9hvpxG_L4zSrNzR0bFyAgny+sSEUb_kPw@mail.gmail.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
hw/char/cmsdk-apb-uart.c | 1 +
11
target/arm/cpu.c | 1 +
15
1 file changed, 1 insertion(+)
12
1 file changed, 1 insertion(+)
16
13
17
diff --git a/hw/char/cmsdk-apb-uart.c b/hw/char/cmsdk-apb-uart.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/char/cmsdk-apb-uart.c
16
--- a/target/arm/cpu.c
20
+++ b/hw/char/cmsdk-apb-uart.c
17
+++ b/target/arm/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static uint64_t uart_read(void *opaque, hwaddr offset, unsigned size)
18
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
22
r = s->rxbuf;
19
set_feature(&cpu->env, ARM_FEATURE_V7);
23
s->state &= ~R_STATE_RXFULL_MASK;
20
set_feature(&cpu->env, ARM_FEATURE_V7MP);
24
cmsdk_apb_uart_update(s);
21
set_feature(&cpu->env, ARM_FEATURE_PMSA);
25
+ qemu_chr_fe_accept_input(&s->chr);
22
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
26
break;
23
cpu->midr = 0x411fc153; /* r1p3 */
27
case A_STATE:
24
cpu->id_pfr0 = 0x0131;
28
r = s->state;
25
cpu->id_pfr1 = 0x001;
29
--
26
--
30
2.17.0
27
2.20.1
31
28
32
29
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Vincent Dehors <vincent.dehors@smile.fr>
2
2
3
In case the MSI is translated by an IOMMU we need to fixup the
3
In the PAC computation, sbox was applied over wrong bits.
4
MSI route with the translated address.
4
As this is a 4-bit sbox, bit index should be incremented by 4 instead of 16.
5
5
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
Test vector from QARMA paper (https://eprint.iacr.org/2016/444.pdf) was
7
Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
7
used to verify one computation of the pauth_computepac() function which
8
Message-id: 1524665762-31355-12-git-send-email-eric.auger@redhat.com
8
uses sbox2.
9
10
Launchpad: https://bugs.launchpad.net/bugs/1859713
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Vincent DEHORS <vincent.dehors@smile.fr>
13
Signed-off-by: Adrien GRASSEIN <adrien.grassein@smile.fr>
14
Message-id: 20200116230809.19078-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
17
---
12
target/arm/kvm.c | 38 +++++++++++++++++++++++++++++++++++++-
18
target/arm/pauth_helper.c | 4 ++--
13
target/arm/trace-events | 3 +++
19
1 file changed, 2 insertions(+), 2 deletions(-)
14
2 files changed, 40 insertions(+), 1 deletion(-)
15
20
16
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
21
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/kvm.c
23
--- a/target/arm/pauth_helper.c
19
+++ b/target/arm/kvm.c
24
+++ b/target/arm/pauth_helper.c
20
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ static uint64_t pac_sub(uint64_t i)
21
#include "sysemu/kvm.h"
26
uint64_t o = 0;
22
#include "kvm_arm.h"
27
int b;
23
#include "cpu.h"
28
24
+#include "trace.h"
29
- for (b = 0; b < 64; b += 16) {
25
#include "internals.h"
30
+ for (b = 0; b < 64; b += 4) {
26
#include "hw/arm/arm.h"
31
o |= (uint64_t)sub[(i >> b) & 0xf] << b;
27
+#include "hw/pci/pci.h"
32
}
28
#include "exec/memattrs.h"
33
return o;
29
#include "exec/address-spaces.h"
34
@@ -XXX,XX +XXX,XX @@ static uint64_t pac_inv_sub(uint64_t i)
30
#include "hw/boards.h"
35
uint64_t o = 0;
31
@@ -XXX,XX +XXX,XX @@ int kvm_arm_vgic_probe(void)
36
int b;
32
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
37
33
uint64_t address, uint32_t data, PCIDevice *dev)
38
- for (b = 0; b < 64; b += 16) {
34
{
39
+ for (b = 0; b < 64; b += 4) {
35
- return 0;
40
o |= (uint64_t)inv_sub[(i >> b) & 0xf] << b;
36
+ AddressSpace *as = pci_device_iommu_address_space(dev);
41
}
37
+ hwaddr xlat, len, doorbell_gpa;
42
return o;
38
+ MemoryRegionSection mrs;
39
+ MemoryRegion *mr;
40
+ int ret = 1;
41
+
42
+ if (as == &address_space_memory) {
43
+ return 0;
44
+ }
45
+
46
+ /* MSI doorbell address is translated by an IOMMU */
47
+
48
+ rcu_read_lock();
49
+ mr = address_space_translate(as, address, &xlat, &len, true);
50
+ if (!mr) {
51
+ goto unlock;
52
+ }
53
+ mrs = memory_region_find(mr, xlat, 1);
54
+ if (!mrs.mr) {
55
+ goto unlock;
56
+ }
57
+
58
+ doorbell_gpa = mrs.offset_within_address_space;
59
+ memory_region_unref(mrs.mr);
60
+
61
+ route->u.msi.address_lo = doorbell_gpa;
62
+ route->u.msi.address_hi = doorbell_gpa >> 32;
63
+
64
+ trace_kvm_arm_fixup_msi_route(address, doorbell_gpa);
65
+
66
+ ret = 0;
67
+
68
+unlock:
69
+ rcu_read_unlock();
70
+ return ret;
71
}
72
73
int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
74
diff --git a/target/arm/trace-events b/target/arm/trace-events
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/trace-events
77
+++ b/target/arm/trace-events
78
@@ -XXX,XX +XXX,XX @@ arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: timer %d value 0x%"
79
arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value 0x%" PRIx64
80
arm_gt_imask_toggle(int timer, int irqstate) "gt_ctl_write: timer %d IMASK toggle, new irqstate %d"
81
arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value 0x%" PRIx64
82
+
83
+# target/arm/kvm.c
84
+kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
85
--
43
--
86
2.17.0
44
2.20.1
87
45
88
46
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Path analysis shows that size == 3 && !is_q has been eliminated.
3
We were incorrectly requiring ARMv8.4 support for the pauth
4
tests, but Pointer Authentication is an ARMv8.3 extension.
5
Further, hiding the required architecture within asm() is
6
not correct.
4
7
5
Fixes: Coverity CID1385853
8
Correct the architecture version requested, and specify it
9
in the cflags of the (cross-) compiler rather than in the asm.
10
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20180501180455.11214-3-richard.henderson@linaro.org
13
Message-id: 20200116230809.19078-3-richard.henderson@linaro.org
14
[PMM: tweaked commit message]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
target/arm/translate-a64.c | 6 +++++-
17
tests/tcg/aarch64/Makefile.target | 1 +
12
1 file changed, 5 insertions(+), 1 deletion(-)
18
tests/tcg/aarch64/pauth-1.c | 2 --
19
tests/tcg/aarch64/pauth-2.c | 2 --
20
3 files changed, 1 insertion(+), 4 deletions(-)
13
21
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
22
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
24
--- a/tests/tcg/aarch64/Makefile.target
17
+++ b/target/arm/translate-a64.c
25
+++ b/tests/tcg/aarch64/Makefile.target
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
26
@@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt
19
/* All 64-bit element operations can be shared with scalar 2misc */
27
# Pauth Tests
20
int pass;
28
AARCH64_TESTS += pauth-1 pauth-2
21
29
run-pauth-%: QEMU_OPTS += -cpu max
22
- for (pass = 0; pass < (is_q ? 2 : 1); pass++) {
30
+pauth-%: CFLAGS += -march=armv8.3-a
23
+ /* Coverity claims (size == 3 && !is_q) has been eliminated
31
24
+ * from all paths leading to here.
32
# Semihosting smoke test for linux-user
25
+ */
33
AARCH64_TESTS += semihosting
26
+ tcg_debug_assert(is_q);
34
diff --git a/tests/tcg/aarch64/pauth-1.c b/tests/tcg/aarch64/pauth-1.c
27
+ for (pass = 0; pass < 2; pass++) {
35
index XXXXXXX..XXXXXXX 100644
28
TCGv_i64 tcg_op = tcg_temp_new_i64();
36
--- a/tests/tcg/aarch64/pauth-1.c
29
TCGv_i64 tcg_res = tcg_temp_new_i64();
37
+++ b/tests/tcg/aarch64/pauth-1.c
30
38
@@ -XXX,XX +XXX,XX @@
39
#include <sys/prctl.h>
40
#include <stdio.h>
41
42
-asm(".arch armv8.4-a");
43
-
44
#ifndef PR_PAC_RESET_KEYS
45
#define PR_PAC_RESET_KEYS 54
46
#define PR_PAC_APDAKEY (1 << 2)
47
diff --git a/tests/tcg/aarch64/pauth-2.c b/tests/tcg/aarch64/pauth-2.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/tests/tcg/aarch64/pauth-2.c
50
+++ b/tests/tcg/aarch64/pauth-2.c
51
@@ -XXX,XX +XXX,XX @@
52
#include <stdint.h>
53
#include <assert.h>
54
55
-asm(".arch armv8.4-a");
56
-
57
void do_test(uint64_t value)
58
{
59
uint64_t salt1, salt2;
31
--
60
--
32
2.17.0
61
2.20.1
33
62
34
63
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Now we have relevant helpers for queue and irq
3
This is the test vector from the QARMA paper, run through PACGA.
4
management, let's implement MMIO write operations.
5
4
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
5
Suggested-by: Vincent Dehors <vincent.dehors@smile.fr>
7
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200116230809.19078-4-richard.henderson@linaro.org
9
Message-id: 1524665762-31355-8-git-send-email-eric.auger@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
hw/arm/smmuv3-internal.h | 8 +-
10
tests/tcg/aarch64/Makefile.softmmu-target | 5 ++-
13
hw/arm/smmuv3.c | 170 +++++++++++++++++++++++++++++++++++++--
11
tests/tcg/aarch64/system/pauth-3.c | 40 +++++++++++++++++++++++
14
hw/arm/trace-events | 6 ++
12
2 files changed, 44 insertions(+), 1 deletion(-)
15
3 files changed, 174 insertions(+), 10 deletions(-)
13
create mode 100644 tests/tcg/aarch64/system/pauth-3.c
16
14
17
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
15
diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/smmuv3-internal.h
17
--- a/tests/tcg/aarch64/Makefile.softmmu-target
20
+++ b/hw/arm/smmuv3-internal.h
18
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
21
@@ -XXX,XX +XXX,XX @@ REG32(CR0, 0x20)
19
@@ -XXX,XX +XXX,XX @@ run-memory-replay: memory-replay run-memory-record
22
FIELD(CR0, EVENTQEN, 2, 1)
20
          $(QEMU_OPTS) memory, \
23
FIELD(CR0, CMDQEN, 3, 1)
21
     "$< on $(TARGET_NAME)")
24
22
25
+#define SMMU_CR0_RESERVED 0xFFFFFC20
23
-EXTRA_TESTS+=memory-record memory-replay
24
+run-pauth-3: pauth-3
25
+pauth-3: CFLAGS += -march=armv8.3-a
26
+
26
+
27
REG32(CR0ACK, 0x24)
27
+EXTRA_TESTS+=memory-record memory-replay pauth-3
28
REG32(CR1, 0x28)
28
diff --git a/tests/tcg/aarch64/system/pauth-3.c b/tests/tcg/aarch64/system/pauth-3.c
29
REG32(CR2, 0x2c)
29
new file mode 100644
30
@@ -XXX,XX +XXX,XX @@ static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
30
index XXXXXXX..XXXXXXX
31
return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN);
31
--- /dev/null
32
}
32
+++ b/tests/tcg/aarch64/system/pauth-3.c
33
34
-/* public until callers get introduced */
35
-void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask);
36
-void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn);
37
-
38
/* Queue Handling */
39
40
#define Q_BASE(q) ((q)->base & SMMU_BASE_ADDR_MASK)
41
@@ -XXX,XX +XXX,XX @@ enum { /* Command completion notification */
42
addr; \
43
})
44
45
-int smmuv3_cmdq_consume(SMMUv3State *s);
46
+#define SMMU_FEATURE_2LVL_STE (1 << 0)
47
48
#endif
49
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/smmuv3.c
52
+++ b/hw/arm/smmuv3.c
53
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@
54
* @irq: irq type
34
+#include <inttypes.h>
55
* @gerror_mask: mask of gerrors to toggle (relevant if @irq is GERROR)
35
+#include <minilib.h>
56
*/
36
+
57
-void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask)
37
+int main()
58
+static void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq,
59
+ uint32_t gerror_mask)
60
{
61
62
bool pulse = false;
63
@@ -XXX,XX +XXX,XX @@ void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask)
64
}
65
}
66
67
-void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
68
+static void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
69
{
70
uint32_t pending = s->gerror ^ s->gerrorn;
71
uint32_t toggled = s->gerrorn ^ new_gerrorn;
72
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
73
s->sid_split = 0;
74
}
75
76
-int smmuv3_cmdq_consume(SMMUv3State *s)
77
+static int smmuv3_cmdq_consume(SMMUv3State *s)
78
{
79
SMMUCmdError cmd_error = SMMU_CERROR_NONE;
80
SMMUQueue *q = &s->cmdq;
81
@@ -XXX,XX +XXX,XX @@ int smmuv3_cmdq_consume(SMMUv3State *s)
82
return 0;
83
}
84
85
+static MemTxResult smmu_writell(SMMUv3State *s, hwaddr offset,
86
+ uint64_t data, MemTxAttrs attrs)
87
+{
38
+{
88
+ switch (offset) {
39
+ /*
89
+ case A_GERROR_IRQ_CFG0:
40
+ * Test vector from QARMA paper (https://eprint.iacr.org/2016/444.pdf)
90
+ s->gerror_irq_cfg0 = data;
41
+ * to verify one computation of the pauth_computepac() function,
91
+ return MEMTX_OK;
42
+ * which uses sbox2.
92
+ case A_STRTAB_BASE:
43
+ *
93
+ s->strtab_base = data;
44
+ * Use PACGA, because it returns the most bits from ComputePAC.
94
+ return MEMTX_OK;
45
+ * We still only get the most significant 32-bits of the result.
95
+ case A_CMDQ_BASE:
46
+ */
96
+ s->cmdq.base = data;
47
+
97
+ s->cmdq.log2size = extract64(s->cmdq.base, 0, 5);
48
+ static const uint64_t d[5] = {
98
+ if (s->cmdq.log2size > SMMU_CMDQS) {
49
+ 0xfb623599da6e8127ull,
99
+ s->cmdq.log2size = SMMU_CMDQS;
50
+ 0x477d469dec0b8762ull,
100
+ }
51
+ 0x84be85ce9804e94bull,
101
+ return MEMTX_OK;
52
+ 0xec2802d4e0a488e9ull,
102
+ case A_EVENTQ_BASE:
53
+ 0xc003b93999b33765ull & 0xffffffff00000000ull
103
+ s->eventq.base = data;
54
+ };
104
+ s->eventq.log2size = extract64(s->eventq.base, 0, 5);
55
+ uint64_t r;
105
+ if (s->eventq.log2size > SMMU_EVENTQS) {
56
+
106
+ s->eventq.log2size = SMMU_EVENTQS;
57
+ asm("msr apgakeyhi_el1, %[w0]\n\t"
107
+ }
58
+ "msr apgakeylo_el1, %[k0]\n\t"
108
+ return MEMTX_OK;
59
+ "pacga %[r], %[P], %[T]"
109
+ case A_EVENTQ_IRQ_CFG0:
60
+ : [r] "=r"(r)
110
+ s->eventq_irq_cfg0 = data;
61
+ : [P] "r" (d[0]),
111
+ return MEMTX_OK;
62
+ [T] "r" (d[1]),
112
+ default:
63
+ [w0] "r" (d[2]),
113
+ qemu_log_mask(LOG_UNIMP,
64
+ [k0] "r" (d[3]));
114
+ "%s Unexpected 64-bit access to 0x%"PRIx64" (WI)\n",
65
+
115
+ __func__, offset);
66
+ if (r == d[4]) {
116
+ return MEMTX_OK;
67
+ ml_printf("OK\n");
68
+ return 0;
69
+ } else {
70
+ ml_printf("FAIL: %lx != %lx\n", r, d[4]);
71
+ return 1;
117
+ }
72
+ }
118
+}
73
+}
119
+
120
+static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset,
121
+ uint64_t data, MemTxAttrs attrs)
122
+{
123
+ switch (offset) {
124
+ case A_CR0:
125
+ s->cr[0] = data;
126
+ s->cr0ack = data & ~SMMU_CR0_RESERVED;
127
+ /* in case the command queue has been enabled */
128
+ smmuv3_cmdq_consume(s);
129
+ return MEMTX_OK;
130
+ case A_CR1:
131
+ s->cr[1] = data;
132
+ return MEMTX_OK;
133
+ case A_CR2:
134
+ s->cr[2] = data;
135
+ return MEMTX_OK;
136
+ case A_IRQ_CTRL:
137
+ s->irq_ctrl = data;
138
+ return MEMTX_OK;
139
+ case A_GERRORN:
140
+ smmuv3_write_gerrorn(s, data);
141
+ /*
142
+ * By acknowledging the CMDQ_ERR, SW may notify cmds can
143
+ * be processed again
144
+ */
145
+ smmuv3_cmdq_consume(s);
146
+ return MEMTX_OK;
147
+ case A_GERROR_IRQ_CFG0: /* 64b */
148
+ s->gerror_irq_cfg0 = deposit64(s->gerror_irq_cfg0, 0, 32, data);
149
+ return MEMTX_OK;
150
+ case A_GERROR_IRQ_CFG0 + 4:
151
+ s->gerror_irq_cfg0 = deposit64(s->gerror_irq_cfg0, 32, 32, data);
152
+ return MEMTX_OK;
153
+ case A_GERROR_IRQ_CFG1:
154
+ s->gerror_irq_cfg1 = data;
155
+ return MEMTX_OK;
156
+ case A_GERROR_IRQ_CFG2:
157
+ s->gerror_irq_cfg2 = data;
158
+ return MEMTX_OK;
159
+ case A_STRTAB_BASE: /* 64b */
160
+ s->strtab_base = deposit64(s->strtab_base, 0, 32, data);
161
+ return MEMTX_OK;
162
+ case A_STRTAB_BASE + 4:
163
+ s->strtab_base = deposit64(s->strtab_base, 32, 32, data);
164
+ return MEMTX_OK;
165
+ case A_STRTAB_BASE_CFG:
166
+ s->strtab_base_cfg = data;
167
+ if (FIELD_EX32(data, STRTAB_BASE_CFG, FMT) == 1) {
168
+ s->sid_split = FIELD_EX32(data, STRTAB_BASE_CFG, SPLIT);
169
+ s->features |= SMMU_FEATURE_2LVL_STE;
170
+ }
171
+ return MEMTX_OK;
172
+ case A_CMDQ_BASE: /* 64b */
173
+ s->cmdq.base = deposit64(s->cmdq.base, 0, 32, data);
174
+ s->cmdq.log2size = extract64(s->cmdq.base, 0, 5);
175
+ if (s->cmdq.log2size > SMMU_CMDQS) {
176
+ s->cmdq.log2size = SMMU_CMDQS;
177
+ }
178
+ return MEMTX_OK;
179
+ case A_CMDQ_BASE + 4: /* 64b */
180
+ s->cmdq.base = deposit64(s->cmdq.base, 32, 32, data);
181
+ return MEMTX_OK;
182
+ case A_CMDQ_PROD:
183
+ s->cmdq.prod = data;
184
+ smmuv3_cmdq_consume(s);
185
+ return MEMTX_OK;
186
+ case A_CMDQ_CONS:
187
+ s->cmdq.cons = data;
188
+ return MEMTX_OK;
189
+ case A_EVENTQ_BASE: /* 64b */
190
+ s->eventq.base = deposit64(s->eventq.base, 0, 32, data);
191
+ s->eventq.log2size = extract64(s->eventq.base, 0, 5);
192
+ if (s->eventq.log2size > SMMU_EVENTQS) {
193
+ s->eventq.log2size = SMMU_EVENTQS;
194
+ }
195
+ return MEMTX_OK;
196
+ case A_EVENTQ_BASE + 4:
197
+ s->eventq.base = deposit64(s->eventq.base, 32, 32, data);
198
+ return MEMTX_OK;
199
+ case A_EVENTQ_PROD:
200
+ s->eventq.prod = data;
201
+ return MEMTX_OK;
202
+ case A_EVENTQ_CONS:
203
+ s->eventq.cons = data;
204
+ return MEMTX_OK;
205
+ case A_EVENTQ_IRQ_CFG0: /* 64b */
206
+ s->eventq_irq_cfg0 = deposit64(s->eventq_irq_cfg0, 0, 32, data);
207
+ return MEMTX_OK;
208
+ case A_EVENTQ_IRQ_CFG0 + 4:
209
+ s->eventq_irq_cfg0 = deposit64(s->eventq_irq_cfg0, 32, 32, data);
210
+ return MEMTX_OK;
211
+ case A_EVENTQ_IRQ_CFG1:
212
+ s->eventq_irq_cfg1 = data;
213
+ return MEMTX_OK;
214
+ case A_EVENTQ_IRQ_CFG2:
215
+ s->eventq_irq_cfg2 = data;
216
+ return MEMTX_OK;
217
+ default:
218
+ qemu_log_mask(LOG_UNIMP,
219
+ "%s Unexpected 32-bit access to 0x%"PRIx64" (WI)\n",
220
+ __func__, offset);
221
+ return MEMTX_OK;
222
+ }
223
+}
224
+
225
static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data,
226
unsigned size, MemTxAttrs attrs)
227
{
228
- /* not yet implemented */
229
- return MEMTX_ERROR;
230
+ SMMUState *sys = opaque;
231
+ SMMUv3State *s = ARM_SMMUV3(sys);
232
+ MemTxResult r;
233
+
234
+ /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */
235
+ offset &= ~0x10000;
236
+
237
+ switch (size) {
238
+ case 8:
239
+ r = smmu_writell(s, offset, data, attrs);
240
+ break;
241
+ case 4:
242
+ r = smmu_writel(s, offset, data, attrs);
243
+ break;
244
+ default:
245
+ r = MEMTX_ERROR;
246
+ break;
247
+ }
248
+
249
+ trace_smmuv3_write_mmio(offset, data, size, r);
250
+ return r;
251
}
252
253
static MemTxResult smmu_readll(SMMUv3State *s, hwaddr offset,
254
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
255
index XXXXXXX..XXXXXXX 100644
256
--- a/hw/arm/trace-events
257
+++ b/hw/arm/trace-events
258
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_consume(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t con
259
smmuv3_cmdq_opcode(const char *opcode) "<--- %s"
260
smmuv3_cmdq_consume_out(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod:%d, cons:%d, prod_wrap:%d, cons_wrap:%d "
261
smmuv3_cmdq_consume_error(const char *cmd_name, uint8_t cmd_error) "Error on %s command execution: %d"
262
+smmuv3_update(bool is_empty, uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "q empty:%d prod:%d cons:%d p.wrap:%d p.cons:%d"
263
+smmuv3_update_check_cmd(int error) "cmdq not enabled or error :0x%x"
264
+smmuv3_write_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
265
+smmuv3_write_mmio_idr(uint64_t addr, uint64_t val) "write to RO/Unimpl reg 0x%lx val64:0x%lx"
266
+smmuv3_write_mmio_evtq_cons_bef_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "Before clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
267
+smmuv3_write_mmio_evtq_cons_after_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "after clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
268
--
74
--
269
2.17.0
75
2.20.1
270
76
271
77
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The (size > 3 && !is_q) condition is identical to the preceeding test
3
Perform the set of operations and test described in LP 1859713.
4
of bit 3 in immh; eliminate it. For the benefit of Coverity, assert
5
that size is within the bounds we expect.
6
4
7
Fixes: Coverity CID1385846
5
Suggested-by: Adrien GRASSEIN <adrien.grassein@smile.fr>
8
Fixes: Coverity CID1385849
9
Fixes: Coverity CID1385852
10
Fixes: Coverity CID1385857
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20200116230809.19078-5-richard.henderson@linaro.org
13
Message-id: 20180501180455.11214-2-richard.henderson@linaro.org
8
[PMM: fixed hard-coded tabs]
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
target/arm/translate-a64.c | 6 +-----
11
tests/tcg/aarch64/Makefile.target | 2 +-
17
1 file changed, 1 insertion(+), 5 deletions(-)
12
tests/tcg/aarch64/pauth-4.c | 25 +++++++++++++++++++++++++
13
2 files changed, 26 insertions(+), 1 deletion(-)
14
create mode 100644 tests/tcg/aarch64/pauth-4.c
18
15
19
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-a64.c
18
--- a/tests/tcg/aarch64/Makefile.target
22
+++ b/target/arm/translate-a64.c
19
+++ b/tests/tcg/aarch64/Makefile.target
23
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
20
@@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt
24
unallocated_encoding(s);
21
    $(call diff-out,$<,$(AARCH64_SRC)/fcvt.ref)
25
return;
22
26
}
23
# Pauth Tests
27
-
24
-AARCH64_TESTS += pauth-1 pauth-2
28
- if (size > 3 && !is_q) {
25
+AARCH64_TESTS += pauth-1 pauth-2 pauth-4
29
- unallocated_encoding(s);
26
run-pauth-%: QEMU_OPTS += -cpu max
30
- return;
27
pauth-%: CFLAGS += -march=armv8.3-a
31
- }
28
32
+ tcg_debug_assert(size <= 3);
29
diff --git a/tests/tcg/aarch64/pauth-4.c b/tests/tcg/aarch64/pauth-4.c
33
30
new file mode 100644
34
if (!fp_access_check(s)) {
31
index XXXXXXX..XXXXXXX
35
return;
32
--- /dev/null
33
+++ b/tests/tcg/aarch64/pauth-4.c
34
@@ -XXX,XX +XXX,XX @@
35
+#include <stdint.h>
36
+#include <assert.h>
37
+
38
+int main()
39
+{
40
+ uintptr_t x, y;
41
+
42
+ asm("mov %0, lr\n\t"
43
+ "pacia %0, sp\n\t" /* sigill if pauth not supported */
44
+ "eor %0, %0, #4\n\t" /* corrupt single bit */
45
+ "mov %1, %0\n\t"
46
+ "autia %1, sp\n\t" /* validate corrupted pointer */
47
+ "xpaci %0\n\t" /* strip pac from corrupted pointer */
48
+ : "=r"(x), "=r"(y));
49
+
50
+ /*
51
+ * Once stripped, the corrupted pointer is of the form 0x0000...wxyz.
52
+ * We expect the autia to indicate failure, producing a pointer of the
53
+ * form 0x000e....wxyz. Use xpaci and != for the test, rather than
54
+ * extracting explicit bits from the top, because the location of the
55
+ * error code "e" depends on the configuration of virtual memory.
56
+ */
57
+ assert(x != y);
58
+ return 0;
59
+}
36
--
60
--
37
2.17.0
61
2.20.1
38
62
39
63
diff view generated by jsdifflib
1
From: Mathew Maidment <mathew1800@gmail.com>
1
From: Keqian Zhu <zhukeqian1@huawei.com>
2
2
3
The duplication of id_tlbtr_reginfo was unintentionally added within
3
There is extra indent in ACPI GED hotplug cb that should be
4
3281af8114c6b8ead02f08b58e3c36895c1ea047 which should have been
4
deleted.
5
id_mpuir_reginfo.
6
5
7
The effect was that for OMAP and StrongARM CPUs we would
6
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
8
incorrectly UNDEF writes to MPUIR rather than NOPing them.
7
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
9
8
Message-id: 20200120012755.44581-2-zhukeqian1@huawei.com
10
Signed-off-by: Mathew Maidment <mathew1800@gmail.com>
11
Message-id: 20180501184933.37609-2-mathew1800@gmail.com
12
[PMM: tweak commit message]
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
target/arm/helper.c | 2 +-
11
hw/acpi/generic_event_device.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
18
13
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
16
--- a/hw/acpi/generic_event_device.c
22
+++ b/target/arm/helper.c
17
+++ b/hw/acpi/generic_event_device.c
23
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
18
@@ -XXX,XX +XXX,XX @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
24
for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) {
19
AcpiGedState *s = ACPI_GED(hotplug_dev);
25
r->access = PL1_RW;
20
26
}
21
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
27
- id_tlbtr_reginfo.access = PL1_RW;
22
- acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);
28
+ id_mpuir_reginfo.access = PL1_RW;
23
+ acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);
29
id_tlbtr_reginfo.access = PL1_RW;
24
} else {
30
}
25
error_setg(errp, "virt: device plug request for unsupported device"
31
if (arm_feature(env, ARM_FEATURE_V8)) {
26
" type: %s", object_get_typename(OBJECT(dev)));
32
--
27
--
33
2.17.0
28
2.20.1
34
29
35
30
diff view generated by jsdifflib
1
From: Jan Kiszka <jan.kiszka@siemens.com>
1
From: Keqian Zhu <zhukeqian1@huawei.com>
2
2
3
This allows to pin the host controller in the Linux PCI domain space.
3
We can use existing helper function to trigger hotplug handler
4
Linux requires that property to be available consistently or not at all,
4
plug, which makes code clearer.
5
in which case the domain number becomes unstable on additions/removals.
6
Adding it here won't make a difference in practice for most setups as we
7
only expose one controller.
8
5
9
However, enabling Jailhouse on top may introduce another controller, and
6
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
that one would like to have stable address as well. So the property is
7
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
11
needed for the first controller as well.
8
Message-id: 20200120012755.44581-3-zhukeqian1@huawei.com
12
13
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
14
Message-id: 3301c5bc-7b47-1b0e-8ce4-30435057a276@web.de
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
hw/arm/virt.c | 1 +
11
hw/arm/virt.c | 6 +++---
19
1 file changed, 1 insertion(+)
12
1 file changed, 3 insertions(+), 3 deletions(-)
20
13
21
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
14
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
22
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/virt.c
16
--- a/hw/arm/virt.c
24
+++ b/hw/arm/virt.c
17
+++ b/hw/arm/virt.c
25
@@ -XXX,XX +XXX,XX @@ static void create_pcie(const VirtMachineState *vms, qemu_irq *pic)
18
@@ -XXX,XX +XXX,XX @@ static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
26
qemu_fdt_setprop_string(vms->fdt, nodename, "device_type", "pci");
19
static void virt_memory_plug(HotplugHandler *hotplug_dev,
27
qemu_fdt_setprop_cell(vms->fdt, nodename, "#address-cells", 3);
20
DeviceState *dev, Error **errp)
28
qemu_fdt_setprop_cell(vms->fdt, nodename, "#size-cells", 2);
21
{
29
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "linux,pci-domain", 0);
22
- HotplugHandlerClass *hhc;
30
qemu_fdt_setprop_cells(vms->fdt, nodename, "bus-range", 0,
23
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
31
nr_pcie_buses - 1);
24
Error *local_err = NULL;
32
qemu_fdt_setprop(vms->fdt, nodename, "dma-coherent", NULL, 0);
25
26
@@ -XXX,XX +XXX,XX @@ static void virt_memory_plug(HotplugHandler *hotplug_dev,
27
goto out;
28
}
29
30
- hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);
31
- hhc->plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &error_abort);
32
+ hotplug_handler_plug(HOTPLUG_HANDLER(vms->acpi_dev),
33
+ dev, &error_abort);
34
+
35
out:
36
error_propagate(errp, local_err);
37
}
33
--
38
--
34
2.17.0
39
2.20.1
35
40
36
41
diff view generated by jsdifflib
1
From: Prem Mallappa <prem.mallappa@broadcom.com>
1
The qemu-nbd documentation is currently in qemu-nbd.texi in Texinfo
2
2
format, which we present to the user as:
3
This patch implements a skeleton for the smmuv3 device.
3
* a qemu-nbd manpage
4
Datatypes and register definitions are introduced. The MMIO
4
* a section of the main qemu-doc HTML documentation
5
region, the interrupts and the queue are initialized.
5
6
6
Convert the documentation to rST format, and present it to the user as:
7
Only the MMIO read operation is implemented here.
7
* a qemu-nbd manpage
8
8
* part of the interop/ Sphinx manual
9
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
This follows the same pattern as commit 27a296fce982 did for the
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
qemu-ga manpage.
12
Message-id: 1524665762-31355-5-git-send-email-eric.auger@redhat.com
12
13
All the content of the old manpage is retained, except that I have
14
dropped the "This is free software; see the source for copying
15
conditions. There is NO warranty..." text that was in the old AUTHOR
16
section; Sphinx's manpage builder doesn't expect that much text in
17
the AUTHOR section, and since none of our other manpages have it it
18
seems easiest to delete it rather than try to figure out where else
19
in the manpage to put it.
20
21
The only other textual change is that I have had to give the
22
--nocache option its own description ("Equivalent to --cache=none")
23
because Sphinx doesn't have an equivalent of using item/itemx
24
to share a description between two options.
25
26
Some minor aspects of the formatting have changed, to suit what is
27
easiest for Sphinx to output. (The most notable is that Sphinx
28
option section option syntax doesn't support '--option foo=bar'
29
with bar underlined rather than bold, so we have to switch to
30
'--option foo=BAR' instead.)
31
32
The contents of qemu-option-trace.texi are now duplicated in
33
docs/interop/qemu-option-trace.rst.inc, until such time as we complete
34
the conversion of the other files which use it; since it has had only
35
3 changes in 3 years, this shouldn't be too awkward a burden.
36
(We use .rst.inc because if this file fragment has a .rst extension
37
then Sphinx complains about not seeing it in a toctree.)
38
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
41
Reviewed-by: Eric Blake <eblake@redhat.com>
42
Tested-by: Alex Bennée <alex.bennee@linaro.org>
43
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
44
Message-id: 20200116141511.16849-2-peter.maydell@linaro.org
14
---
45
---
15
hw/arm/Makefile.objs | 2 +-
46
Makefile | 16 +-
16
hw/arm/smmuv3-internal.h | 142 +++++++++++++++
47
MAINTAINERS | 1 +
17
include/hw/arm/smmuv3.h | 87 ++++++++++
48
docs/interop/conf.py | 4 +-
18
hw/arm/smmuv3.c | 366 +++++++++++++++++++++++++++++++++++++++
49
docs/interop/index.rst | 1 +
19
hw/arm/trace-events | 3 +
50
docs/interop/qemu-nbd.rst | 263 +++++++++++++++++++++++++
20
5 files changed, 599 insertions(+), 1 deletion(-)
51
docs/interop/qemu-option-trace.rst.inc | 30 +++
21
create mode 100644 hw/arm/smmuv3-internal.h
52
qemu-doc.texi | 6 -
22
create mode 100644 include/hw/arm/smmuv3.h
53
qemu-nbd.texi | 214 --------------------
23
create mode 100644 hw/arm/smmuv3.c
54
qemu-option-trace.texi | 4 +
24
55
9 files changed, 313 insertions(+), 226 deletions(-)
25
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
56
create mode 100644 docs/interop/qemu-nbd.rst
57
create mode 100644 docs/interop/qemu-option-trace.rst.inc
58
delete mode 100644 qemu-nbd.texi
59
60
diff --git a/Makefile b/Makefile
26
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/Makefile.objs
62
--- a/Makefile
28
+++ b/hw/arm/Makefile.objs
63
+++ b/Makefile
29
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2-tz.o
64
@@ -XXX,XX +XXX,XX @@ MANUAL_BUILDDIR := docs
30
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
65
endif
31
obj-$(CONFIG_IOTKIT) += iotkit.o
66
32
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
67
ifdef BUILD_DOCS
33
-obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o
68
-DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8 $(MANUAL_BUILDDIR)/interop/qemu-ga.8
34
+obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
69
+DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1
35
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
70
+DOCS+=$(MANUAL_BUILDDIR)/interop/qemu-nbd.8
71
+DOCS+=$(MANUAL_BUILDDIR)/interop/qemu-ga.8
72
DOCS+=docs/interop/qemu-qmp-ref.html docs/interop/qemu-qmp-ref.txt docs/interop/qemu-qmp-ref.7
73
DOCS+=docs/interop/qemu-ga-ref.html docs/interop/qemu-ga-ref.txt docs/interop/qemu-ga-ref.7
74
DOCS+=docs/qemu-block-drivers.7
75
@@ -XXX,XX +XXX,XX @@ ifdef CONFIG_POSIX
76
ifeq ($(CONFIG_TOOLS),y)
77
    $(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
78
    $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8"
79
-    $(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
80
+    $(INSTALL_DATA) $(MANUAL_BUILDDIR)/interop/qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
81
endif
82
ifdef CONFIG_TRACE_SYSTEMTAP
83
    $(INSTALL_DATA) scripts/qemu-trace-stap.1 "$(DESTDIR)$(mandir)/man1"
84
@@ -XXX,XX +XXX,XX @@ sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html $(MANUAL_BUILDDIR)/interop/index
85
# a single doctree: https://github.com/sphinx-doc/sphinx/issues/2946
86
build-manual = $(call quiet-command,CONFDIR="$(qemu_confdir)" sphinx-build $(if $(V),,-q) -W -b $2 -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1-$2 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
87
# We assume all RST files in the manual's directory are used in it
88
-manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py
89
+manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) \
90
+ $(wildcard $(SRC_PATH)/docs/$1/*.rst.inc) \
91
+ $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py
92
93
$(MANUAL_BUILDDIR)/devel/index.html: $(call manual-deps,devel)
94
    $(call build-manual,devel,html)
95
@@ -XXX,XX +XXX,XX @@ $(MANUAL_BUILDDIR)/specs/index.html: $(call manual-deps,specs)
96
$(MANUAL_BUILDDIR)/interop/qemu-ga.8: $(call manual-deps,interop)
97
    $(call build-manual,interop,man)
98
99
+$(MANUAL_BUILDDIR)/interop/qemu-nbd.8: $(call manual-deps,interop)
100
+    $(call build-manual,interop,man)
101
+
102
$(MANUAL_BUILDDIR)/index.html: $(SRC_PATH)/docs/index.html.in qemu-version.h
103
    @mkdir -p "$(MANUAL_BUILDDIR)"
104
    $(call quiet-command, sed "s|@@VERSION@@|${VERSION}|g" $< >$@, \
105
@@ -XXX,XX +XXX,XX @@ qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi qemu-monitor-info.texi
106
qemu.1: qemu-option-trace.texi
107
qemu-img.1: qemu-img.texi qemu-option-trace.texi qemu-img-cmds.texi
108
fsdev/virtfs-proxy-helper.1: fsdev/virtfs-proxy-helper.texi
109
-qemu-nbd.8: qemu-nbd.texi qemu-option-trace.texi
110
docs/qemu-block-drivers.7: docs/qemu-block-drivers.texi
111
docs/qemu-cpu-models.7: docs/qemu-cpu-models.texi
112
scripts/qemu-trace-stap.1: scripts/qemu-trace-stap.texi
113
@@ -XXX,XX +XXX,XX @@ pdf: qemu-doc.pdf docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf
114
txt: qemu-doc.txt docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
115
116
qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \
117
-    qemu-img.texi qemu-nbd.texi qemu-options.texi \
118
+    qemu-img.texi qemu-options.texi \
119
    qemu-tech.texi qemu-option-trace.texi \
120
    qemu-deprecated.texi qemu-monitor.texi qemu-img-cmds.texi \
121
    qemu-monitor-info.texi docs/qemu-block-drivers.texi \
122
diff --git a/MAINTAINERS b/MAINTAINERS
123
index XXXXXXX..XXXXXXX 100644
124
--- a/MAINTAINERS
125
+++ b/MAINTAINERS
126
@@ -XXX,XX +XXX,XX @@ F: include/block/nbd*
127
F: qemu-nbd.*
128
F: blockdev-nbd.c
129
F: docs/interop/nbd.txt
130
+F: docs/interop/qemu-nbd.rst
131
T: git https://repo.or.cz/qemu/ericb.git nbd
132
133
NFS
134
diff --git a/docs/interop/conf.py b/docs/interop/conf.py
135
index XXXXXXX..XXXXXXX 100644
136
--- a/docs/interop/conf.py
137
+++ b/docs/interop/conf.py
138
@@ -XXX,XX +XXX,XX @@ html_theme_options['description'] = u'System Emulation Management and Interopera
139
# (source start file, name, description, authors, manual section).
140
man_pages = [
141
('qemu-ga', 'qemu-ga', u'QEMU Guest Agent',
142
- ['Michael Roth <mdroth@linux.vnet.ibm.com>'], 8)
143
+ ['Michael Roth <mdroth@linux.vnet.ibm.com>'], 8),
144
+ ('qemu-nbd', 'qemu-nbd', u'QEMU Disk Network Block Device Server',
145
+ ['Anthony Liguori <anthony@codemonkey.ws>'], 8)
146
]
147
diff --git a/docs/interop/index.rst b/docs/interop/index.rst
148
index XXXXXXX..XXXXXXX 100644
149
--- a/docs/interop/index.rst
150
+++ b/docs/interop/index.rst
151
@@ -XXX,XX +XXX,XX @@ Contents:
152
live-block-operations
153
pr-helper
154
qemu-ga
155
+ qemu-nbd
156
vhost-user
157
vhost-user-gpu
158
diff --git a/docs/interop/qemu-nbd.rst b/docs/interop/qemu-nbd.rst
36
new file mode 100644
159
new file mode 100644
37
index XXXXXXX..XXXXXXX
160
index XXXXXXX..XXXXXXX
38
--- /dev/null
161
--- /dev/null
39
+++ b/hw/arm/smmuv3-internal.h
162
+++ b/docs/interop/qemu-nbd.rst
40
@@ -XXX,XX +XXX,XX @@
163
@@ -XXX,XX +XXX,XX @@
41
+/*
164
+QEMU Disk Network Block Device Server
42
+ * ARM SMMUv3 support - Internal API
165
+=====================================
43
+ *
166
+
44
+ * Copyright (C) 2014-2016 Broadcom Corporation
167
+Synopsis
45
+ * Copyright (c) 2017 Red Hat, Inc.
168
+--------
46
+ * Written by Prem Mallappa, Eric Auger
169
+
47
+ *
170
+**qemu-nbd** [*OPTION*]... *filename*
48
+ * This program is free software; you can redistribute it and/or modify
171
+
49
+ * it under the terms of the GNU General Public License version 2 as
172
+**qemu-nbd** -L [*OPTION*]...
50
+ * published by the Free Software Foundation.
173
+
51
+ *
174
+**qemu-nbd** -d *dev*
52
+ * This program is distributed in the hope that it will be useful,
175
+
53
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
176
+Description
54
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
177
+-----------
55
+ * GNU General Public License for more details.
178
+
56
+ *
179
+Export a QEMU disk image using the NBD protocol.
57
+ * You should have received a copy of the GNU General Public License along
180
+
58
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
181
+Other uses:
59
+ */
182
+
60
+
183
+- Bind a /dev/nbdX block device to a QEMU server (on Linux).
61
+#ifndef HW_ARM_SMMU_V3_INTERNAL_H
184
+- As a client to query exports of a remote NBD server.
62
+#define HW_ARM_SMMU_V3_INTERNAL_H
185
+
63
+
186
+Options
64
+#include "hw/arm/smmu-common.h"
187
+-------
65
+
188
+
66
+/* MMIO Registers */
189
+.. program:: qemu-nbd
67
+
190
+
68
+REG32(IDR0, 0x0)
191
+*filename* is a disk image filename, or a set of block
69
+ FIELD(IDR0, S1P, 1 , 1)
192
+driver options if ``--image-opts`` is specified.
70
+ FIELD(IDR0, TTF, 2 , 2)
193
+
71
+ FIELD(IDR0, COHACC, 4 , 1)
194
+*dev* is an NBD device.
72
+ FIELD(IDR0, ASID16, 12, 1)
195
+
73
+ FIELD(IDR0, TTENDIAN, 21, 2)
196
+.. option:: --object type,id=ID,...props...
74
+ FIELD(IDR0, STALL_MODEL, 24, 2)
197
+
75
+ FIELD(IDR0, TERM_MODEL, 26, 1)
198
+ Define a new instance of the *type* object class identified by *ID*.
76
+ FIELD(IDR0, STLEVEL, 27, 2)
199
+ See the :manpage:`qemu(1)` manual page for full details of the properties
77
+
200
+ supported. The common object types that it makes sense to define are the
78
+REG32(IDR1, 0x4)
201
+ ``secret`` object, which is used to supply passwords and/or encryption
79
+ FIELD(IDR1, SIDSIZE, 0 , 6)
202
+ keys, and the ``tls-creds`` object, which is used to supply TLS
80
+ FIELD(IDR1, EVENTQS, 16, 5)
203
+ credentials for the qemu-nbd server or client.
81
+ FIELD(IDR1, CMDQS, 21, 5)
204
+
82
+
205
+.. option:: -p, --port=PORT
83
+#define SMMU_IDR1_SIDSIZE 16
206
+
84
+#define SMMU_CMDQS 19
207
+ TCP port to listen on as a server, or connect to as a client
85
+#define SMMU_EVENTQS 19
208
+ (default ``10809``).
86
+
209
+
87
+REG32(IDR2, 0x8)
210
+.. option:: -o, --offset=OFFSET
88
+REG32(IDR3, 0xc)
211
+
89
+REG32(IDR4, 0x10)
212
+ The offset into the image.
90
+REG32(IDR5, 0x14)
213
+
91
+ FIELD(IDR5, OAS, 0, 3);
214
+.. option:: -b, --bind=IFACE
92
+ FIELD(IDR5, GRAN4K, 4, 1);
215
+
93
+ FIELD(IDR5, GRAN16K, 5, 1);
216
+ The interface to bind to as a server, or connect to as a client
94
+ FIELD(IDR5, GRAN64K, 6, 1);
217
+ (default ``0.0.0.0``).
95
+
218
+
96
+#define SMMU_IDR5_OAS 4
219
+.. option:: -k, --socket=PATH
97
+
220
+
98
+REG32(IIDR, 0x1c)
221
+ Use a unix socket with path *PATH*.
99
+REG32(CR0, 0x20)
222
+
100
+ FIELD(CR0, SMMU_ENABLE, 0, 1)
223
+.. option:: --image-opts
101
+ FIELD(CR0, EVENTQEN, 2, 1)
224
+
102
+ FIELD(CR0, CMDQEN, 3, 1)
225
+ Treat *filename* as a set of image options, instead of a plain
103
+
226
+ filename. If this flag is specified, the ``-f`` flag should
104
+REG32(CR0ACK, 0x24)
227
+ not be used, instead the :option:`format=` option should be set.
105
+REG32(CR1, 0x28)
228
+
106
+REG32(CR2, 0x2c)
229
+.. option:: -f, --format=FMT
107
+REG32(STATUSR, 0x40)
230
+
108
+REG32(IRQ_CTRL, 0x50)
231
+ Force the use of the block driver for format *FMT* instead of
109
+ FIELD(IRQ_CTRL, GERROR_IRQEN, 0, 1)
232
+ auto-detecting.
110
+ FIELD(IRQ_CTRL, PRI_IRQEN, 1, 1)
233
+
111
+ FIELD(IRQ_CTRL, EVENTQ_IRQEN, 2, 1)
234
+.. option:: -r, --read-only
112
+
235
+
113
+REG32(IRQ_CTRL_ACK, 0x54)
236
+ Export the disk as read-only.
114
+REG32(GERROR, 0x60)
237
+
115
+ FIELD(GERROR, CMDQ_ERR, 0, 1)
238
+.. option:: -P, --partition=NUM
116
+ FIELD(GERROR, EVENTQ_ABT_ERR, 2, 1)
239
+
117
+ FIELD(GERROR, PRIQ_ABT_ERR, 3, 1)
240
+ Deprecated: Only expose MBR partition *NUM*. Understands physical
118
+ FIELD(GERROR, MSI_CMDQ_ABT_ERR, 4, 1)
241
+ partitions 1-4 and logical partition 5. New code should instead use
119
+ FIELD(GERROR, MSI_EVENTQ_ABT_ERR, 5, 1)
242
+ :option:`--image-opts` with the raw driver wrapping a subset of the
120
+ FIELD(GERROR, MSI_PRIQ_ABT_ERR, 6, 1)
243
+ original image.
121
+ FIELD(GERROR, MSI_GERROR_ABT_ERR, 7, 1)
244
+
122
+ FIELD(GERROR, MSI_SFM_ERR, 8, 1)
245
+.. option:: -B, --bitmap=NAME
123
+
246
+
124
+REG32(GERRORN, 0x64)
247
+ If *filename* has a qcow2 persistent bitmap *NAME*, expose
125
+
248
+ that bitmap via the ``qemu:dirty-bitmap:NAME`` context
126
+#define A_GERROR_IRQ_CFG0 0x68 /* 64b */
249
+ accessible through NBD_OPT_SET_META_CONTEXT.
127
+REG32(GERROR_IRQ_CFG1, 0x70)
250
+
128
+REG32(GERROR_IRQ_CFG2, 0x74)
251
+.. option:: -s, --snapshot
129
+
252
+
130
+#define A_STRTAB_BASE 0x80 /* 64b */
253
+ Use *filename* as an external snapshot, create a temporary
131
+
254
+ file with ``backing_file=``\ *filename*, redirect the write to
132
+#define SMMU_BASE_ADDR_MASK 0xffffffffffe0
255
+ the temporary one.
133
+
256
+
134
+REG32(STRTAB_BASE_CFG, 0x88)
257
+.. option:: -l, --load-snapshot=SNAPSHOT_PARAM
135
+ FIELD(STRTAB_BASE_CFG, FMT, 16, 2)
258
+
136
+ FIELD(STRTAB_BASE_CFG, SPLIT, 6 , 5)
259
+ Load an internal snapshot inside *filename* and export it
137
+ FIELD(STRTAB_BASE_CFG, LOG2SIZE, 0 , 6)
260
+ as an read-only device, SNAPSHOT_PARAM format is
138
+
261
+ ``snapshot.id=[ID],snapshot.name=[NAME]`` or ``[ID_OR_NAME]``
139
+#define A_CMDQ_BASE 0x90 /* 64b */
262
+
140
+REG32(CMDQ_PROD, 0x98)
263
+.. option:: --cache=CACHE
141
+REG32(CMDQ_CONS, 0x9c)
264
+
142
+ FIELD(CMDQ_CONS, ERR, 24, 7)
265
+ The cache mode to be used with the file. See the documentation of
143
+
266
+ the emulator's ``-drive cache=...`` option for allowed values.
144
+#define A_EVENTQ_BASE 0xa0 /* 64b */
267
+
145
+REG32(EVENTQ_PROD, 0xa8)
268
+.. option:: -n, --nocache
146
+REG32(EVENTQ_CONS, 0xac)
269
+
147
+
270
+ Equivalent to :option:`--cache=none`.
148
+#define A_EVENTQ_IRQ_CFG0 0xb0 /* 64b */
271
+
149
+REG32(EVENTQ_IRQ_CFG1, 0xb8)
272
+.. option:: --aio=AIO
150
+REG32(EVENTQ_IRQ_CFG2, 0xbc)
273
+
151
+
274
+ Set the asynchronous I/O mode between ``threads`` (the default)
152
+#define A_IDREGS 0xfd0
275
+ and ``native`` (Linux only).
153
+
276
+
154
+static inline int smmu_enabled(SMMUv3State *s)
277
+.. option:: --discard=DISCARD
155
+{
278
+
156
+ return FIELD_EX32(s->cr[0], CR0, SMMU_ENABLE);
279
+ Control whether ``discard`` (also known as ``trim`` or ``unmap``)
157
+}
280
+ requests are ignored or passed to the filesystem. *DISCARD* is one of
158
+
281
+ ``ignore`` (or ``off``), ``unmap`` (or ``on``). The default is
159
+/* Command Queue Entry */
282
+ ``ignore``.
160
+typedef struct Cmd {
283
+
161
+ uint32_t word[4];
284
+.. option:: --detect-zeroes=DETECT_ZEROES
162
+} Cmd;
285
+
163
+
286
+ Control the automatic conversion of plain zero writes by the OS to
164
+/* Event Queue Entry */
287
+ driver-specific optimized zero write commands. *DETECT_ZEROES* is one of
165
+typedef struct Evt {
288
+ ``off``, ``on``, or ``unmap``. ``unmap``
166
+ uint32_t word[8];
289
+ converts a zero write to an unmap operation and can only be used if
167
+} Evt;
290
+ *DISCARD* is set to ``unmap``. The default is ``off``.
168
+
291
+
169
+static inline uint32_t smmuv3_idreg(int regoffset)
292
+.. option:: -c, --connect=DEV
170
+{
293
+
171
+ /*
294
+ Connect *filename* to NBD device *DEV* (Linux only).
172
+ * Return the value of the Primecell/Corelink ID registers at the
295
+
173
+ * specified offset from the first ID register.
296
+.. option:: -d, --disconnect
174
+ * These value indicate an ARM implementation of MMU600 p1
297
+
175
+ */
298
+ Disconnect the device *DEV* (Linux only).
176
+ static const uint8_t smmuv3_ids[] = {
299
+
177
+ 0x04, 0, 0, 0, 0x84, 0xB4, 0xF0, 0x10, 0x0D, 0xF0, 0x05, 0xB1
300
+.. option:: -e, --shared=NUM
178
+ };
301
+
179
+ return smmuv3_ids[regoffset / 4];
302
+ Allow up to *NUM* clients to share the device (default
180
+}
303
+ ``1``). Safe for readers, but for now, consistency is not
181
+
304
+ guaranteed between multiple writers.
182
+#endif
305
+
183
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
306
+.. option:: -t, --persistent
307
+
308
+ Don't exit on the last connection.
309
+
310
+.. option:: -x, --export-name=NAME
311
+
312
+ Set the NBD volume export name (default of a zero-length string).
313
+
314
+.. option:: -D, --description=DESCRIPTION
315
+
316
+ Set the NBD volume export description, as a human-readable
317
+ string.
318
+
319
+.. option:: -L, --list
320
+
321
+ Connect as a client and list all details about the exports exposed by
322
+ a remote NBD server. This enables list mode, and is incompatible
323
+ with options that change behavior related to a specific export (such as
324
+ :option:`--export-name`, :option:`--offset`, ...).
325
+
326
+.. option:: --tls-creds=ID
327
+
328
+ Enable mandatory TLS encryption for the server by setting the ID
329
+ of the TLS credentials object previously created with the --object
330
+ option; or provide the credentials needed for connecting as a client
331
+ in list mode.
332
+
333
+.. option:: --fork
334
+
335
+ Fork off the server process and exit the parent once the server is running.
336
+
337
+.. option:: --pid-file=PATH
338
+
339
+ Store the server's process ID in the given file.
340
+
341
+.. option:: --tls-authz=ID
342
+
343
+ Specify the ID of a qauthz object previously created with the
344
+ :option:`--object` option. This will be used to authorize connecting users
345
+ against their x509 distinguished name.
346
+
347
+.. option:: -v, --verbose
348
+
349
+ Display extra debugging information.
350
+
351
+.. option:: -h, --help
352
+
353
+ Display this help and exit.
354
+
355
+.. option:: -V, --version
356
+
357
+ Display version information and exit.
358
+
359
+.. option:: -T, --trace [[enable=]PATTERN][,events=FILE][,file=FILE]
360
+
361
+ .. include:: qemu-option-trace.rst.inc
362
+
363
+Examples
364
+--------
365
+
366
+Start a server listening on port 10809 that exposes only the
367
+guest-visible contents of a qcow2 file, with no TLS encryption, and
368
+with the default export name (an empty string). The command is
369
+one-shot, and will block until the first successful client
370
+disconnects:
371
+
372
+::
373
+
374
+ qemu-nbd -f qcow2 file.qcow2
375
+
376
+Start a long-running server listening with encryption on port 10810,
377
+and whitelist clients with a specific X.509 certificate to connect to
378
+a 1 megabyte subset of a raw file, using the export name 'subset':
379
+
380
+::
381
+
382
+ qemu-nbd \
383
+ --object tls-creds-x509,id=tls0,endpoint=server,dir=/path/to/qemutls \
384
+ --object 'authz-simple,id=auth0,identity=CN=laptop.example.com,,\
385
+ O=Example Org,,L=London,,ST=London,,C=GB' \
386
+ --tls-creds tls0 --tls-authz auth0 \
387
+ -t -x subset -p 10810 \
388
+ --image-opts driver=raw,offset=1M,size=1M,file.driver=file,file.filename=file.raw
389
+
390
+Serve a read-only copy of just the first MBR partition of a guest
391
+image over a Unix socket with as many as 5 simultaneous readers, with
392
+a persistent process forked as a daemon:
393
+
394
+::
395
+
396
+ qemu-nbd --fork --persistent --shared=5 --socket=/path/to/sock \
397
+ --partition=1 --read-only --format=qcow2 file.qcow2
398
+
399
+Expose the guest-visible contents of a qcow2 file via a block device
400
+/dev/nbd0 (and possibly creating /dev/nbd0p1 and friends for
401
+partitions found within), then disconnect the device when done.
402
+Access to bind qemu-nbd to an /dev/nbd device generally requires root
403
+privileges, and may also require the execution of ``modprobe nbd``
404
+to enable the kernel NBD client module. *CAUTION*: Do not use
405
+this method to mount filesystems from an untrusted guest image - a
406
+malicious guest may have prepared the image to attempt to trigger
407
+kernel bugs in partition probing or file system mounting.
408
+
409
+::
410
+
411
+ qemu-nbd -c /dev/nbd0 -f qcow2 file.qcow2
412
+ qemu-nbd -d /dev/nbd0
413
+
414
+Query a remote server to see details about what export(s) it is
415
+serving on port 10809, and authenticating via PSK:
416
+
417
+::
418
+
419
+ qemu-nbd \
420
+ --object tls-creds-psk,id=tls0,dir=/tmp/keys,username=eblake,endpoint=client \
421
+ --tls-creds tls0 -L -b remote.example.com
422
+
423
+See also
424
+--------
425
+
426
+:manpage:`qemu(1)`, :manpage:`qemu-img(1)`
427
diff --git a/docs/interop/qemu-option-trace.rst.inc b/docs/interop/qemu-option-trace.rst.inc
184
new file mode 100644
428
new file mode 100644
185
index XXXXXXX..XXXXXXX
429
index XXXXXXX..XXXXXXX
186
--- /dev/null
430
--- /dev/null
187
+++ b/include/hw/arm/smmuv3.h
431
+++ b/docs/interop/qemu-option-trace.rst.inc
188
@@ -XXX,XX +XXX,XX @@
432
@@ -XXX,XX +XXX,XX @@
189
+/*
433
+..
190
+ * Copyright (C) 2014-2016 Broadcom Corporation
434
+ The contents of this file must be kept in sync with qemu-option-trace.texi
191
+ * Copyright (c) 2017 Red Hat, Inc.
435
+ until all the users of the texi file have been converted to rst and
192
+ * Written by Prem Mallappa, Eric Auger
436
+ the texi file can be removed.
193
+ *
437
+
194
+ * This program is free software; you can redistribute it and/or modify
438
+Specify tracing options.
195
+ * it under the terms of the GNU General Public License version 2 as
439
+
196
+ * published by the Free Software Foundation.
440
+.. option:: [enable=]PATTERN
197
+ *
441
+
198
+ * This program is distributed in the hope that it will be useful,
442
+ Immediately enable events matching *PATTERN*
199
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
443
+ (either event name or a globbing pattern). This option is only
200
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
444
+ available if QEMU has been compiled with the ``simple``, ``log``
201
+ * GNU General Public License for more details.
445
+ or ``ftrace`` tracing backend. To specify multiple events or patterns,
202
+ *
446
+ specify the :option:`-trace` option multiple times.
203
+ * You should have received a copy of the GNU General Public License along
447
+
204
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
448
+ Use :option:`-trace help` to print a list of names of trace points.
205
+ */
449
+
206
+
450
+.. option:: events=FILE
207
+#ifndef HW_ARM_SMMUV3_H
451
+
208
+#define HW_ARM_SMMUV3_H
452
+ Immediately enable events listed in *FILE*.
209
+
453
+ The file must contain one event name (as listed in the ``trace-events-all``
210
+#include "hw/arm/smmu-common.h"
454
+ file) per line; globbing patterns are accepted too. This option is only
211
+#include "hw/registerfields.h"
455
+ available if QEMU has been compiled with the ``simple``, ``log`` or
212
+
456
+ ``ftrace`` tracing backend.
213
+#define TYPE_SMMUV3_IOMMU_MEMORY_REGION "smmuv3-iommu-memory-region"
457
+
214
+
458
+.. option:: file=FILE
215
+typedef struct SMMUQueue {
459
+
216
+ uint64_t base; /* base register */
460
+ Log output traces to *FILE*.
217
+ uint32_t prod;
461
+ This option is only available if QEMU has been compiled with
218
+ uint32_t cons;
462
+ the ``simple`` tracing backend.
219
+ uint8_t entry_size;
463
diff --git a/qemu-doc.texi b/qemu-doc.texi
220
+ uint8_t log2size;
464
index XXXXXXX..XXXXXXX 100644
221
+} SMMUQueue;
465
--- a/qemu-doc.texi
222
+
466
+++ b/qemu-doc.texi
223
+typedef struct SMMUv3State {
467
@@ -XXX,XX +XXX,XX @@ encrypted disk images.
224
+ SMMUState smmu_state;
468
* disk_images_snapshot_mode:: Snapshot mode
225
+
469
* vm_snapshots:: VM snapshots
226
+ uint32_t features;
470
* qemu_img_invocation:: qemu-img Invocation
227
+ uint8_t sid_size;
471
-* qemu_nbd_invocation:: qemu-nbd Invocation
228
+ uint8_t sid_split;
472
* disk_images_formats:: Disk image file formats
229
+
473
* host_drives:: Using host drives
230
+ uint32_t idr[6];
474
* disk_images_fat_images:: Virtual FAT disk images
231
+ uint32_t iidr;
475
@@ -XXX,XX +XXX,XX @@ state is not saved or restored properly (in particular USB).
232
+ uint32_t cr[3];
476
233
+ uint32_t cr0ack;
477
@include qemu-img.texi
234
+ uint32_t statusr;
478
235
+ uint32_t irq_ctrl;
479
-@node qemu_nbd_invocation
236
+ uint32_t gerror;
480
-@subsection @code{qemu-nbd} Invocation
237
+ uint32_t gerrorn;
481
-
238
+ uint64_t gerror_irq_cfg0;
482
-@include qemu-nbd.texi
239
+ uint32_t gerror_irq_cfg1;
483
-
240
+ uint32_t gerror_irq_cfg2;
484
@include docs/qemu-block-drivers.texi
241
+ uint64_t strtab_base;
485
242
+ uint32_t strtab_base_cfg;
486
@node pcsys_network
243
+ uint64_t eventq_irq_cfg0;
487
diff --git a/qemu-nbd.texi b/qemu-nbd.texi
244
+ uint32_t eventq_irq_cfg1;
488
deleted file mode 100644
245
+ uint32_t eventq_irq_cfg2;
246
+
247
+ SMMUQueue eventq, cmdq;
248
+
249
+ qemu_irq irq[4];
250
+} SMMUv3State;
251
+
252
+typedef enum {
253
+ SMMU_IRQ_EVTQ,
254
+ SMMU_IRQ_PRIQ,
255
+ SMMU_IRQ_CMD_SYNC,
256
+ SMMU_IRQ_GERROR,
257
+} SMMUIrq;
258
+
259
+typedef struct {
260
+ /*< private >*/
261
+ SMMUBaseClass smmu_base_class;
262
+ /*< public >*/
263
+
264
+ DeviceRealize parent_realize;
265
+ DeviceReset parent_reset;
266
+} SMMUv3Class;
267
+
268
+#define TYPE_ARM_SMMUV3 "arm-smmuv3"
269
+#define ARM_SMMUV3(obj) OBJECT_CHECK(SMMUv3State, (obj), TYPE_ARM_SMMUV3)
270
+#define ARM_SMMUV3_CLASS(klass) \
271
+ OBJECT_CLASS_CHECK(SMMUv3Class, (klass), TYPE_ARM_SMMUV3)
272
+#define ARM_SMMUV3_GET_CLASS(obj) \
273
+ OBJECT_GET_CLASS(SMMUv3Class, (obj), TYPE_ARM_SMMUV3)
274
+
275
+#endif
276
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
277
new file mode 100644
278
index XXXXXXX..XXXXXXX
489
index XXXXXXX..XXXXXXX
279
--- /dev/null
490
--- a/qemu-nbd.texi
280
+++ b/hw/arm/smmuv3.c
491
+++ /dev/null
281
@@ -XXX,XX +XXX,XX @@
492
@@ -XXX,XX +XXX,XX @@
282
+/*
493
-@example
283
+ * Copyright (C) 2014-2016 Broadcom Corporation
494
-@c man begin SYNOPSIS
284
+ * Copyright (c) 2017 Red Hat, Inc.
495
-@command{qemu-nbd} [OPTION]... @var{filename}
285
+ * Written by Prem Mallappa, Eric Auger
496
-
286
+ *
497
-@command{qemu-nbd} @option{-L} [OPTION]...
287
+ * This program is free software; you can redistribute it and/or modify
498
-
288
+ * it under the terms of the GNU General Public License version 2 as
499
-@command{qemu-nbd} @option{-d} @var{dev}
289
+ * published by the Free Software Foundation.
500
-@c man end
290
+ *
501
-@end example
291
+ * This program is distributed in the hope that it will be useful,
502
-
292
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
503
-@c man begin DESCRIPTION
293
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
504
-
294
+ * GNU General Public License for more details.
505
-Export a QEMU disk image using the NBD protocol.
295
+ *
506
-
296
+ * You should have received a copy of the GNU General Public License along
507
-Other uses:
297
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
508
-@itemize
298
+ */
509
-@item
299
+
510
-Bind a /dev/nbdX block device to a QEMU server (on Linux).
300
+#include "qemu/osdep.h"
511
-@item
301
+#include "hw/boards.h"
512
-As a client to query exports of a remote NBD server.
302
+#include "sysemu/sysemu.h"
513
-@end itemize
303
+#include "hw/sysbus.h"
514
-
304
+#include "hw/qdev-core.h"
515
-@c man end
305
+#include "hw/pci/pci.h"
516
-
306
+#include "exec/address-spaces.h"
517
-@c man begin OPTIONS
307
+#include "trace.h"
518
-@var{filename} is a disk image filename, or a set of block
308
+#include "qemu/log.h"
519
-driver options if @option{--image-opts} is specified.
309
+#include "qemu/error-report.h"
520
-
310
+#include "qapi/error.h"
521
-@var{dev} is an NBD device.
311
+
522
-
312
+#include "hw/arm/smmuv3.h"
523
-@table @option
313
+#include "smmuv3-internal.h"
524
-@item --object type,id=@var{id},...props...
314
+
525
-Define a new instance of the @var{type} object class identified by @var{id}.
315
+static void smmuv3_init_regs(SMMUv3State *s)
526
-See the @code{qemu(1)} manual page for full details of the properties
316
+{
527
-supported. The common object types that it makes sense to define are the
317
+ /**
528
-@code{secret} object, which is used to supply passwords and/or encryption
318
+ * IDR0: stage1 only, AArch64 only, coherent access, 16b ASID,
529
-keys, and the @code{tls-creds} object, which is used to supply TLS
319
+ * multi-level stream table
530
-credentials for the qemu-nbd server or client.
320
+ */
531
-@item -p, --port=@var{port}
321
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S1P, 1); /* stage 1 supported */
532
-The TCP port to listen on as a server, or connect to as a client
322
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTF, 2); /* AArch64 PTW only */
533
-(default @samp{10809}).
323
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, COHACC, 1); /* IO coherent */
534
-@item -o, --offset=@var{offset}
324
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ASID16, 1); /* 16-bit ASID */
535
-The offset into the image.
325
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTENDIAN, 2); /* little endian */
536
-@item -b, --bind=@var{iface}
326
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, STALL_MODEL, 1); /* No stall */
537
-The interface to bind to as a server, or connect to as a client
327
+ /* terminated transaction will always be aborted/error returned */
538
-(default @samp{0.0.0.0}).
328
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TERM_MODEL, 1);
539
-@item -k, --socket=@var{path}
329
+ /* 2-level stream table supported */
540
-Use a unix socket with path @var{path}.
330
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, STLEVEL, 1);
541
-@item --image-opts
331
+
542
-Treat @var{filename} as a set of image options, instead of a plain
332
+ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SIDSIZE, SMMU_IDR1_SIDSIZE);
543
-filename. If this flag is specified, the @var{-f} flag should
333
+ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, EVENTQS, SMMU_EVENTQS);
544
-not be used, instead the '@code{format=}' option should be set.
334
+ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, CMDQS, SMMU_CMDQS);
545
-@item -f, --format=@var{fmt}
335
+
546
-Force the use of the block driver for format @var{fmt} instead of
336
+ /* 4K and 64K granule support */
547
-auto-detecting.
337
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN4K, 1);
548
-@item -r, --read-only
338
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1);
549
-Export the disk as read-only.
339
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44 bits */
550
-@item -P, --partition=@var{num}
340
+
551
-Deprecated: Only expose MBR partition @var{num}. Understands physical
341
+ s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
552
-partitions 1-4 and logical partition 5. New code should instead use
342
+ s->cmdq.prod = 0;
553
-@option{--image-opts} with the raw driver wrapping a subset of the
343
+ s->cmdq.cons = 0;
554
-original image.
344
+ s->cmdq.entry_size = sizeof(struct Cmd);
555
-@item -B, --bitmap=@var{name}
345
+ s->eventq.base = deposit64(s->eventq.base, 0, 5, SMMU_EVENTQS);
556
-If @var{filename} has a qcow2 persistent bitmap @var{name}, expose
346
+ s->eventq.prod = 0;
557
-that bitmap via the ``qemu:dirty-bitmap:@var{name}'' context
347
+ s->eventq.cons = 0;
558
-accessible through NBD_OPT_SET_META_CONTEXT.
348
+ s->eventq.entry_size = sizeof(struct Evt);
559
-@item -s, --snapshot
349
+
560
-Use @var{filename} as an external snapshot, create a temporary
350
+ s->features = 0;
561
-file with backing_file=@var{filename}, redirect the write to
351
+ s->sid_split = 0;
562
-the temporary one.
352
+}
563
-@item -l, --load-snapshot=@var{snapshot_param}
353
+
564
-Load an internal snapshot inside @var{filename} and export it
354
+static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data,
565
-as an read-only device, @var{snapshot_param} format is
355
+ unsigned size, MemTxAttrs attrs)
566
-'snapshot.id=[ID],snapshot.name=[NAME]' or '[ID_OR_NAME]'
356
+{
567
-@item -n, --nocache
357
+ /* not yet implemented */
568
-@itemx --cache=@var{cache}
358
+ return MEMTX_ERROR;
569
-The cache mode to be used with the file. See the documentation of
359
+}
570
-the emulator's @code{-drive cache=...} option for allowed values.
360
+
571
-@item --aio=@var{aio}
361
+static MemTxResult smmu_readll(SMMUv3State *s, hwaddr offset,
572
-Set the asynchronous I/O mode between @samp{threads} (the default)
362
+ uint64_t *data, MemTxAttrs attrs)
573
-and @samp{native} (Linux only).
363
+{
574
-@item --discard=@var{discard}
364
+ switch (offset) {
575
-Control whether @dfn{discard} (also known as @dfn{trim} or @dfn{unmap})
365
+ case A_GERROR_IRQ_CFG0:
576
-requests are ignored or passed to the filesystem. @var{discard} is one of
366
+ *data = s->gerror_irq_cfg0;
577
-@samp{ignore} (or @samp{off}), @samp{unmap} (or @samp{on}). The default is
367
+ return MEMTX_OK;
578
-@samp{ignore}.
368
+ case A_STRTAB_BASE:
579
-@item --detect-zeroes=@var{detect-zeroes}
369
+ *data = s->strtab_base;
580
-Control the automatic conversion of plain zero writes by the OS to
370
+ return MEMTX_OK;
581
-driver-specific optimized zero write commands. @var{detect-zeroes} is one of
371
+ case A_CMDQ_BASE:
582
-@samp{off}, @samp{on} or @samp{unmap}. @samp{unmap}
372
+ *data = s->cmdq.base;
583
-converts a zero write to an unmap operation and can only be used if
373
+ return MEMTX_OK;
584
-@var{discard} is set to @samp{unmap}. The default is @samp{off}.
374
+ case A_EVENTQ_BASE:
585
-@item -c, --connect=@var{dev}
375
+ *data = s->eventq.base;
586
-Connect @var{filename} to NBD device @var{dev} (Linux only).
376
+ return MEMTX_OK;
587
-@item -d, --disconnect
377
+ default:
588
-Disconnect the device @var{dev} (Linux only).
378
+ *data = 0;
589
-@item -e, --shared=@var{num}
379
+ qemu_log_mask(LOG_UNIMP,
590
-Allow up to @var{num} clients to share the device (default
380
+ "%s Unexpected 64-bit access to 0x%"PRIx64" (RAZ)\n",
591
-@samp{1}). Safe for readers, but for now, consistency is not
381
+ __func__, offset);
592
-guaranteed between multiple writers.
382
+ return MEMTX_OK;
593
-@item -t, --persistent
383
+ }
594
-Don't exit on the last connection.
384
+}
595
-@item -x, --export-name=@var{name}
385
+
596
-Set the NBD volume export name (default of a zero-length string).
386
+static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset,
597
-@item -D, --description=@var{description}
387
+ uint64_t *data, MemTxAttrs attrs)
598
-Set the NBD volume export description, as a human-readable
388
+{
599
-string.
389
+ switch (offset) {
600
-@item -L, --list
390
+ case A_IDREGS ... A_IDREGS + 0x1f:
601
-Connect as a client and list all details about the exports exposed by
391
+ *data = smmuv3_idreg(offset - A_IDREGS);
602
-a remote NBD server. This enables list mode, and is incompatible
392
+ return MEMTX_OK;
603
-with options that change behavior related to a specific export (such as
393
+ case A_IDR0 ... A_IDR5:
604
-@option{--export-name}, @option{--offset}, ...).
394
+ *data = s->idr[(offset - A_IDR0) / 4];
605
-@item --tls-creds=ID
395
+ return MEMTX_OK;
606
-Enable mandatory TLS encryption for the server by setting the ID
396
+ case A_IIDR:
607
-of the TLS credentials object previously created with the --object
397
+ *data = s->iidr;
608
-option; or provide the credentials needed for connecting as a client
398
+ return MEMTX_OK;
609
-in list mode.
399
+ case A_CR0:
610
-@item --fork
400
+ *data = s->cr[0];
611
-Fork off the server process and exit the parent once the server is running.
401
+ return MEMTX_OK;
612
-@item --pid-file=PATH
402
+ case A_CR0ACK:
613
-Store the server's process ID in the given file.
403
+ *data = s->cr0ack;
614
-@item --tls-authz=ID
404
+ return MEMTX_OK;
615
-Specify the ID of a qauthz object previously created with the
405
+ case A_CR1:
616
---object option. This will be used to authorize connecting users
406
+ *data = s->cr[1];
617
-against their x509 distinguished name.
407
+ return MEMTX_OK;
618
-@item -v, --verbose
408
+ case A_CR2:
619
-Display extra debugging information.
409
+ *data = s->cr[2];
620
-@item -h, --help
410
+ return MEMTX_OK;
621
-Display this help and exit.
411
+ case A_STATUSR:
622
-@item -V, --version
412
+ *data = s->statusr;
623
-Display version information and exit.
413
+ return MEMTX_OK;
624
-@item -T, --trace [[enable=]@var{pattern}][,events=@var{file}][,file=@var{file}]
414
+ case A_IRQ_CTRL:
625
-@findex --trace
415
+ case A_IRQ_CTRL_ACK:
626
-@include qemu-option-trace.texi
416
+ *data = s->irq_ctrl;
627
-@end table
417
+ return MEMTX_OK;
628
-
418
+ case A_GERROR:
629
-@c man end
419
+ *data = s->gerror;
630
-
420
+ return MEMTX_OK;
631
-@c man begin EXAMPLES
421
+ case A_GERRORN:
632
-Start a server listening on port 10809 that exposes only the
422
+ *data = s->gerrorn;
633
-guest-visible contents of a qcow2 file, with no TLS encryption, and
423
+ return MEMTX_OK;
634
-with the default export name (an empty string). The command is
424
+ case A_GERROR_IRQ_CFG0: /* 64b */
635
-one-shot, and will block until the first successful client
425
+ *data = extract64(s->gerror_irq_cfg0, 0, 32);
636
-disconnects:
426
+ return MEMTX_OK;
637
-
427
+ case A_GERROR_IRQ_CFG0 + 4:
638
-@example
428
+ *data = extract64(s->gerror_irq_cfg0, 32, 32);
639
-qemu-nbd -f qcow2 file.qcow2
429
+ return MEMTX_OK;
640
-@end example
430
+ case A_GERROR_IRQ_CFG1:
641
-
431
+ *data = s->gerror_irq_cfg1;
642
-Start a long-running server listening with encryption on port 10810,
432
+ return MEMTX_OK;
643
-and whitelist clients with a specific X.509 certificate to connect to
433
+ case A_GERROR_IRQ_CFG2:
644
-a 1 megabyte subset of a raw file, using the export name 'subset':
434
+ *data = s->gerror_irq_cfg2;
645
-
435
+ return MEMTX_OK;
646
-@example
436
+ case A_STRTAB_BASE: /* 64b */
647
-qemu-nbd \
437
+ *data = extract64(s->strtab_base, 0, 32);
648
- --object tls-creds-x509,id=tls0,endpoint=server,dir=/path/to/qemutls \
438
+ return MEMTX_OK;
649
- --object 'authz-simple,id=auth0,identity=CN=laptop.example.com,,\
439
+ case A_STRTAB_BASE + 4: /* 64b */
650
- O=Example Org,,L=London,,ST=London,,C=GB' \
440
+ *data = extract64(s->strtab_base, 32, 32);
651
- --tls-creds tls0 --tls-authz auth0 \
441
+ return MEMTX_OK;
652
- -t -x subset -p 10810 \
442
+ case A_STRTAB_BASE_CFG:
653
- --image-opts driver=raw,offset=1M,size=1M,file.driver=file,file.filename=file.raw
443
+ *data = s->strtab_base_cfg;
654
-@end example
444
+ return MEMTX_OK;
655
-
445
+ case A_CMDQ_BASE: /* 64b */
656
-Serve a read-only copy of just the first MBR partition of a guest
446
+ *data = extract64(s->cmdq.base, 0, 32);
657
-image over a Unix socket with as many as 5 simultaneous readers, with
447
+ return MEMTX_OK;
658
-a persistent process forked as a daemon:
448
+ case A_CMDQ_BASE + 4:
659
-
449
+ *data = extract64(s->cmdq.base, 32, 32);
660
-@example
450
+ return MEMTX_OK;
661
-qemu-nbd --fork --persistent --shared=5 --socket=/path/to/sock \
451
+ case A_CMDQ_PROD:
662
- --partition=1 --read-only --format=qcow2 file.qcow2
452
+ *data = s->cmdq.prod;
663
-@end example
453
+ return MEMTX_OK;
664
-
454
+ case A_CMDQ_CONS:
665
-Expose the guest-visible contents of a qcow2 file via a block device
455
+ *data = s->cmdq.cons;
666
-/dev/nbd0 (and possibly creating /dev/nbd0p1 and friends for
456
+ return MEMTX_OK;
667
-partitions found within), then disconnect the device when done.
457
+ case A_EVENTQ_BASE: /* 64b */
668
-Access to bind qemu-nbd to an /dev/nbd device generally requires root
458
+ *data = extract64(s->eventq.base, 0, 32);
669
-privileges, and may also require the execution of @code{modprobe nbd}
459
+ return MEMTX_OK;
670
-to enable the kernel NBD client module. @emph{CAUTION}: Do not use
460
+ case A_EVENTQ_BASE + 4: /* 64b */
671
-this method to mount filesystems from an untrusted guest image - a
461
+ *data = extract64(s->eventq.base, 32, 32);
672
-malicious guest may have prepared the image to attempt to trigger
462
+ return MEMTX_OK;
673
-kernel bugs in partition probing or file system mounting.
463
+ case A_EVENTQ_PROD:
674
-
464
+ *data = s->eventq.prod;
675
-@example
465
+ return MEMTX_OK;
676
-qemu-nbd -c /dev/nbd0 -f qcow2 file.qcow2
466
+ case A_EVENTQ_CONS:
677
-qemu-nbd -d /dev/nbd0
467
+ *data = s->eventq.cons;
678
-@end example
468
+ return MEMTX_OK;
679
-
469
+ default:
680
-Query a remote server to see details about what export(s) it is
470
+ *data = 0;
681
-serving on port 10809, and authenticating via PSK:
471
+ qemu_log_mask(LOG_UNIMP,
682
-
472
+ "%s unhandled 32-bit access at 0x%"PRIx64" (RAZ)\n",
683
-@example
473
+ __func__, offset);
684
-qemu-nbd \
474
+ return MEMTX_OK;
685
- --object tls-creds-psk,id=tls0,dir=/tmp/keys,username=eblake,endpoint=client \
475
+ }
686
- --tls-creds tls0 -L -b remote.example.com
476
+}
687
-@end example
477
+
688
-
478
+static MemTxResult smmu_read_mmio(void *opaque, hwaddr offset, uint64_t *data,
689
-@c man end
479
+ unsigned size, MemTxAttrs attrs)
690
-
480
+{
691
-@ignore
481
+ SMMUState *sys = opaque;
692
-
482
+ SMMUv3State *s = ARM_SMMUV3(sys);
693
-@setfilename qemu-nbd
483
+ MemTxResult r;
694
-@settitle QEMU Disk Network Block Device Server
484
+
695
-
485
+ /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */
696
-@c man begin AUTHOR
486
+ offset &= ~0x10000;
697
-Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>.
487
+
698
-This is free software; see the source for copying conditions. There is NO
488
+ switch (size) {
699
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
489
+ case 8:
700
-@c man end
490
+ r = smmu_readll(s, offset, data, attrs);
701
-
491
+ break;
702
-@c man begin SEEALSO
492
+ case 4:
703
-qemu(1), qemu-img(1)
493
+ r = smmu_readl(s, offset, data, attrs);
704
-@c man end
494
+ break;
705
-
495
+ default:
706
-@end ignore
496
+ r = MEMTX_ERROR;
707
diff --git a/qemu-option-trace.texi b/qemu-option-trace.texi
497
+ break;
498
+ }
499
+
500
+ trace_smmuv3_read_mmio(offset, *data, size, r);
501
+ return r;
502
+}
503
+
504
+static const MemoryRegionOps smmu_mem_ops = {
505
+ .read_with_attrs = smmu_read_mmio,
506
+ .write_with_attrs = smmu_write_mmio,
507
+ .endianness = DEVICE_LITTLE_ENDIAN,
508
+ .valid = {
509
+ .min_access_size = 4,
510
+ .max_access_size = 8,
511
+ },
512
+ .impl = {
513
+ .min_access_size = 4,
514
+ .max_access_size = 8,
515
+ },
516
+};
517
+
518
+static void smmu_init_irq(SMMUv3State *s, SysBusDevice *dev)
519
+{
520
+ int i;
521
+
522
+ for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
523
+ sysbus_init_irq(dev, &s->irq[i]);
524
+ }
525
+}
526
+
527
+static void smmu_reset(DeviceState *dev)
528
+{
529
+ SMMUv3State *s = ARM_SMMUV3(dev);
530
+ SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s);
531
+
532
+ c->parent_reset(dev);
533
+
534
+ smmuv3_init_regs(s);
535
+}
536
+
537
+static void smmu_realize(DeviceState *d, Error **errp)
538
+{
539
+ SMMUState *sys = ARM_SMMU(d);
540
+ SMMUv3State *s = ARM_SMMUV3(sys);
541
+ SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s);
542
+ SysBusDevice *dev = SYS_BUS_DEVICE(d);
543
+ Error *local_err = NULL;
544
+
545
+ c->parent_realize(d, &local_err);
546
+ if (local_err) {
547
+ error_propagate(errp, local_err);
548
+ return;
549
+ }
550
+
551
+ memory_region_init_io(&sys->iomem, OBJECT(s),
552
+ &smmu_mem_ops, sys, TYPE_ARM_SMMUV3, 0x20000);
553
+
554
+ sys->mrtypename = TYPE_SMMUV3_IOMMU_MEMORY_REGION;
555
+
556
+ sysbus_init_mmio(dev, &sys->iomem);
557
+
558
+ smmu_init_irq(s, dev);
559
+}
560
+
561
+static const VMStateDescription vmstate_smmuv3_queue = {
562
+ .name = "smmuv3_queue",
563
+ .version_id = 1,
564
+ .minimum_version_id = 1,
565
+ .fields = (VMStateField[]) {
566
+ VMSTATE_UINT64(base, SMMUQueue),
567
+ VMSTATE_UINT32(prod, SMMUQueue),
568
+ VMSTATE_UINT32(cons, SMMUQueue),
569
+ VMSTATE_UINT8(log2size, SMMUQueue),
570
+ },
571
+};
572
+
573
+static const VMStateDescription vmstate_smmuv3 = {
574
+ .name = "smmuv3",
575
+ .version_id = 1,
576
+ .minimum_version_id = 1,
577
+ .fields = (VMStateField[]) {
578
+ VMSTATE_UINT32(features, SMMUv3State),
579
+ VMSTATE_UINT8(sid_size, SMMUv3State),
580
+ VMSTATE_UINT8(sid_split, SMMUv3State),
581
+
582
+ VMSTATE_UINT32_ARRAY(cr, SMMUv3State, 3),
583
+ VMSTATE_UINT32(cr0ack, SMMUv3State),
584
+ VMSTATE_UINT32(statusr, SMMUv3State),
585
+ VMSTATE_UINT32(irq_ctrl, SMMUv3State),
586
+ VMSTATE_UINT32(gerror, SMMUv3State),
587
+ VMSTATE_UINT32(gerrorn, SMMUv3State),
588
+ VMSTATE_UINT64(gerror_irq_cfg0, SMMUv3State),
589
+ VMSTATE_UINT32(gerror_irq_cfg1, SMMUv3State),
590
+ VMSTATE_UINT32(gerror_irq_cfg2, SMMUv3State),
591
+ VMSTATE_UINT64(strtab_base, SMMUv3State),
592
+ VMSTATE_UINT32(strtab_base_cfg, SMMUv3State),
593
+ VMSTATE_UINT64(eventq_irq_cfg0, SMMUv3State),
594
+ VMSTATE_UINT32(eventq_irq_cfg1, SMMUv3State),
595
+ VMSTATE_UINT32(eventq_irq_cfg2, SMMUv3State),
596
+
597
+ VMSTATE_STRUCT(cmdq, SMMUv3State, 0, vmstate_smmuv3_queue, SMMUQueue),
598
+ VMSTATE_STRUCT(eventq, SMMUv3State, 0, vmstate_smmuv3_queue, SMMUQueue),
599
+
600
+ VMSTATE_END_OF_LIST(),
601
+ },
602
+};
603
+
604
+static void smmuv3_instance_init(Object *obj)
605
+{
606
+ /* Nothing much to do here as of now */
607
+}
608
+
609
+static void smmuv3_class_init(ObjectClass *klass, void *data)
610
+{
611
+ DeviceClass *dc = DEVICE_CLASS(klass);
612
+ SMMUv3Class *c = ARM_SMMUV3_CLASS(klass);
613
+
614
+ dc->vmsd = &vmstate_smmuv3;
615
+ device_class_set_parent_reset(dc, smmu_reset, &c->parent_reset);
616
+ c->parent_realize = dc->realize;
617
+ dc->realize = smmu_realize;
618
+}
619
+
620
+static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
621
+ void *data)
622
+{
623
+}
624
+
625
+static const TypeInfo smmuv3_type_info = {
626
+ .name = TYPE_ARM_SMMUV3,
627
+ .parent = TYPE_ARM_SMMU,
628
+ .instance_size = sizeof(SMMUv3State),
629
+ .instance_init = smmuv3_instance_init,
630
+ .class_size = sizeof(SMMUv3Class),
631
+ .class_init = smmuv3_class_init,
632
+};
633
+
634
+static const TypeInfo smmuv3_iommu_memory_region_info = {
635
+ .parent = TYPE_IOMMU_MEMORY_REGION,
636
+ .name = TYPE_SMMUV3_IOMMU_MEMORY_REGION,
637
+ .class_init = smmuv3_iommu_memory_region_class_init,
638
+};
639
+
640
+static void smmuv3_register_types(void)
641
+{
642
+ type_register(&smmuv3_type_info);
643
+ type_register(&smmuv3_iommu_memory_region_info);
644
+}
645
+
646
+type_init(smmuv3_register_types)
647
+
648
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
649
index XXXXXXX..XXXXXXX 100644
708
index XXXXXXX..XXXXXXX 100644
650
--- a/hw/arm/trace-events
709
--- a/qemu-option-trace.texi
651
+++ b/hw/arm/trace-events
710
+++ b/qemu-option-trace.texi
652
@@ -XXX,XX +XXX,XX @@ smmu_ptw_invalid_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr,
711
@@ -XXX,XX +XXX,XX @@
653
smmu_ptw_page_pte(int stage, int level, uint64_t iova, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t address) "stage=%d level=%d iova=0x%"PRIx64" base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" page address = 0x%"PRIx64
712
+@c The contents of this file must be kept in sync with qemu-option-trace.rst.inc
654
smmu_ptw_block_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t iova, uint64_t gpa, int bsize_mb) "stage=%d level=%d base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" iova=0x%"PRIx64" block address = 0x%"PRIx64" block size = %d MiB"
713
+@c until all the users of the texi file have been converted to rst and
655
smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, uint64_t pte) "baseaddr=0x%"PRIx64" index=0x%x, pteaddr=0x%"PRIx64", pte=0x%"PRIx64
714
+@c the texi file can be removed.
656
+
715
+
657
+#hw/arm/smmuv3.c
716
Specify tracing options.
658
+smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
717
718
@table @option
659
--
719
--
660
2.17.0
720
2.20.1
661
721
662
722
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
We want a user-facing manual which contains system emulation
2
documentation. Create an empty one which we can populate.
2
3
3
The patch introduces the smmu base device and class for the ARM
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
smmu. Devices for specific versions will be derived from this
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
base device.
6
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Message-id: 20200116141511.16849-3-peter.maydell@linaro.org
8
---
9
Makefile | 10 +++++++++-
10
docs/index.html.in | 1 +
11
docs/system/conf.py | 15 +++++++++++++++
12
docs/system/index.rst | 16 ++++++++++++++++
13
4 files changed, 41 insertions(+), 1 deletion(-)
14
create mode 100644 docs/system/conf.py
15
create mode 100644 docs/system/index.rst
6
16
7
We also introduce some important datatypes.
17
diff --git a/Makefile b/Makefile
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1524665762-31355-2-git-send-email-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/arm/Makefile.objs | 1 +
16
include/hw/arm/smmu-common.h | 123 ++++++++++++++++++++++++++++
17
hw/arm/smmu-common.c | 81 ++++++++++++++++++
18
default-configs/aarch64-softmmu.mak | 1 +
19
4 files changed, 206 insertions(+)
20
create mode 100644 include/hw/arm/smmu-common.h
21
create mode 100644 hw/arm/smmu-common.c
22
23
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
24
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/Makefile.objs
19
--- a/Makefile
26
+++ b/hw/arm/Makefile.objs
20
+++ b/Makefile
27
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2-tz.o
21
@@ -XXX,XX +XXX,XX @@ distclean: clean
28
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
22
    $(call clean-manual,devel)
29
obj-$(CONFIG_IOTKIT) += iotkit.o
23
    $(call clean-manual,interop)
30
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
24
    $(call clean-manual,specs)
31
+obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o
25
+    $(call clean-manual,system)
32
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
26
    for d in $(TARGET_DIRS); do \
27
    rm -rf $$d || exit 1 ; \
28
done
29
@@ -XXX,XX +XXX,XX @@ endef
30
install-sphinxdocs: sphinxdocs
31
    $(call install-manual,interop)
32
    $(call install-manual,specs)
33
+    $(call install-manual,system)
34
35
install-doc: $(DOCS) install-sphinxdocs
36
    $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
37
@@ -XXX,XX +XXX,XX @@ docs/version.texi: $(SRC_PATH)/VERSION config-host.mak
38
# and handles "don't rebuild things unless necessary" itself.
39
# The '.doctrees' files are cached information to speed this up.
40
.PHONY: sphinxdocs
41
-sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html $(MANUAL_BUILDDIR)/interop/index.html $(MANUAL_BUILDDIR)/specs/index.html
42
+sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html \
43
+ $(MANUAL_BUILDDIR)/interop/index.html \
44
+ $(MANUAL_BUILDDIR)/specs/index.html \
45
+ $(MANUAL_BUILDDIR)/system/index.html
46
47
# Canned command to build a single manual
48
# Arguments: $1 = manual name, $2 = Sphinx builder ('html' or 'man')
49
@@ -XXX,XX +XXX,XX @@ $(MANUAL_BUILDDIR)/interop/index.html: $(call manual-deps,interop)
50
$(MANUAL_BUILDDIR)/specs/index.html: $(call manual-deps,specs)
51
    $(call build-manual,specs,html)
52
53
+$(MANUAL_BUILDDIR)/system/index.html: $(call manual-deps,system)
54
+    $(call build-manual,system,html)
55
+
56
$(MANUAL_BUILDDIR)/interop/qemu-ga.8: $(call manual-deps,interop)
57
    $(call build-manual,interop,man)
58
59
diff --git a/docs/index.html.in b/docs/index.html.in
60
index XXXXXXX..XXXXXXX 100644
61
--- a/docs/index.html.in
62
+++ b/docs/index.html.in
63
@@ -XXX,XX +XXX,XX @@
64
<li><a href="qemu-ga-ref.html">Guest Agent Protocol Reference</a></li>
65
<li><a href="interop/index.html">System Emulation Management and Interoperability Guide</a></li>
66
<li><a href="specs/index.html">System Emulation Guest Hardware Specifications</a></li>
67
+ <li><a href="system/index.html">System Emulation User's Guide</a></li>
68
</ul>
69
</body>
70
</html>
71
diff --git a/docs/system/conf.py b/docs/system/conf.py
33
new file mode 100644
72
new file mode 100644
34
index XXXXXXX..XXXXXXX
73
index XXXXXXX..XXXXXXX
35
--- /dev/null
74
--- /dev/null
36
+++ b/include/hw/arm/smmu-common.h
75
+++ b/docs/system/conf.py
37
@@ -XXX,XX +XXX,XX @@
76
@@ -XXX,XX +XXX,XX @@
38
+/*
77
+# -*- coding: utf-8 -*-
39
+ * ARM SMMU Support
78
+#
40
+ *
79
+# QEMU documentation build configuration file for the 'system' manual.
41
+ * Copyright (C) 2015-2016 Broadcom Corporation
80
+#
42
+ * Copyright (c) 2017 Red Hat, Inc.
81
+# This includes the top level conf file and then makes any necessary tweaks.
43
+ * Written by Prem Mallappa, Eric Auger
82
+import sys
44
+ *
83
+import os
45
+ * This program is free software; you can redistribute it and/or modify
46
+ * it under the terms of the GNU General Public License version 2 as
47
+ * published by the Free Software Foundation.
48
+ *
49
+ * This program is distributed in the hope that it will be useful,
50
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
51
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52
+ * GNU General Public License for more details.
53
+ *
54
+ */
55
+
84
+
56
+#ifndef HW_ARM_SMMU_COMMON_H
85
+qemu_docdir = os.path.abspath("..")
57
+#define HW_ARM_SMMU_COMMON_H
86
+parent_config = os.path.join(qemu_docdir, "conf.py")
87
+exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
58
+
88
+
59
+#include "hw/sysbus.h"
89
+# This slightly misuses the 'description', but is the best way to get
60
+#include "hw/pci/pci.h"
90
+# the manual title to appear in the sidebar.
61
+
91
+html_theme_options['description'] = u'System Emulation User''s Guide'
62
+#define SMMU_PCI_BUS_MAX 256
92
diff --git a/docs/system/index.rst b/docs/system/index.rst
63
+#define SMMU_PCI_DEVFN_MAX 256
64
+
65
+#define SMMU_MAX_VA_BITS 48
66
+
67
+/*
68
+ * Page table walk error types
69
+ */
70
+typedef enum {
71
+ SMMU_PTW_ERR_NONE,
72
+ SMMU_PTW_ERR_WALK_EABT, /* Translation walk external abort */
73
+ SMMU_PTW_ERR_TRANSLATION, /* Translation fault */
74
+ SMMU_PTW_ERR_ADDR_SIZE, /* Address Size fault */
75
+ SMMU_PTW_ERR_ACCESS, /* Access fault */
76
+ SMMU_PTW_ERR_PERMISSION, /* Permission fault */
77
+} SMMUPTWEventType;
78
+
79
+typedef struct SMMUPTWEventInfo {
80
+ SMMUPTWEventType type;
81
+ dma_addr_t addr; /* fetched address that induced an abort, if any */
82
+} SMMUPTWEventInfo;
83
+
84
+typedef struct SMMUTransTableInfo {
85
+ bool disabled; /* is the translation table disabled? */
86
+ uint64_t ttb; /* TT base address */
87
+ uint8_t tsz; /* input range, ie. 2^(64 -tsz)*/
88
+ uint8_t granule_sz; /* granule page shift */
89
+} SMMUTransTableInfo;
90
+
91
+/*
92
+ * Generic structure populated by derived SMMU devices
93
+ * after decoding the configuration information and used as
94
+ * input to the page table walk
95
+ */
96
+typedef struct SMMUTransCfg {
97
+ int stage; /* translation stage */
98
+ bool aa64; /* arch64 or aarch32 translation table */
99
+ bool disabled; /* smmu is disabled */
100
+ bool bypassed; /* translation is bypassed */
101
+ bool aborted; /* translation is aborted */
102
+ uint64_t ttb; /* TT base address */
103
+ uint8_t oas; /* output address width */
104
+ uint8_t tbi; /* Top Byte Ignore */
105
+ uint16_t asid;
106
+ SMMUTransTableInfo tt[2];
107
+} SMMUTransCfg;
108
+
109
+typedef struct SMMUDevice {
110
+ void *smmu;
111
+ PCIBus *bus;
112
+ int devfn;
113
+ IOMMUMemoryRegion iommu;
114
+ AddressSpace as;
115
+} SMMUDevice;
116
+
117
+typedef struct SMMUNotifierNode {
118
+ SMMUDevice *sdev;
119
+ QLIST_ENTRY(SMMUNotifierNode) next;
120
+} SMMUNotifierNode;
121
+
122
+typedef struct SMMUPciBus {
123
+ PCIBus *bus;
124
+ SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
125
+} SMMUPciBus;
126
+
127
+typedef struct SMMUState {
128
+ /* <private> */
129
+ SysBusDevice dev;
130
+ const char *mrtypename;
131
+ MemoryRegion iomem;
132
+
133
+ GHashTable *smmu_pcibus_by_busptr;
134
+ GHashTable *configs; /* cache for configuration data */
135
+ GHashTable *iotlb;
136
+ SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
137
+ PCIBus *pci_bus;
138
+ QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
139
+ uint8_t bus_num;
140
+ PCIBus *primary_bus;
141
+} SMMUState;
142
+
143
+typedef struct {
144
+ /* <private> */
145
+ SysBusDeviceClass parent_class;
146
+
147
+ /*< public >*/
148
+
149
+ DeviceRealize parent_realize;
150
+
151
+} SMMUBaseClass;
152
+
153
+#define TYPE_ARM_SMMU "arm-smmu"
154
+#define ARM_SMMU(obj) OBJECT_CHECK(SMMUState, (obj), TYPE_ARM_SMMU)
155
+#define ARM_SMMU_CLASS(klass) \
156
+ OBJECT_CLASS_CHECK(SMMUBaseClass, (klass), TYPE_ARM_SMMU)
157
+#define ARM_SMMU_GET_CLASS(obj) \
158
+ OBJECT_GET_CLASS(SMMUBaseClass, (obj), TYPE_ARM_SMMU)
159
+
160
+#endif /* HW_ARM_SMMU_COMMON */
161
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
162
new file mode 100644
93
new file mode 100644
163
index XXXXXXX..XXXXXXX
94
index XXXXXXX..XXXXXXX
164
--- /dev/null
95
--- /dev/null
165
+++ b/hw/arm/smmu-common.c
96
+++ b/docs/system/index.rst
166
@@ -XXX,XX +XXX,XX @@
97
@@ -XXX,XX +XXX,XX @@
167
+/*
98
+.. This is the top level page for the 'system' manual.
168
+ * Copyright (C) 2014-2016 Broadcom Corporation
169
+ * Copyright (c) 2017 Red Hat, Inc.
170
+ * Written by Prem Mallappa, Eric Auger
171
+ *
172
+ * This program is free software; you can redistribute it and/or modify
173
+ * it under the terms of the GNU General Public License version 2 as
174
+ * published by the Free Software Foundation.
175
+ *
176
+ * This program is distributed in the hope that it will be useful,
177
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
178
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
179
+ * GNU General Public License for more details.
180
+ *
181
+ * Author: Prem Mallappa <pmallapp@broadcom.com>
182
+ *
183
+ */
184
+
99
+
185
+#include "qemu/osdep.h"
186
+#include "sysemu/sysemu.h"
187
+#include "exec/address-spaces.h"
188
+#include "trace.h"
189
+#include "exec/target_page.h"
190
+#include "qom/cpu.h"
191
+#include "hw/qdev-properties.h"
192
+#include "qapi/error.h"
193
+
100
+
194
+#include "qemu/error-report.h"
101
+QEMU System Emulation User's Guide
195
+#include "hw/arm/smmu-common.h"
102
+==================================
196
+
103
+
197
+static void smmu_base_realize(DeviceState *dev, Error **errp)
104
+This manual is the overall guide for users using QEMU
198
+{
105
+for full system emulation (as opposed to user-mode emulation).
199
+ SMMUBaseClass *sbc = ARM_SMMU_GET_CLASS(dev);
106
+This includes working with hypervisors such as KVM, Xen, Hax
200
+ Error *local_err = NULL;
107
+or Hypervisor.Framework.
201
+
108
+
202
+ sbc->parent_realize(dev, &local_err);
109
+Contents:
203
+ if (local_err) {
204
+ error_propagate(errp, local_err);
205
+ return;
206
+ }
207
+}
208
+
110
+
209
+static void smmu_base_reset(DeviceState *dev)
111
+.. toctree::
210
+{
112
+ :maxdepth: 2
211
+ /* will be filled later on */
212
+}
213
+
113
+
214
+static Property smmu_dev_properties[] = {
215
+ DEFINE_PROP_UINT8("bus_num", SMMUState, bus_num, 0),
216
+ DEFINE_PROP_LINK("primary-bus", SMMUState, primary_bus, "PCI", PCIBus *),
217
+ DEFINE_PROP_END_OF_LIST(),
218
+};
219
+
220
+static void smmu_base_class_init(ObjectClass *klass, void *data)
221
+{
222
+ DeviceClass *dc = DEVICE_CLASS(klass);
223
+ SMMUBaseClass *sbc = ARM_SMMU_CLASS(klass);
224
+
225
+ dc->props = smmu_dev_properties;
226
+ device_class_set_parent_realize(dc, smmu_base_realize,
227
+ &sbc->parent_realize);
228
+ dc->reset = smmu_base_reset;
229
+}
230
+
231
+static const TypeInfo smmu_base_info = {
232
+ .name = TYPE_ARM_SMMU,
233
+ .parent = TYPE_SYS_BUS_DEVICE,
234
+ .instance_size = sizeof(SMMUState),
235
+ .class_data = NULL,
236
+ .class_size = sizeof(SMMUBaseClass),
237
+ .class_init = smmu_base_class_init,
238
+ .abstract = true,
239
+};
240
+
241
+static void smmu_base_register_types(void)
242
+{
243
+ type_register_static(&smmu_base_info);
244
+}
245
+
246
+type_init(smmu_base_register_types)
247
+
248
diff --git a/default-configs/aarch64-softmmu.mak b/default-configs/aarch64-softmmu.mak
249
index XXXXXXX..XXXXXXX 100644
250
--- a/default-configs/aarch64-softmmu.mak
251
+++ b/default-configs/aarch64-softmmu.mak
252
@@ -XXX,XX +XXX,XX @@ CONFIG_DDC=y
253
CONFIG_DPCD=y
254
CONFIG_XLNX_ZYNQMP=y
255
CONFIG_XLNX_ZYNQMP_ARM=y
256
+CONFIG_ARM_SMMUV3=y
257
--
114
--
258
2.17.0
115
2.20.1
259
116
260
117
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
The qemu-block-drivers documentation is currently in
2
docs/qemu-block-drivers.texi in Texinfo format, which we present
3
to the user as:
4
* a qemu-block-drivers manpage
5
* a section of the main qemu-doc HTML documentation
2
6
3
This patch implements the page table walk for VMSAv8-64.
7
Convert the documentation to rST format, and present it to
8
the user as:
9
* a qemu-block-drivers manpage
10
* part of the system/ Sphinx manual
4
11
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
12
This follows the same pattern we've done for qemu-ga and qemu-nbd.
6
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
13
7
Message-id: 1524665762-31355-4-git-send-email-eric.auger@redhat.com
14
We have to drop a cross-reference from the documentation of the
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
-cdrom option back to the qemu-block-drivers documentation, since
16
they're no longer within the same texinfo document.
17
18
As noted in a comment, the manpage output is slightly compromised
19
due to limitations in Sphinx. In an ideal world, the HTML output
20
would have the various headings like 'Disk image file formats'
21
as top-level section headings (which then appear in the overall
22
system manual's table-of-contents), and it would not have the
23
section headings which make sense only for the manpage like
24
'synopsis', 'description', and 'see also'. Unfortunately, the
25
mechanism Sphinx provides for restricting pieces of documentation
26
is limited to the point of being flawed: the 'only::' directive
27
is implemented as a filter that is applied at a very late stage
28
in the document processing pipeline, rather than as an early
29
equivalent of an #ifdef. This means that Sphinx's process of
30
identifying which section heading markup styles are which levels
31
of heading gets confused if the 'only::' directive contains
32
section headings which would affect the heading-level of a
33
later heading. I have opted to prioritise making the HTML format
34
look better, with the compromise being that in the manpage
35
the 'Disk image file formats' &c headings are top-level headings
36
rather than being sub-headings under the traditional 'Description'
37
top-level section title.
38
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
41
Tested-by: Alex Bennée <alex.bennee@linaro.org>
42
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
43
Message-id: 20200116141511.16849-4-peter.maydell@linaro.org
10
---
44
---
11
hw/arm/smmu-internal.h | 99 ++++++++++++++++
45
Makefile | 11 +-
12
include/hw/arm/smmu-common.h | 14 +++
46
docs/qemu-block-drivers.texi | 889 --------------------------
13
hw/arm/smmu-common.c | 222 +++++++++++++++++++++++++++++++++++
47
docs/system/conf.py | 7 +
14
hw/arm/trace-events | 9 +-
48
docs/system/index.rst | 1 +
15
4 files changed, 343 insertions(+), 1 deletion(-)
49
docs/system/qemu-block-drivers.rst | 985 +++++++++++++++++++++++++++++
16
create mode 100644 hw/arm/smmu-internal.h
50
qemu-doc.texi | 12 -
51
qemu-options.hx | 2 +-
52
7 files changed, 1000 insertions(+), 907 deletions(-)
53
delete mode 100644 docs/qemu-block-drivers.texi
54
create mode 100644 docs/system/qemu-block-drivers.rst
17
55
18
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
56
diff --git a/Makefile b/Makefile
57
index XXXXXXX..XXXXXXX 100644
58
--- a/Makefile
59
+++ b/Makefile
60
@@ -XXX,XX +XXX,XX @@ ifdef BUILD_DOCS
61
DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1
62
DOCS+=$(MANUAL_BUILDDIR)/interop/qemu-nbd.8
63
DOCS+=$(MANUAL_BUILDDIR)/interop/qemu-ga.8
64
+DOCS+=$(MANUAL_BUILDDIR)/system/qemu-block-drivers.7
65
DOCS+=docs/interop/qemu-qmp-ref.html docs/interop/qemu-qmp-ref.txt docs/interop/qemu-qmp-ref.7
66
DOCS+=docs/interop/qemu-ga-ref.html docs/interop/qemu-ga-ref.txt docs/interop/qemu-ga-ref.7
67
-DOCS+=docs/qemu-block-drivers.7
68
DOCS+=docs/qemu-cpu-models.7
69
DOCS+=$(MANUAL_BUILDDIR)/index.html
70
ifdef CONFIG_VIRTFS
71
@@ -XXX,XX +XXX,XX @@ distclean: clean
72
    rm -f docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
73
    rm -f docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf
74
    rm -f docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html
75
-    rm -f docs/qemu-block-drivers.7
76
    rm -f docs/qemu-cpu-models.7
77
    rm -rf .doctrees
78
    $(call clean-manual,devel)
79
@@ -XXX,XX +XXX,XX @@ ifdef CONFIG_POSIX
80
    $(INSTALL_DATA) qemu.1 "$(DESTDIR)$(mandir)/man1"
81
    $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man7"
82
    $(INSTALL_DATA) docs/interop/qemu-qmp-ref.7 "$(DESTDIR)$(mandir)/man7"
83
-    $(INSTALL_DATA) docs/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7"
84
+    $(INSTALL_DATA) $(MANUAL_BUILDDIR)/system/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7"
85
    $(INSTALL_DATA) docs/qemu-cpu-models.7 "$(DESTDIR)$(mandir)/man7"
86
ifeq ($(CONFIG_TOOLS),y)
87
    $(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
88
@@ -XXX,XX +XXX,XX @@ $(MANUAL_BUILDDIR)/interop/qemu-ga.8: $(call manual-deps,interop)
89
$(MANUAL_BUILDDIR)/interop/qemu-nbd.8: $(call manual-deps,interop)
90
    $(call build-manual,interop,man)
91
92
+$(MANUAL_BUILDDIR)/system/qemu-block-drivers.7: $(call manual-deps,system)
93
+    $(call build-manual,system,man)
94
+
95
$(MANUAL_BUILDDIR)/index.html: $(SRC_PATH)/docs/index.html.in qemu-version.h
96
    @mkdir -p "$(MANUAL_BUILDDIR)"
97
    $(call quiet-command, sed "s|@@VERSION@@|${VERSION}|g" $< >$@, \
98
@@ -XXX,XX +XXX,XX @@ qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi qemu-monitor-info.texi
99
qemu.1: qemu-option-trace.texi
100
qemu-img.1: qemu-img.texi qemu-option-trace.texi qemu-img-cmds.texi
101
fsdev/virtfs-proxy-helper.1: fsdev/virtfs-proxy-helper.texi
102
-docs/qemu-block-drivers.7: docs/qemu-block-drivers.texi
103
docs/qemu-cpu-models.7: docs/qemu-cpu-models.texi
104
scripts/qemu-trace-stap.1: scripts/qemu-trace-stap.texi
105
106
@@ -XXX,XX +XXX,XX @@ qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \
107
    qemu-img.texi qemu-options.texi \
108
    qemu-tech.texi qemu-option-trace.texi \
109
    qemu-deprecated.texi qemu-monitor.texi qemu-img-cmds.texi \
110
-    qemu-monitor-info.texi docs/qemu-block-drivers.texi \
111
+    qemu-monitor-info.texi \
112
    docs/qemu-cpu-models.texi docs/security.texi
113
114
docs/interop/qemu-ga-ref.dvi docs/interop/qemu-ga-ref.html \
115
diff --git a/docs/qemu-block-drivers.texi b/docs/qemu-block-drivers.texi
116
deleted file mode 100644
117
index XXXXXXX..XXXXXXX
118
--- a/docs/qemu-block-drivers.texi
119
+++ /dev/null
120
@@ -XXX,XX +XXX,XX @@
121
-@c man begin SYNOPSIS
122
-QEMU block driver reference manual
123
-@c man end
124
-
125
-@set qemu_system qemu-system-x86_64
126
-
127
-@c man begin DESCRIPTION
128
-
129
-@node disk_images_formats
130
-@subsection Disk image file formats
131
-
132
-QEMU supports many image file formats that can be used with VMs as well as with
133
-any of the tools (like @code{qemu-img}). This includes the preferred formats
134
-raw and qcow2 as well as formats that are supported for compatibility with
135
-older QEMU versions or other hypervisors.
136
-
137
-Depending on the image format, different options can be passed to
138
-@code{qemu-img create} and @code{qemu-img convert} using the @code{-o} option.
139
-This section describes each format and the options that are supported for it.
140
-
141
-@table @option
142
-@item raw
143
-
144
-Raw disk image format. This format has the advantage of
145
-being simple and easily exportable to all other emulators. If your
146
-file system supports @emph{holes} (for example in ext2 or ext3 on
147
-Linux or NTFS on Windows), then only the written sectors will reserve
148
-space. Use @code{qemu-img info} to know the real size used by the
149
-image or @code{ls -ls} on Unix/Linux.
150
-
151
-Supported options:
152
-@table @code
153
-@item preallocation
154
-Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{full}).
155
-@code{falloc} mode preallocates space for image by calling posix_fallocate().
156
-@code{full} mode preallocates space for image by writing data to underlying
157
-storage. This data may or may not be zero, depending on the storage location.
158
-@end table
159
-
160
-@item qcow2
161
-QEMU image format, the most versatile format. Use it to have smaller
162
-images (useful if your filesystem does not supports holes, for example
163
-on Windows), zlib based compression and support of multiple VM
164
-snapshots.
165
-
166
-Supported options:
167
-@table @code
168
-@item compat
169
-Determines the qcow2 version to use. @code{compat=0.10} uses the
170
-traditional image format that can be read by any QEMU since 0.10.
171
-@code{compat=1.1} enables image format extensions that only QEMU 1.1 and
172
-newer understand (this is the default). Amongst others, this includes
173
-zero clusters, which allow efficient copy-on-read for sparse images.
174
-
175
-@item backing_file
176
-File name of a base image (see @option{create} subcommand)
177
-@item backing_fmt
178
-Image format of the base image
179
-@item encryption
180
-This option is deprecated and equivalent to @code{encrypt.format=aes}
181
-
182
-@item encrypt.format
183
-
184
-If this is set to @code{luks}, it requests that the qcow2 payload (not
185
-qcow2 header) be encrypted using the LUKS format. The passphrase to
186
-use to unlock the LUKS key slot is given by the @code{encrypt.key-secret}
187
-parameter. LUKS encryption parameters can be tuned with the other
188
-@code{encrypt.*} parameters.
189
-
190
-If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
191
-The encryption key is given by the @code{encrypt.key-secret} parameter.
192
-This encryption format is considered to be flawed by modern cryptography
193
-standards, suffering from a number of design problems:
194
-
195
-@itemize @minus
196
-@item The AES-CBC cipher is used with predictable initialization vectors based
197
-on the sector number. This makes it vulnerable to chosen plaintext attacks
198
-which can reveal the existence of encrypted data.
199
-@item The user passphrase is directly used as the encryption key. A poorly
200
-chosen or short passphrase will compromise the security of the encryption.
201
-@item In the event of the passphrase being compromised there is no way to
202
-change the passphrase to protect data in any qcow images. The files must
203
-be cloned, using a different encryption passphrase in the new file. The
204
-original file must then be securely erased using a program like shred,
205
-though even this is ineffective with many modern storage technologies.
206
-@end itemize
207
-
208
-The use of this is no longer supported in system emulators. Support only
209
-remains in the command line utilities, for the purposes of data liberation
210
-and interoperability with old versions of QEMU. The @code{luks} format
211
-should be used instead.
212
-
213
-@item encrypt.key-secret
214
-
215
-Provides the ID of a @code{secret} object that contains the passphrase
216
-(@code{encrypt.format=luks}) or encryption key (@code{encrypt.format=aes}).
217
-
218
-@item encrypt.cipher-alg
219
-
220
-Name of the cipher algorithm and key length. Currently defaults
221
-to @code{aes-256}. Only used when @code{encrypt.format=luks}.
222
-
223
-@item encrypt.cipher-mode
224
-
225
-Name of the encryption mode to use. Currently defaults to @code{xts}.
226
-Only used when @code{encrypt.format=luks}.
227
-
228
-@item encrypt.ivgen-alg
229
-
230
-Name of the initialization vector generator algorithm. Currently defaults
231
-to @code{plain64}. Only used when @code{encrypt.format=luks}.
232
-
233
-@item encrypt.ivgen-hash-alg
234
-
235
-Name of the hash algorithm to use with the initialization vector generator
236
-(if required). Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
237
-
238
-@item encrypt.hash-alg
239
-
240
-Name of the hash algorithm to use for PBKDF algorithm
241
-Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
242
-
243
-@item encrypt.iter-time
244
-
245
-Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
246
-Defaults to @code{2000}. Only used when @code{encrypt.format=luks}.
247
-
248
-@item cluster_size
249
-Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster
250
-sizes can improve the image file size whereas larger cluster sizes generally
251
-provide better performance.
252
-
253
-@item preallocation
254
-Preallocation mode (allowed values: @code{off}, @code{metadata}, @code{falloc},
255
-@code{full}). An image with preallocated metadata is initially larger but can
256
-improve performance when the image needs to grow. @code{falloc} and @code{full}
257
-preallocations are like the same options of @code{raw} format, but sets up
258
-metadata also.
259
-
260
-@item lazy_refcounts
261
-If this option is set to @code{on}, reference count updates are postponed with
262
-the goal of avoiding metadata I/O and improving performance. This is
263
-particularly interesting with @option{cache=writethrough} which doesn't batch
264
-metadata updates. The tradeoff is that after a host crash, the reference count
265
-tables must be rebuilt, i.e. on the next open an (automatic) @code{qemu-img
266
-check -r all} is required, which may take some time.
267
-
268
-This option can only be enabled if @code{compat=1.1} is specified.
269
-
270
-@item nocow
271
-If this option is set to @code{on}, it will turn off COW of the file. It's only
272
-valid on btrfs, no effect on other file systems.
273
-
274
-Btrfs has low performance when hosting a VM image file, even more when the guest
275
-on the VM also using btrfs as file system. Turning off COW is a way to mitigate
276
-this bad performance. Generally there are two ways to turn off COW on btrfs:
277
-a) Disable it by mounting with nodatacow, then all newly created files will be
278
-NOCOW. b) For an empty file, add the NOCOW file attribute. That's what this option
279
-does.
280
-
281
-Note: this option is only valid to new or empty files. If there is an existing
282
-file which is COW and has data blocks already, it couldn't be changed to NOCOW
283
-by setting @code{nocow=on}. One can issue @code{lsattr filename} to check if
284
-the NOCOW flag is set or not (Capital 'C' is NOCOW flag).
285
-
286
-@end table
287
-
288
-@item qed
289
-Old QEMU image format with support for backing files and compact image files
290
-(when your filesystem or transport medium does not support holes).
291
-
292
-When converting QED images to qcow2, you might want to consider using the
293
-@code{lazy_refcounts=on} option to get a more QED-like behaviour.
294
-
295
-Supported options:
296
-@table @code
297
-@item backing_file
298
-File name of a base image (see @option{create} subcommand).
299
-@item backing_fmt
300
-Image file format of backing file (optional). Useful if the format cannot be
301
-autodetected because it has no header, like some vhd/vpc files.
302
-@item cluster_size
303
-Changes the cluster size (must be power-of-2 between 4K and 64K). Smaller
304
-cluster sizes can improve the image file size whereas larger cluster sizes
305
-generally provide better performance.
306
-@item table_size
307
-Changes the number of clusters per L1/L2 table (must be power-of-2 between 1
308
-and 16). There is normally no need to change this value but this option can be
309
-used for performance benchmarking.
310
-@end table
311
-
312
-@item qcow
313
-Old QEMU image format with support for backing files, compact image files,
314
-encryption and compression.
315
-
316
-Supported options:
317
-@table @code
318
-@item backing_file
319
-File name of a base image (see @option{create} subcommand)
320
-@item encryption
321
-This option is deprecated and equivalent to @code{encrypt.format=aes}
322
-
323
-@item encrypt.format
324
-If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
325
-The encryption key is given by the @code{encrypt.key-secret} parameter.
326
-This encryption format is considered to be flawed by modern cryptography
327
-standards, suffering from a number of design problems enumerated previously
328
-against the @code{qcow2} image format.
329
-
330
-The use of this is no longer supported in system emulators. Support only
331
-remains in the command line utilities, for the purposes of data liberation
332
-and interoperability with old versions of QEMU.
333
-
334
-Users requiring native encryption should use the @code{qcow2} format
335
-instead with @code{encrypt.format=luks}.
336
-
337
-@item encrypt.key-secret
338
-
339
-Provides the ID of a @code{secret} object that contains the encryption
340
-key (@code{encrypt.format=aes}).
341
-
342
-@end table
343
-
344
-@item luks
345
-
346
-LUKS v1 encryption format, compatible with Linux dm-crypt/cryptsetup
347
-
348
-Supported options:
349
-@table @code
350
-
351
-@item key-secret
352
-
353
-Provides the ID of a @code{secret} object that contains the passphrase.
354
-
355
-@item cipher-alg
356
-
357
-Name of the cipher algorithm and key length. Currently defaults
358
-to @code{aes-256}.
359
-
360
-@item cipher-mode
361
-
362
-Name of the encryption mode to use. Currently defaults to @code{xts}.
363
-
364
-@item ivgen-alg
365
-
366
-Name of the initialization vector generator algorithm. Currently defaults
367
-to @code{plain64}.
368
-
369
-@item ivgen-hash-alg
370
-
371
-Name of the hash algorithm to use with the initialization vector generator
372
-(if required). Defaults to @code{sha256}.
373
-
374
-@item hash-alg
375
-
376
-Name of the hash algorithm to use for PBKDF algorithm
377
-Defaults to @code{sha256}.
378
-
379
-@item iter-time
380
-
381
-Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
382
-Defaults to @code{2000}.
383
-
384
-@end table
385
-
386
-@item vdi
387
-VirtualBox 1.1 compatible image format.
388
-Supported options:
389
-@table @code
390
-@item static
391
-If this option is set to @code{on}, the image is created with metadata
392
-preallocation.
393
-@end table
394
-
395
-@item vmdk
396
-VMware 3 and 4 compatible image format.
397
-
398
-Supported options:
399
-@table @code
400
-@item backing_file
401
-File name of a base image (see @option{create} subcommand).
402
-@item compat6
403
-Create a VMDK version 6 image (instead of version 4)
404
-@item hwversion
405
-Specify vmdk virtual hardware version. Compat6 flag cannot be enabled
406
-if hwversion is specified.
407
-@item subformat
408
-Specifies which VMDK subformat to use. Valid options are
409
-@code{monolithicSparse} (default),
410
-@code{monolithicFlat},
411
-@code{twoGbMaxExtentSparse},
412
-@code{twoGbMaxExtentFlat} and
413
-@code{streamOptimized}.
414
-@end table
415
-
416
-@item vpc
417
-VirtualPC compatible image format (VHD).
418
-Supported options:
419
-@table @code
420
-@item subformat
421
-Specifies which VHD subformat to use. Valid options are
422
-@code{dynamic} (default) and @code{fixed}.
423
-@end table
424
-
425
-@item VHDX
426
-Hyper-V compatible image format (VHDX).
427
-Supported options:
428
-@table @code
429
-@item subformat
430
-Specifies which VHDX subformat to use. Valid options are
431
-@code{dynamic} (default) and @code{fixed}.
432
-@item block_state_zero
433
-Force use of payload blocks of type 'ZERO'. Can be set to @code{on} (default)
434
-or @code{off}. When set to @code{off}, new blocks will be created as
435
-@code{PAYLOAD_BLOCK_NOT_PRESENT}, which means parsers are free to return
436
-arbitrary data for those blocks. Do not set to @code{off} when using
437
-@code{qemu-img convert} with @code{subformat=dynamic}.
438
-@item block_size
439
-Block size; min 1 MB, max 256 MB. 0 means auto-calculate based on image size.
440
-@item log_size
441
-Log size; min 1 MB.
442
-@end table
443
-@end table
444
-
445
-@subsubsection Read-only formats
446
-More disk image file formats are supported in a read-only mode.
447
-@table @option
448
-@item bochs
449
-Bochs images of @code{growing} type.
450
-@item cloop
451
-Linux Compressed Loop image, useful only to reuse directly compressed
452
-CD-ROM images present for example in the Knoppix CD-ROMs.
453
-@item dmg
454
-Apple disk image.
455
-@item parallels
456
-Parallels disk image format.
457
-@end table
458
-
459
-
460
-@node host_drives
461
-@subsection Using host drives
462
-
463
-In addition to disk image files, QEMU can directly access host
464
-devices. We describe here the usage for QEMU version >= 0.8.3.
465
-
466
-@subsubsection Linux
467
-
468
-On Linux, you can directly use the host device filename instead of a
469
-disk image filename provided you have enough privileges to access
470
-it. For example, use @file{/dev/cdrom} to access to the CDROM.
471
-
472
-@table @code
473
-@item CD
474
-You can specify a CDROM device even if no CDROM is loaded. QEMU has
475
-specific code to detect CDROM insertion or removal. CDROM ejection by
476
-the guest OS is supported. Currently only data CDs are supported.
477
-@item Floppy
478
-You can specify a floppy device even if no floppy is loaded. Floppy
479
-removal is currently not detected accurately (if you change floppy
480
-without doing floppy access while the floppy is not loaded, the guest
481
-OS will think that the same floppy is loaded).
482
-Use of the host's floppy device is deprecated, and support for it will
483
-be removed in a future release.
484
-@item Hard disks
485
-Hard disks can be used. Normally you must specify the whole disk
486
-(@file{/dev/hdb} instead of @file{/dev/hdb1}) so that the guest OS can
487
-see it as a partitioned disk. WARNING: unless you know what you do, it
488
-is better to only make READ-ONLY accesses to the hard disk otherwise
489
-you may corrupt your host data (use the @option{-snapshot} command
490
-line option or modify the device permissions accordingly).
491
-@end table
492
-
493
-@subsubsection Windows
494
-
495
-@table @code
496
-@item CD
497
-The preferred syntax is the drive letter (e.g. @file{d:}). The
498
-alternate syntax @file{\\.\d:} is supported. @file{/dev/cdrom} is
499
-supported as an alias to the first CDROM drive.
500
-
501
-Currently there is no specific code to handle removable media, so it
502
-is better to use the @code{change} or @code{eject} monitor commands to
503
-change or eject media.
504
-@item Hard disks
505
-Hard disks can be used with the syntax: @file{\\.\PhysicalDrive@var{N}}
506
-where @var{N} is the drive number (0 is the first hard disk).
507
-
508
-WARNING: unless you know what you do, it is better to only make
509
-READ-ONLY accesses to the hard disk otherwise you may corrupt your
510
-host data (use the @option{-snapshot} command line so that the
511
-modifications are written in a temporary file).
512
-@end table
513
-
514
-
515
-@subsubsection Mac OS X
516
-
517
-@file{/dev/cdrom} is an alias to the first CDROM.
518
-
519
-Currently there is no specific code to handle removable media, so it
520
-is better to use the @code{change} or @code{eject} monitor commands to
521
-change or eject media.
522
-
523
-@node disk_images_fat_images
524
-@subsection Virtual FAT disk images
525
-
526
-QEMU can automatically create a virtual FAT disk image from a
527
-directory tree. In order to use it, just type:
528
-
529
-@example
530
-@value{qemu_system} linux.img -hdb fat:/my_directory
531
-@end example
532
-
533
-Then you access access to all the files in the @file{/my_directory}
534
-directory without having to copy them in a disk image or to export
535
-them via SAMBA or NFS. The default access is @emph{read-only}.
536
-
537
-Floppies can be emulated with the @code{:floppy:} option:
538
-
539
-@example
540
-@value{qemu_system} linux.img -fda fat:floppy:/my_directory
541
-@end example
542
-
543
-A read/write support is available for testing (beta stage) with the
544
-@code{:rw:} option:
545
-
546
-@example
547
-@value{qemu_system} linux.img -fda fat:floppy:rw:/my_directory
548
-@end example
549
-
550
-What you should @emph{never} do:
551
-@itemize
552
-@item use non-ASCII filenames ;
553
-@item use "-snapshot" together with ":rw:" ;
554
-@item expect it to work when loadvm'ing ;
555
-@item write to the FAT directory on the host system while accessing it with the guest system.
556
-@end itemize
557
-
558
-@node disk_images_nbd
559
-@subsection NBD access
560
-
561
-QEMU can access directly to block device exported using the Network Block Device
562
-protocol.
563
-
564
-@example
565
-@value{qemu_system} linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
566
-@end example
567
-
568
-If the NBD server is located on the same host, you can use an unix socket instead
569
-of an inet socket:
570
-
571
-@example
572
-@value{qemu_system} linux.img -hdb nbd+unix://?socket=/tmp/my_socket
573
-@end example
574
-
575
-In this case, the block device must be exported using qemu-nbd:
576
-
577
-@example
578
-qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
579
-@end example
580
-
581
-The use of qemu-nbd allows sharing of a disk between several guests:
582
-@example
583
-qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
584
-@end example
585
-
586
-@noindent
587
-and then you can use it with two guests:
588
-@example
589
-@value{qemu_system} linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
590
-@value{qemu_system} linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
591
-@end example
592
-
593
-If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
594
-own embedded NBD server), you must specify an export name in the URI:
595
-@example
596
-@value{qemu_system} -cdrom nbd://localhost/debian-500-ppc-netinst
597
-@value{qemu_system} -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
598
-@end example
599
-
600
-The URI syntax for NBD is supported since QEMU 1.3. An alternative syntax is
601
-also available. Here are some example of the older syntax:
602
-@example
603
-@value{qemu_system} linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
604
-@value{qemu_system} linux2.img -hdb nbd:unix:/tmp/my_socket
605
-@value{qemu_system} -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
606
-@end example
607
-
608
-@node disk_images_sheepdog
609
-@subsection Sheepdog disk images
610
-
611
-Sheepdog is a distributed storage system for QEMU. It provides highly
612
-available block level storage volumes that can be attached to
613
-QEMU-based virtual machines.
614
-
615
-You can create a Sheepdog disk image with the command:
616
-@example
617
-qemu-img create sheepdog:///@var{image} @var{size}
618
-@end example
619
-where @var{image} is the Sheepdog image name and @var{size} is its
620
-size.
621
-
622
-To import the existing @var{filename} to Sheepdog, you can use a
623
-convert command.
624
-@example
625
-qemu-img convert @var{filename} sheepdog:///@var{image}
626
-@end example
627
-
628
-You can boot from the Sheepdog disk image with the command:
629
-@example
630
-@value{qemu_system} sheepdog:///@var{image}
631
-@end example
632
-
633
-You can also create a snapshot of the Sheepdog image like qcow2.
634
-@example
635
-qemu-img snapshot -c @var{tag} sheepdog:///@var{image}
636
-@end example
637
-where @var{tag} is a tag name of the newly created snapshot.
638
-
639
-To boot from the Sheepdog snapshot, specify the tag name of the
640
-snapshot.
641
-@example
642
-@value{qemu_system} sheepdog:///@var{image}#@var{tag}
643
-@end example
644
-
645
-You can create a cloned image from the existing snapshot.
646
-@example
647
-qemu-img create -b sheepdog:///@var{base}#@var{tag} sheepdog:///@var{image}
648
-@end example
649
-where @var{base} is an image name of the source snapshot and @var{tag}
650
-is its tag name.
651
-
652
-You can use an unix socket instead of an inet socket:
653
-
654
-@example
655
-@value{qemu_system} sheepdog+unix:///@var{image}?socket=@var{path}
656
-@end example
657
-
658
-If the Sheepdog daemon doesn't run on the local host, you need to
659
-specify one of the Sheepdog servers to connect to.
660
-@example
661
-qemu-img create sheepdog://@var{hostname}:@var{port}/@var{image} @var{size}
662
-@value{qemu_system} sheepdog://@var{hostname}:@var{port}/@var{image}
663
-@end example
664
-
665
-@node disk_images_iscsi
666
-@subsection iSCSI LUNs
667
-
668
-iSCSI is a popular protocol used to access SCSI devices across a computer
669
-network.
670
-
671
-There are two different ways iSCSI devices can be used by QEMU.
672
-
673
-The first method is to mount the iSCSI LUN on the host, and make it appear as
674
-any other ordinary SCSI device on the host and then to access this device as a
675
-/dev/sd device from QEMU. How to do this differs between host OSes.
676
-
677
-The second method involves using the iSCSI initiator that is built into
678
-QEMU. This provides a mechanism that works the same way regardless of which
679
-host OS you are running QEMU on. This section will describe this second method
680
-of using iSCSI together with QEMU.
681
-
682
-In QEMU, iSCSI devices are described using special iSCSI URLs
683
-
684
-@example
685
-URL syntax:
686
-iscsi://[<username>[%<password>]@@]<host>[:<port>]/<target-iqn-name>/<lun>
687
-@end example
688
-
689
-Username and password are optional and only used if your target is set up
690
-using CHAP authentication for access control.
691
-Alternatively the username and password can also be set via environment
692
-variables to have these not show up in the process list
693
-
694
-@example
695
-export LIBISCSI_CHAP_USERNAME=<username>
696
-export LIBISCSI_CHAP_PASSWORD=<password>
697
-iscsi://<host>/<target-iqn-name>/<lun>
698
-@end example
699
-
700
-Various session related parameters can be set via special options, either
701
-in a configuration file provided via '-readconfig' or directly on the
702
-command line.
703
-
704
-If the initiator-name is not specified qemu will use a default name
705
-of 'iqn.2008-11.org.linux-kvm[:<uuid>'] where <uuid> is the UUID of the
706
-virtual machine. If the UUID is not specified qemu will use
707
-'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
708
-virtual machine.
709
-
710
-@example
711
-Setting a specific initiator name to use when logging in to the target
712
--iscsi initiator-name=iqn.qemu.test:my-initiator
713
-@end example
714
-
715
-@example
716
-Controlling which type of header digest to negotiate with the target
717
--iscsi header-digest=CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
718
-@end example
719
-
720
-These can also be set via a configuration file
721
-@example
722
-[iscsi]
723
- user = "CHAP username"
724
- password = "CHAP password"
725
- initiator-name = "iqn.qemu.test:my-initiator"
726
- # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
727
- header-digest = "CRC32C"
728
-@end example
729
-
730
-
731
-Setting the target name allows different options for different targets
732
-@example
733
-[iscsi "iqn.target.name"]
734
- user = "CHAP username"
735
- password = "CHAP password"
736
- initiator-name = "iqn.qemu.test:my-initiator"
737
- # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
738
- header-digest = "CRC32C"
739
-@end example
740
-
741
-
742
-Howto use a configuration file to set iSCSI configuration options:
743
-@example
744
-cat >iscsi.conf <<EOF
745
-[iscsi]
746
- user = "me"
747
- password = "my password"
748
- initiator-name = "iqn.qemu.test:my-initiator"
749
- header-digest = "CRC32C"
750
-EOF
751
-
752
-@value{qemu_system} -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
753
- -readconfig iscsi.conf
754
-@end example
755
-
756
-
757
-How to set up a simple iSCSI target on loopback and access it via QEMU:
758
-@example
759
-This example shows how to set up an iSCSI target with one CDROM and one DISK
760
-using the Linux STGT software target. This target is available on Red Hat based
761
-systems as the package 'scsi-target-utils'.
762
-
763
-tgtd --iscsi portal=127.0.0.1:3260
764
-tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.qemu.test
765
-tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 \
766
- -b /IMAGES/disk.img --device-type=disk
767
-tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \
768
- -b /IMAGES/cd.iso --device-type=cd
769
-tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
770
-
771
-@value{qemu_system} -iscsi initiator-name=iqn.qemu.test:my-initiator \
772
- -boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
773
- -cdrom iscsi://127.0.0.1/iqn.qemu.test/2
774
-@end example
775
-
776
-@node disk_images_gluster
777
-@subsection GlusterFS disk images
778
-
779
-GlusterFS is a user space distributed file system.
780
-
781
-You can boot from the GlusterFS disk image with the command:
782
-@example
783
-URI:
784
-@value{qemu_system} -drive file=gluster[+@var{type}]://[@var{host}[:@var{port}]]/@var{volume}/@var{path}
785
- [?socket=...][,file.debug=9][,file.logfile=...]
786
-
787
-JSON:
788
-@value{qemu_system} 'json:@{"driver":"qcow2",
789
- "file":@{"driver":"gluster",
790
- "volume":"testvol","path":"a.img","debug":9,"logfile":"...",
791
- "server":[@{"type":"tcp","host":"...","port":"..."@},
792
- @{"type":"unix","socket":"..."@}]@}@}'
793
-@end example
794
-
795
-@var{gluster} is the protocol.
796
-
797
-@var{type} specifies the transport type used to connect to gluster
798
-management daemon (glusterd). Valid transport types are
799
-tcp and unix. In the URI form, if a transport type isn't specified,
800
-then tcp type is assumed.
801
-
802
-@var{host} specifies the server where the volume file specification for
803
-the given volume resides. This can be either a hostname or an ipv4 address.
804
-If transport type is unix, then @var{host} field should not be specified.
805
-Instead @var{socket} field needs to be populated with the path to unix domain
806
-socket.
807
-
808
-@var{port} is the port number on which glusterd is listening. This is optional
809
-and if not specified, it defaults to port 24007. If the transport type is unix,
810
-then @var{port} should not be specified.
811
-
812
-@var{volume} is the name of the gluster volume which contains the disk image.
813
-
814
-@var{path} is the path to the actual disk image that resides on gluster volume.
815
-
816
-@var{debug} is the logging level of the gluster protocol driver. Debug levels
817
-are 0-9, with 9 being the most verbose, and 0 representing no debugging output.
818
-The default level is 4. The current logging levels defined in the gluster source
819
-are 0 - None, 1 - Emergency, 2 - Alert, 3 - Critical, 4 - Error, 5 - Warning,
820
-6 - Notice, 7 - Info, 8 - Debug, 9 - Trace
821
-
822
-@var{logfile} is a commandline option to mention log file path which helps in
823
-logging to the specified file and also help in persisting the gfapi logs. The
824
-default is stderr.
825
-
826
-
827
-
828
-
829
-You can create a GlusterFS disk image with the command:
830
-@example
831
-qemu-img create gluster://@var{host}/@var{volume}/@var{path} @var{size}
832
-@end example
833
-
834
-Examples
835
-@example
836
-@value{qemu_system} -drive file=gluster://1.2.3.4/testvol/a.img
837
-@value{qemu_system} -drive file=gluster+tcp://1.2.3.4/testvol/a.img
838
-@value{qemu_system} -drive file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
839
-@value{qemu_system} -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
840
-@value{qemu_system} -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
841
-@value{qemu_system} -drive file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
842
-@value{qemu_system} -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
843
-@value{qemu_system} -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
844
-@value{qemu_system} -drive file=gluster://1.2.3.4/testvol/a.img,file.debug=9,file.logfile=/var/log/qemu-gluster.log
845
-@value{qemu_system} 'json:@{"driver":"qcow2",
846
- "file":@{"driver":"gluster",
847
- "volume":"testvol","path":"a.img",
848
- "debug":9,"logfile":"/var/log/qemu-gluster.log",
849
- "server":[@{"type":"tcp","host":"1.2.3.4","port":24007@},
850
- @{"type":"unix","socket":"/var/run/glusterd.socket"@}]@}@}'
851
-@value{qemu_system} -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
852
- file.debug=9,file.logfile=/var/log/qemu-gluster.log,
853
- file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
854
- file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
855
-@end example
856
-
857
-@node disk_images_ssh
858
-@subsection Secure Shell (ssh) disk images
859
-
860
-You can access disk images located on a remote ssh server
861
-by using the ssh protocol:
862
-
863
-@example
864
-@value{qemu_system} -drive file=ssh://[@var{user}@@]@var{server}[:@var{port}]/@var{path}[?host_key_check=@var{host_key_check}]
865
-@end example
866
-
867
-Alternative syntax using properties:
868
-
869
-@example
870
-@value{qemu_system} -drive file.driver=ssh[,file.user=@var{user}],file.host=@var{server}[,file.port=@var{port}],file.path=@var{path}[,file.host_key_check=@var{host_key_check}]
871
-@end example
872
-
873
-@var{ssh} is the protocol.
874
-
875
-@var{user} is the remote user. If not specified, then the local
876
-username is tried.
877
-
878
-@var{server} specifies the remote ssh server. Any ssh server can be
879
-used, but it must implement the sftp-server protocol. Most Unix/Linux
880
-systems should work without requiring any extra configuration.
881
-
882
-@var{port} is the port number on which sshd is listening. By default
883
-the standard ssh port (22) is used.
884
-
885
-@var{path} is the path to the disk image.
886
-
887
-The optional @var{host_key_check} parameter controls how the remote
888
-host's key is checked. The default is @code{yes} which means to use
889
-the local @file{.ssh/known_hosts} file. Setting this to @code{no}
890
-turns off known-hosts checking. Or you can check that the host key
891
-matches a specific fingerprint:
892
-@code{host_key_check=md5:78:45:8e:14:57:4f:d5:45:83:0a:0e:f3:49:82:c9:c8}
893
-(@code{sha1:} can also be used as a prefix, but note that OpenSSH
894
-tools only use MD5 to print fingerprints).
895
-
896
-Currently authentication must be done using ssh-agent. Other
897
-authentication methods may be supported in future.
898
-
899
-Note: Many ssh servers do not support an @code{fsync}-style operation.
900
-The ssh driver cannot guarantee that disk flush requests are
901
-obeyed, and this causes a risk of disk corruption if the remote
902
-server or network goes down during writes. The driver will
903
-print a warning when @code{fsync} is not supported:
904
-
905
-warning: ssh server @code{ssh.example.com:22} does not support fsync
906
-
907
-With sufficiently new versions of libssh and OpenSSH, @code{fsync} is
908
-supported.
909
-
910
-@node disk_images_nvme
911
-@subsection NVMe disk images
912
-
913
-NVM Express (NVMe) storage controllers can be accessed directly by a userspace
914
-driver in QEMU. This bypasses the host kernel file system and block layers
915
-while retaining QEMU block layer functionalities, such as block jobs, I/O
916
-throttling, image formats, etc. Disk I/O performance is typically higher than
917
-with @code{-drive file=/dev/sda} using either thread pool or linux-aio.
918
-
919
-The controller will be exclusively used by the QEMU process once started. To be
920
-able to share storage between multiple VMs and other applications on the host,
921
-please use the file based protocols.
922
-
923
-Before starting QEMU, bind the host NVMe controller to the host vfio-pci
924
-driver. For example:
925
-
926
-@example
927
-# modprobe vfio-pci
928
-# lspci -n -s 0000:06:0d.0
929
-06:0d.0 0401: 1102:0002 (rev 08)
930
-# echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
931
-# echo 1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
932
-
933
-# @value{qemu_system} -drive file=nvme://@var{host}:@var{bus}:@var{slot}.@var{func}/@var{namespace}
934
-@end example
935
-
936
-Alternative syntax using properties:
937
-
938
-@example
939
-@value{qemu_system} -drive file.driver=nvme,file.device=@var{host}:@var{bus}:@var{slot}.@var{func},file.namespace=@var{namespace}
940
-@end example
941
-
942
-@var{host}:@var{bus}:@var{slot}.@var{func} is the NVMe controller's PCI device
943
-address on the host.
944
-
945
-@var{namespace} is the NVMe namespace number, starting from 1.
946
-
947
-@node disk_image_locking
948
-@subsection Disk image file locking
949
-
950
-By default, QEMU tries to protect image files from unexpected concurrent
951
-access, as long as it's supported by the block protocol driver and host
952
-operating system. If multiple QEMU processes (including QEMU emulators and
953
-utilities) try to open the same image with conflicting accessing modes, all but
954
-the first one will get an error.
955
-
956
-This feature is currently supported by the file protocol on Linux with the Open
957
-File Descriptor (OFD) locking API, and can be configured to fall back to POSIX
958
-locking if the POSIX host doesn't support Linux OFD locking.
959
-
960
-To explicitly enable image locking, specify "locking=on" in the file protocol
961
-driver options. If OFD locking is not possible, a warning will be printed and
962
-the POSIX locking API will be used. In this case there is a risk that the lock
963
-will get silently lost when doing hot plugging and block jobs, due to the
964
-shortcomings of the POSIX locking API.
965
-
966
-QEMU transparently handles lock handover during shared storage migration. For
967
-shared virtual disk images between multiple VMs, the "share-rw" device option
968
-should be used.
969
-
970
-By default, the guest has exclusive write access to its disk image. If the
971
-guest can safely share the disk image with other writers the @code{-device
972
-...,share-rw=on} parameter can be used. This is only safe if the guest is
973
-running software, such as a cluster file system, that coordinates disk accesses
974
-to avoid corruption.
975
-
976
-Note that share-rw=on only declares the guest's ability to share the disk.
977
-Some QEMU features, such as image file formats, require exclusive write access
978
-to the disk image and this is unaffected by the share-rw=on option.
979
-
980
-Alternatively, locking can be fully disabled by "locking=off" block device
981
-option. In the command line, the option is usually in the form of
982
-"file.locking=off" as the protocol driver is normally placed as a "file" child
983
-under a format driver. For example:
984
-
985
-@code{-blockdev driver=qcow2,file.filename=/path/to/image,file.locking=off,file.driver=file}
986
-
987
-To check if image locking is active, check the output of the "lslocks" command
988
-on host and see if there are locks held by the QEMU process on the image file.
989
-More than one byte could be locked by the QEMU instance, each byte of which
990
-reflects a particular permission that is acquired or protected by the running
991
-block driver.
992
-
993
-@c man end
994
-
995
-@ignore
996
-
997
-@setfilename qemu-block-drivers
998
-@settitle QEMU block drivers reference
999
-
1000
-@c man begin SEEALSO
1001
-The HTML documentation of QEMU for more precise information and Linux
1002
-user mode emulator invocation.
1003
-@c man end
1004
-
1005
-@c man begin AUTHOR
1006
-Fabrice Bellard and the QEMU Project developers
1007
-@c man end
1008
-
1009
-@end ignore
1010
diff --git a/docs/system/conf.py b/docs/system/conf.py
1011
index XXXXXXX..XXXXXXX 100644
1012
--- a/docs/system/conf.py
1013
+++ b/docs/system/conf.py
1014
@@ -XXX,XX +XXX,XX @@ exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
1015
# This slightly misuses the 'description', but is the best way to get
1016
# the manual title to appear in the sidebar.
1017
html_theme_options['description'] = u'System Emulation User''s Guide'
1018
+# One entry per manual page. List of tuples
1019
+# (source start file, name, description, authors, manual section).
1020
+man_pages = [
1021
+ ('qemu-block-drivers', 'qemu-block-drivers',
1022
+ u'QEMU block drivers reference',
1023
+ ['Fabrice Bellard and the QEMU Project developers'], 7)
1024
+]
1025
diff --git a/docs/system/index.rst b/docs/system/index.rst
1026
index XXXXXXX..XXXXXXX 100644
1027
--- a/docs/system/index.rst
1028
+++ b/docs/system/index.rst
1029
@@ -XXX,XX +XXX,XX @@ Contents:
1030
.. toctree::
1031
:maxdepth: 2
1032
1033
+ qemu-block-drivers
1034
diff --git a/docs/system/qemu-block-drivers.rst b/docs/system/qemu-block-drivers.rst
19
new file mode 100644
1035
new file mode 100644
20
index XXXXXXX..XXXXXXX
1036
index XXXXXXX..XXXXXXX
21
--- /dev/null
1037
--- /dev/null
22
+++ b/hw/arm/smmu-internal.h
1038
+++ b/docs/system/qemu-block-drivers.rst
23
@@ -XXX,XX +XXX,XX @@
1039
@@ -XXX,XX +XXX,XX @@
24
+/*
1040
+QEMU block drivers reference
25
+ * ARM SMMU support - Internal API
1041
+============================
26
+ *
1042
+
27
+ * Copyright (c) 2017 Red Hat, Inc.
1043
+.. |qemu_system| replace:: qemu-system-x86_64
28
+ * Copyright (C) 2014-2016 Broadcom Corporation
1044
+
29
+ * Written by Prem Mallappa, Eric Auger
1045
+..
30
+ *
1046
+ We put the 'Synopsis' and 'See also' sections into the manpage, but not
31
+ * This program is free software; you can redistribute it and/or modify
1047
+ the HTML. This makes the HTML docs read better and means the ToC in
32
+ * it under the terms of the GNU General Public License version 2 as
1048
+ the index has a more useful set of entries. Ideally, the section
33
+ * published by the Free Software Foundation.
1049
+ headings 'Disk image file formats' would be top-level headings for
34
+ *
1050
+ the HTML, but sub-headings of the conventional manpage 'Description'
35
+ * This program is distributed in the hope that it will be useful,
1051
+ header for the manpage. Unfortunately, due to deficiencies in
36
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1052
+ the Sphinx 'only' directive, this isn't possible: they must be headers
37
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1053
+ at the same level as 'Synopsis' and 'See also', otherwise Sphinx's
38
+ * General Public License for more details.
1054
+ identification of which header underline style is which gets confused.
39
+ *
1055
+
40
+ * You should have received a copy of the GNU General Public License along
1056
+.. only:: man
41
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
1057
+
42
+ */
1058
+ Synopsis
43
+
1059
+ --------
44
+#ifndef HW_ARM_SMMU_INTERNAL_H
1060
+
45
+#define HW_ARM_SMMU_INTERNAL_H
1061
+ QEMU block driver reference manual
46
+
1062
+
47
+#define TBI0(tbi) ((tbi) & 0x1)
1063
+Disk image file formats
48
+#define TBI1(tbi) ((tbi) & 0x2 >> 1)
1064
+-----------------------
49
+
1065
+
50
+/* PTE Manipulation */
1066
+QEMU supports many image file formats that can be used with VMs as well as with
51
+
1067
+any of the tools (like ``qemu-img``). This includes the preferred formats
52
+#define ARM_LPAE_PTE_TYPE_SHIFT 0
1068
+raw and qcow2 as well as formats that are supported for compatibility with
53
+#define ARM_LPAE_PTE_TYPE_MASK 0x3
1069
+older QEMU versions or other hypervisors.
54
+
1070
+
55
+#define ARM_LPAE_PTE_TYPE_BLOCK 1
1071
+Depending on the image format, different options can be passed to
56
+#define ARM_LPAE_PTE_TYPE_TABLE 3
1072
+``qemu-img create`` and ``qemu-img convert`` using the ``-o`` option.
57
+
1073
+This section describes each format and the options that are supported for it.
58
+#define ARM_LPAE_L3_PTE_TYPE_RESERVED 1
1074
+
59
+#define ARM_LPAE_L3_PTE_TYPE_PAGE 3
1075
+.. program:: image-formats
60
+
1076
+.. option:: raw
61
+#define ARM_LPAE_PTE_VALID (1 << 0)
1077
+
62
+
1078
+ Raw disk image format. This format has the advantage of
63
+#define PTE_ADDRESS(pte, shift) \
1079
+ being simple and easily exportable to all other emulators. If your
64
+ (extract64(pte, shift, 47 - shift + 1) << shift)
1080
+ file system supports *holes* (for example in ext2 or ext3 on
65
+
1081
+ Linux or NTFS on Windows), then only the written sectors will reserve
66
+#define is_invalid_pte(pte) (!(pte & ARM_LPAE_PTE_VALID))
1082
+ space. Use ``qemu-img info`` to know the real size used by the
67
+
1083
+ image or ``ls -ls`` on Unix/Linux.
68
+#define is_reserved_pte(pte, level) \
1084
+
69
+ ((level == 3) && \
1085
+ Supported options:
70
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_L3_PTE_TYPE_RESERVED))
1086
+
71
+
1087
+ .. program:: raw
72
+#define is_block_pte(pte, level) \
1088
+ .. option:: preallocation
73
+ ((level < 3) && \
1089
+
74
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_PTE_TYPE_BLOCK))
1090
+ Preallocation mode (allowed values: ``off``, ``falloc``,
75
+
1091
+ ``full``). ``falloc`` mode preallocates space for image by
76
+#define is_table_pte(pte, level) \
1092
+ calling ``posix_fallocate()``. ``full`` mode preallocates space
77
+ ((level < 3) && \
1093
+ for image by writing data to underlying storage. This data may or
78
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_PTE_TYPE_TABLE))
1094
+ may not be zero, depending on the storage location.
79
+
1095
+
80
+#define is_page_pte(pte, level) \
1096
+.. program:: image-formats
81
+ ((level == 3) && \
1097
+.. option:: qcow2
82
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_L3_PTE_TYPE_PAGE))
1098
+
83
+
1099
+ QEMU image format, the most versatile format. Use it to have smaller
84
+/* access permissions */
1100
+ images (useful if your filesystem does not supports holes, for example
85
+
1101
+ on Windows), zlib based compression and support of multiple VM
86
+#define PTE_AP(pte) \
1102
+ snapshots.
87
+ (extract64(pte, 6, 2))
1103
+
88
+
1104
+ Supported options:
89
+#define PTE_APTABLE(pte) \
1105
+
90
+ (extract64(pte, 61, 2))
1106
+ .. program:: qcow2
91
+
1107
+ .. option:: compat
92
+/*
1108
+
93
+ * TODO: At the moment all transactions are considered as privileged (EL1)
1109
+ Determines the qcow2 version to use. ``compat=0.10`` uses the
94
+ * as IOMMU translation callback does not pass user/priv attributes.
1110
+ traditional image format that can be read by any QEMU since 0.10.
95
+ */
1111
+ ``compat=1.1`` enables image format extensions that only QEMU 1.1 and
96
+#define is_permission_fault(ap, perm) \
1112
+ newer understand (this is the default). Amongst others, this includes
97
+ (((perm) & IOMMU_WO) && ((ap) & 0x2))
1113
+ zero clusters, which allow efficient copy-on-read for sparse images.
98
+
1114
+
99
+#define PTE_AP_TO_PERM(ap) \
1115
+ .. option:: backing_file
100
+ (IOMMU_ACCESS_FLAG(true, !((ap) & 0x2)))
1116
+
101
+
1117
+ File name of a base image (see ``create`` subcommand)
102
+/* Level Indexing */
1118
+
103
+
1119
+ .. option:: backing_fmt
104
+static inline int level_shift(int level, int granule_sz)
1120
+
105
+{
1121
+ Image format of the base image
106
+ return granule_sz + (3 - level) * (granule_sz - 3);
1122
+
107
+}
1123
+ .. option:: encryption
108
+
1124
+
109
+static inline uint64_t level_page_mask(int level, int granule_sz)
1125
+ This option is deprecated and equivalent to ``encrypt.format=aes``
110
+{
1126
+
111
+ return ~(MAKE_64BIT_MASK(0, level_shift(level, granule_sz)));
1127
+ .. option:: encrypt.format
112
+}
1128
+
113
+
1129
+ If this is set to ``luks``, it requests that the qcow2 payload (not
114
+static inline
1130
+ qcow2 header) be encrypted using the LUKS format. The passphrase to
115
+uint64_t iova_level_offset(uint64_t iova, int inputsize,
1131
+ use to unlock the LUKS key slot is given by the ``encrypt.key-secret``
116
+ int level, int gsz)
1132
+ parameter. LUKS encryption parameters can be tuned with the other
117
+{
1133
+ ``encrypt.*`` parameters.
118
+ return ((iova & MAKE_64BIT_MASK(0, inputsize)) >> level_shift(level, gsz)) &
1134
+
119
+ MAKE_64BIT_MASK(0, gsz - 3);
1135
+ If this is set to ``aes``, the image is encrypted with 128-bit AES-CBC.
120
+}
1136
+ The encryption key is given by the ``encrypt.key-secret`` parameter.
121
+
1137
+ This encryption format is considered to be flawed by modern cryptography
122
+#endif
1138
+ standards, suffering from a number of design problems:
123
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
1139
+
1140
+ - The AES-CBC cipher is used with predictable initialization vectors based
1141
+ on the sector number. This makes it vulnerable to chosen plaintext attacks
1142
+ which can reveal the existence of encrypted data.
1143
+ - The user passphrase is directly used as the encryption key. A poorly
1144
+ chosen or short passphrase will compromise the security of the encryption.
1145
+ - In the event of the passphrase being compromised there is no way to
1146
+ change the passphrase to protect data in any qcow images. The files must
1147
+ be cloned, using a different encryption passphrase in the new file. The
1148
+ original file must then be securely erased using a program like shred,
1149
+ though even this is ineffective with many modern storage technologies.
1150
+
1151
+ The use of this is no longer supported in system emulators. Support only
1152
+ remains in the command line utilities, for the purposes of data liberation
1153
+ and interoperability with old versions of QEMU. The ``luks`` format
1154
+ should be used instead.
1155
+
1156
+ .. option:: encrypt.key-secret
1157
+
1158
+ Provides the ID of a ``secret`` object that contains the passphrase
1159
+ (``encrypt.format=luks``) or encryption key (``encrypt.format=aes``).
1160
+
1161
+ .. option:: encrypt.cipher-alg
1162
+
1163
+ Name of the cipher algorithm and key length. Currently defaults
1164
+ to ``aes-256``. Only used when ``encrypt.format=luks``.
1165
+
1166
+ .. option:: encrypt.cipher-mode
1167
+
1168
+ Name of the encryption mode to use. Currently defaults to ``xts``.
1169
+ Only used when ``encrypt.format=luks``.
1170
+
1171
+ .. option:: encrypt.ivgen-alg
1172
+
1173
+ Name of the initialization vector generator algorithm. Currently defaults
1174
+ to ``plain64``. Only used when ``encrypt.format=luks``.
1175
+
1176
+ .. option:: encrypt.ivgen-hash-alg
1177
+
1178
+ Name of the hash algorithm to use with the initialization vector generator
1179
+ (if required). Defaults to ``sha256``. Only used when ``encrypt.format=luks``.
1180
+
1181
+ .. option:: encrypt.hash-alg
1182
+
1183
+ Name of the hash algorithm to use for PBKDF algorithm
1184
+ Defaults to ``sha256``. Only used when ``encrypt.format=luks``.
1185
+
1186
+ .. option:: encrypt.iter-time
1187
+
1188
+ Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
1189
+ Defaults to ``2000``. Only used when ``encrypt.format=luks``.
1190
+
1191
+ .. option:: cluster_size
1192
+
1193
+ Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster
1194
+ sizes can improve the image file size whereas larger cluster sizes generally
1195
+ provide better performance.
1196
+
1197
+ .. option:: preallocation
1198
+
1199
+ Preallocation mode (allowed values: ``off``, ``metadata``, ``falloc``,
1200
+ ``full``). An image with preallocated metadata is initially larger but can
1201
+ improve performance when the image needs to grow. ``falloc`` and ``full``
1202
+ preallocations are like the same options of ``raw`` format, but sets up
1203
+ metadata also.
1204
+
1205
+ .. option:: lazy_refcounts
1206
+
1207
+ If this option is set to ``on``, reference count updates are postponed with
1208
+ the goal of avoiding metadata I/O and improving performance. This is
1209
+ particularly interesting with :option:`cache=writethrough` which doesn't batch
1210
+ metadata updates. The tradeoff is that after a host crash, the reference count
1211
+ tables must be rebuilt, i.e. on the next open an (automatic) ``qemu-img
1212
+ check -r all`` is required, which may take some time.
1213
+
1214
+ This option can only be enabled if ``compat=1.1`` is specified.
1215
+
1216
+ .. option:: nocow
1217
+
1218
+ If this option is set to ``on``, it will turn off COW of the file. It's only
1219
+ valid on btrfs, no effect on other file systems.
1220
+
1221
+ Btrfs has low performance when hosting a VM image file, even more
1222
+ when the guest on the VM also using btrfs as file system. Turning off
1223
+ COW is a way to mitigate this bad performance. Generally there are two
1224
+ ways to turn off COW on btrfs:
1225
+
1226
+ - Disable it by mounting with nodatacow, then all newly created files
1227
+ will be NOCOW.
1228
+ - For an empty file, add the NOCOW file attribute. That's what this
1229
+ option does.
1230
+
1231
+ Note: this option is only valid to new or empty files. If there is
1232
+ an existing file which is COW and has data blocks already, it couldn't
1233
+ be changed to NOCOW by setting ``nocow=on``. One can issue ``lsattr
1234
+ filename`` to check if the NOCOW flag is set or not (Capital 'C' is
1235
+ NOCOW flag).
1236
+
1237
+.. program:: image-formats
1238
+.. option:: qed
1239
+
1240
+ Old QEMU image format with support for backing files and compact image files
1241
+ (when your filesystem or transport medium does not support holes).
1242
+
1243
+ When converting QED images to qcow2, you might want to consider using the
1244
+ ``lazy_refcounts=on`` option to get a more QED-like behaviour.
1245
+
1246
+ Supported options:
1247
+
1248
+ .. program:: qed
1249
+ .. option:: backing_file
1250
+
1251
+ File name of a base image (see ``create`` subcommand).
1252
+
1253
+ .. option:: backing_fmt
1254
+
1255
+ Image file format of backing file (optional). Useful if the format cannot be
1256
+ autodetected because it has no header, like some vhd/vpc files.
1257
+
1258
+ .. option:: cluster_size
1259
+
1260
+ Changes the cluster size (must be power-of-2 between 4K and 64K). Smaller
1261
+ cluster sizes can improve the image file size whereas larger cluster sizes
1262
+ generally provide better performance.
1263
+
1264
+ .. option:: table_size
1265
+
1266
+ Changes the number of clusters per L1/L2 table (must be
1267
+ power-of-2 between 1 and 16). There is normally no need to
1268
+ change this value but this option can between used for
1269
+ performance benchmarking.
1270
+
1271
+.. program:: image-formats
1272
+.. option:: qcow
1273
+
1274
+ Old QEMU image format with support for backing files, compact image files,
1275
+ encryption and compression.
1276
+
1277
+ Supported options:
1278
+
1279
+ .. program:: qcow
1280
+ .. option:: backing_file
1281
+
1282
+ File name of a base image (see ``create`` subcommand)
1283
+
1284
+ .. option:: encryption
1285
+
1286
+ This option is deprecated and equivalent to ``encrypt.format=aes``
1287
+
1288
+ .. option:: encrypt.format
1289
+
1290
+ If this is set to ``aes``, the image is encrypted with 128-bit AES-CBC.
1291
+ The encryption key is given by the ``encrypt.key-secret`` parameter.
1292
+ This encryption format is considered to be flawed by modern cryptography
1293
+ standards, suffering from a number of design problems enumerated previously
1294
+ against the ``qcow2`` image format.
1295
+
1296
+ The use of this is no longer supported in system emulators. Support only
1297
+ remains in the command line utilities, for the purposes of data liberation
1298
+ and interoperability with old versions of QEMU.
1299
+
1300
+ Users requiring native encryption should use the ``qcow2`` format
1301
+ instead with ``encrypt.format=luks``.
1302
+
1303
+ .. option:: encrypt.key-secret
1304
+
1305
+ Provides the ID of a ``secret`` object that contains the encryption
1306
+ key (``encrypt.format=aes``).
1307
+
1308
+.. program:: image-formats
1309
+.. option:: luks
1310
+
1311
+ LUKS v1 encryption format, compatible with Linux dm-crypt/cryptsetup
1312
+
1313
+ Supported options:
1314
+
1315
+ .. program:: luks
1316
+ .. option:: key-secret
1317
+
1318
+ Provides the ID of a ``secret`` object that contains the passphrase.
1319
+
1320
+ .. option:: cipher-alg
1321
+
1322
+ Name of the cipher algorithm and key length. Currently defaults
1323
+ to ``aes-256``.
1324
+
1325
+ .. option:: cipher-mode
1326
+
1327
+ Name of the encryption mode to use. Currently defaults to ``xts``.
1328
+
1329
+ .. option:: ivgen-alg
1330
+
1331
+ Name of the initialization vector generator algorithm. Currently defaults
1332
+ to ``plain64``.
1333
+
1334
+ .. option:: ivgen-hash-alg
1335
+
1336
+ Name of the hash algorithm to use with the initialization vector generator
1337
+ (if required). Defaults to ``sha256``.
1338
+
1339
+ .. option:: hash-alg
1340
+
1341
+ Name of the hash algorithm to use for PBKDF algorithm
1342
+ Defaults to ``sha256``.
1343
+
1344
+ .. option:: iter-time
1345
+
1346
+ Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
1347
+ Defaults to ``2000``.
1348
+
1349
+.. program:: image-formats
1350
+.. option:: vdi
1351
+
1352
+ VirtualBox 1.1 compatible image format.
1353
+
1354
+ Supported options:
1355
+
1356
+ .. program:: vdi
1357
+ .. option:: static
1358
+
1359
+ If this option is set to ``on``, the image is created with metadata
1360
+ preallocation.
1361
+
1362
+.. program:: image-formats
1363
+.. option:: vmdk
1364
+
1365
+ VMware 3 and 4 compatible image format.
1366
+
1367
+ Supported options:
1368
+
1369
+ .. program: vmdk
1370
+ .. option:: backing_file
1371
+
1372
+ File name of a base image (see ``create`` subcommand).
1373
+
1374
+ .. option:: compat6
1375
+
1376
+ Create a VMDK version 6 image (instead of version 4)
1377
+
1378
+ .. option:: hwversion
1379
+
1380
+ Specify vmdk virtual hardware version. Compat6 flag cannot be enabled
1381
+ if hwversion is specified.
1382
+
1383
+ .. option:: subformat
1384
+
1385
+ Specifies which VMDK subformat to use. Valid options are
1386
+ ``monolithicSparse`` (default),
1387
+ ``monolithicFlat``,
1388
+ ``twoGbMaxExtentSparse``,
1389
+ ``twoGbMaxExtentFlat`` and
1390
+ ``streamOptimized``.
1391
+
1392
+.. program:: image-formats
1393
+.. option:: vpc
1394
+
1395
+ VirtualPC compatible image format (VHD).
1396
+
1397
+ Supported options:
1398
+
1399
+ .. program:: vpc
1400
+ .. option:: subformat
1401
+
1402
+ Specifies which VHD subformat to use. Valid options are
1403
+ ``dynamic`` (default) and ``fixed``.
1404
+
1405
+.. program:: image-formats
1406
+.. option:: VHDX
1407
+
1408
+ Hyper-V compatible image format (VHDX).
1409
+
1410
+ Supported options:
1411
+
1412
+ .. program:: VHDX
1413
+ .. option:: subformat
1414
+
1415
+ Specifies which VHDX subformat to use. Valid options are
1416
+ ``dynamic`` (default) and ``fixed``.
1417
+
1418
+ .. option:: block_state_zero
1419
+
1420
+ Force use of payload blocks of type 'ZERO'. Can be set to ``on`` (default)
1421
+ or ``off``. When set to ``off``, new blocks will be created as
1422
+ ``PAYLOAD_BLOCK_NOT_PRESENT``, which means parsers are free to return
1423
+ arbitrary data for those blocks. Do not set to ``off`` when using
1424
+ ``qemu-img convert`` with ``subformat=dynamic``.
1425
+
1426
+ .. option:: block_size
1427
+
1428
+ Block size; min 1 MB, max 256 MB. 0 means auto-calculate based on
1429
+ image size.
1430
+
1431
+ .. option:: log_size
1432
+
1433
+ Log size; min 1 MB.
1434
+
1435
+Read-only formats
1436
+-----------------
1437
+
1438
+More disk image file formats are supported in a read-only mode.
1439
+
1440
+.. program:: image-formats
1441
+.. option:: bochs
1442
+
1443
+ Bochs images of ``growing`` type.
1444
+
1445
+.. program:: image-formats
1446
+.. option:: cloop
1447
+
1448
+ Linux Compressed Loop image, useful only to reuse directly compressed
1449
+ CD-ROM images present for example in the Knoppix CD-ROMs.
1450
+
1451
+.. program:: image-formats
1452
+.. option:: dmg
1453
+
1454
+ Apple disk image.
1455
+
1456
+.. program:: image-formats
1457
+.. option:: parallels
1458
+
1459
+ Parallels disk image format.
1460
+
1461
+Using host drives
1462
+-----------------
1463
+
1464
+In addition to disk image files, QEMU can directly access host
1465
+devices. We describe here the usage for QEMU version >= 0.8.3.
1466
+
1467
+Linux
1468
+'''''
1469
+
1470
+On Linux, you can directly use the host device filename instead of a
1471
+disk image filename provided you have enough privileges to access
1472
+it. For example, use ``/dev/cdrom`` to access to the CDROM.
1473
+
1474
+CD
1475
+ You can specify a CDROM device even if no CDROM is loaded. QEMU has
1476
+ specific code to detect CDROM insertion or removal. CDROM ejection by
1477
+ the guest OS is supported. Currently only data CDs are supported.
1478
+
1479
+Floppy
1480
+ You can specify a floppy device even if no floppy is loaded. Floppy
1481
+ removal is currently not detected accurately (if you change floppy
1482
+ without doing floppy access while the floppy is not loaded, the guest
1483
+ OS will think that the same floppy is loaded).
1484
+ Use of the host's floppy device is deprecated, and support for it will
1485
+ be removed in a future release.
1486
+
1487
+Hard disks
1488
+ Hard disks can be used. Normally you must specify the whole disk
1489
+ (``/dev/hdb`` instead of ``/dev/hdb1``) so that the guest OS can
1490
+ see it as a partitioned disk. WARNING: unless you know what you do, it
1491
+ is better to only make READ-ONLY accesses to the hard disk otherwise
1492
+ you may corrupt your host data (use the ``-snapshot`` command
1493
+ line option or modify the device permissions accordingly).
1494
+
1495
+Windows
1496
+'''''''
1497
+
1498
+CD
1499
+ The preferred syntax is the drive letter (e.g. ``d:``). The
1500
+ alternate syntax ``\\.\d:`` is supported. ``/dev/cdrom`` is
1501
+ supported as an alias to the first CDROM drive.
1502
+
1503
+ Currently there is no specific code to handle removable media, so it
1504
+ is better to use the ``change`` or ``eject`` monitor commands to
1505
+ change or eject media.
1506
+
1507
+Hard disks
1508
+ Hard disks can be used with the syntax: ``\\.\PhysicalDriveN``
1509
+ where *N* is the drive number (0 is the first hard disk).
1510
+
1511
+ WARNING: unless you know what you do, it is better to only make
1512
+ READ-ONLY accesses to the hard disk otherwise you may corrupt your
1513
+ host data (use the ``-snapshot`` command line so that the
1514
+ modifications are written in a temporary file).
1515
+
1516
+Mac OS X
1517
+''''''''
1518
+
1519
+``/dev/cdrom`` is an alias to the first CDROM.
1520
+
1521
+Currently there is no specific code to handle removable media, so it
1522
+is better to use the ``change`` or ``eject`` monitor commands to
1523
+change or eject media.
1524
+
1525
+Virtual FAT disk images
1526
+-----------------------
1527
+
1528
+QEMU can automatically create a virtual FAT disk image from a
1529
+directory tree. In order to use it, just type:
1530
+
1531
+.. parsed-literal::
1532
+
1533
+ |qemu_system| linux.img -hdb fat:/my_directory
1534
+
1535
+Then you access access to all the files in the ``/my_directory``
1536
+directory without having to copy them in a disk image or to export
1537
+them via SAMBA or NFS. The default access is *read-only*.
1538
+
1539
+Floppies can be emulated with the ``:floppy:`` option:
1540
+
1541
+.. parsed-literal::
1542
+
1543
+ |qemu_system| linux.img -fda fat:floppy:/my_directory
1544
+
1545
+A read/write support is available for testing (beta stage) with the
1546
+``:rw:`` option:
1547
+
1548
+.. parsed-literal::
1549
+
1550
+ |qemu_system| linux.img -fda fat:floppy:rw:/my_directory
1551
+
1552
+What you should *never* do:
1553
+
1554
+- use non-ASCII filenames
1555
+- use "-snapshot" together with ":rw:"
1556
+- expect it to work when loadvm'ing
1557
+- write to the FAT directory on the host system while accessing it with the guest system
1558
+
1559
+NBD access
1560
+----------
1561
+
1562
+QEMU can access directly to block device exported using the Network Block Device
1563
+protocol.
1564
+
1565
+.. parsed-literal::
1566
+
1567
+ |qemu_system| linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
1568
+
1569
+If the NBD server is located on the same host, you can use an unix socket instead
1570
+of an inet socket:
1571
+
1572
+.. parsed-literal::
1573
+
1574
+ |qemu_system| linux.img -hdb nbd+unix://?socket=/tmp/my_socket
1575
+
1576
+In this case, the block device must be exported using qemu-nbd:
1577
+
1578
+.. parsed-literal::
1579
+
1580
+ qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
1581
+
1582
+The use of qemu-nbd allows sharing of a disk between several guests:
1583
+
1584
+.. parsed-literal::
1585
+
1586
+ qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
1587
+
1588
+and then you can use it with two guests:
1589
+
1590
+.. parsed-literal::
1591
+
1592
+ |qemu_system| linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
1593
+ |qemu_system| linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
1594
+
1595
+If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
1596
+own embedded NBD server), you must specify an export name in the URI:
1597
+
1598
+.. parsed-literal::
1599
+
1600
+ |qemu_system| -cdrom nbd://localhost/debian-500-ppc-netinst
1601
+ |qemu_system| -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
1602
+
1603
+The URI syntax for NBD is supported since QEMU 1.3. An alternative syntax is
1604
+also available. Here are some example of the older syntax:
1605
+
1606
+.. parsed-literal::
1607
+
1608
+ |qemu_system| linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
1609
+ |qemu_system| linux2.img -hdb nbd:unix:/tmp/my_socket
1610
+ |qemu_system| -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
1611
+
1612
+
1613
+
1614
+Sheepdog disk images
1615
+--------------------
1616
+
1617
+Sheepdog is a distributed storage system for QEMU. It provides highly
1618
+available block level storage volumes that can be attached to
1619
+QEMU-based virtual machines.
1620
+
1621
+You can create a Sheepdog disk image with the command:
1622
+
1623
+.. parsed-literal::
1624
+
1625
+ qemu-img create sheepdog:///IMAGE SIZE
1626
+
1627
+where *IMAGE* is the Sheepdog image name and *SIZE* is its
1628
+size.
1629
+
1630
+To import the existing *FILENAME* to Sheepdog, you can use a
1631
+convert command.
1632
+
1633
+.. parsed-literal::
1634
+
1635
+ qemu-img convert FILENAME sheepdog:///IMAGE
1636
+
1637
+You can boot from the Sheepdog disk image with the command:
1638
+
1639
+.. parsed-literal::
1640
+
1641
+ |qemu_system| sheepdog:///IMAGE
1642
+
1643
+You can also create a snapshot of the Sheepdog image like qcow2.
1644
+
1645
+.. parsed-literal::
1646
+
1647
+ qemu-img snapshot -c TAG sheepdog:///IMAGE
1648
+
1649
+where *TAG* is a tag name of the newly created snapshot.
1650
+
1651
+To boot from the Sheepdog snapshot, specify the tag name of the
1652
+snapshot.
1653
+
1654
+.. parsed-literal::
1655
+
1656
+ |qemu_system| sheepdog:///IMAGE#TAG
1657
+
1658
+You can create a cloned image from the existing snapshot.
1659
+
1660
+.. parsed-literal::
1661
+
1662
+ qemu-img create -b sheepdog:///BASE#TAG sheepdog:///IMAGE
1663
+
1664
+where *BASE* is an image name of the source snapshot and *TAG*
1665
+is its tag name.
1666
+
1667
+You can use an unix socket instead of an inet socket:
1668
+
1669
+.. parsed-literal::
1670
+
1671
+ |qemu_system| sheepdog+unix:///IMAGE?socket=PATH
1672
+
1673
+If the Sheepdog daemon doesn't run on the local host, you need to
1674
+specify one of the Sheepdog servers to connect to.
1675
+
1676
+.. parsed-literal::
1677
+
1678
+ qemu-img create sheepdog://HOSTNAME:PORT/IMAGE SIZE
1679
+ |qemu_system| sheepdog://HOSTNAME:PORT/IMAGE
1680
+
1681
+iSCSI LUNs
1682
+----------
1683
+
1684
+iSCSI is a popular protocol used to access SCSI devices across a computer
1685
+network.
1686
+
1687
+There are two different ways iSCSI devices can be used by QEMU.
1688
+
1689
+The first method is to mount the iSCSI LUN on the host, and make it appear as
1690
+any other ordinary SCSI device on the host and then to access this device as a
1691
+/dev/sd device from QEMU. How to do this differs between host OSes.
1692
+
1693
+The second method involves using the iSCSI initiator that is built into
1694
+QEMU. This provides a mechanism that works the same way regardless of which
1695
+host OS you are running QEMU on. This section will describe this second method
1696
+of using iSCSI together with QEMU.
1697
+
1698
+In QEMU, iSCSI devices are described using special iSCSI URLs. URL syntax:
1699
+
1700
+::
1701
+
1702
+ iscsi://[<username>[%<password>]@]<host>[:<port>]/<target-iqn-name>/<lun>
1703
+
1704
+Username and password are optional and only used if your target is set up
1705
+using CHAP authentication for access control.
1706
+Alternatively the username and password can also be set via environment
1707
+variables to have these not show up in the process list:
1708
+
1709
+::
1710
+
1711
+ export LIBISCSI_CHAP_USERNAME=<username>
1712
+ export LIBISCSI_CHAP_PASSWORD=<password>
1713
+ iscsi://<host>/<target-iqn-name>/<lun>
1714
+
1715
+Various session related parameters can be set via special options, either
1716
+in a configuration file provided via '-readconfig' or directly on the
1717
+command line.
1718
+
1719
+If the initiator-name is not specified qemu will use a default name
1720
+of 'iqn.2008-11.org.linux-kvm[:<uuid>'] where <uuid> is the UUID of the
1721
+virtual machine. If the UUID is not specified qemu will use
1722
+'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
1723
+virtual machine.
1724
+
1725
+Setting a specific initiator name to use when logging in to the target:
1726
+
1727
+::
1728
+
1729
+ -iscsi initiator-name=iqn.qemu.test:my-initiator
1730
+
1731
+Controlling which type of header digest to negotiate with the target:
1732
+
1733
+::
1734
+
1735
+ -iscsi header-digest=CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
1736
+
1737
+These can also be set via a configuration file:
1738
+
1739
+::
1740
+
1741
+ [iscsi]
1742
+ user = "CHAP username"
1743
+ password = "CHAP password"
1744
+ initiator-name = "iqn.qemu.test:my-initiator"
1745
+ # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
1746
+ header-digest = "CRC32C"
1747
+
1748
+Setting the target name allows different options for different targets:
1749
+
1750
+::
1751
+
1752
+ [iscsi "iqn.target.name"]
1753
+ user = "CHAP username"
1754
+ password = "CHAP password"
1755
+ initiator-name = "iqn.qemu.test:my-initiator"
1756
+ # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
1757
+ header-digest = "CRC32C"
1758
+
1759
+How to use a configuration file to set iSCSI configuration options:
1760
+
1761
+.. parsed-literal::
1762
+
1763
+ cat >iscsi.conf <<EOF
1764
+ [iscsi]
1765
+ user = "me"
1766
+ password = "my password"
1767
+ initiator-name = "iqn.qemu.test:my-initiator"
1768
+ header-digest = "CRC32C"
1769
+ EOF
1770
+
1771
+ |qemu_system| -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \\
1772
+ -readconfig iscsi.conf
1773
+
1774
+How to set up a simple iSCSI target on loopback and access it via QEMU:
1775
+this example shows how to set up an iSCSI target with one CDROM and one DISK
1776
+using the Linux STGT software target. This target is available on Red Hat based
1777
+systems as the package 'scsi-target-utils'.
1778
+
1779
+.. parsed-literal::
1780
+
1781
+ tgtd --iscsi portal=127.0.0.1:3260
1782
+ tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.qemu.test
1783
+ tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 \\
1784
+ -b /IMAGES/disk.img --device-type=disk
1785
+ tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \\
1786
+ -b /IMAGES/cd.iso --device-type=cd
1787
+ tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
1788
+
1789
+ |qemu_system| -iscsi initiator-name=iqn.qemu.test:my-initiator \\
1790
+ -boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \\
1791
+ -cdrom iscsi://127.0.0.1/iqn.qemu.test/2
1792
+
1793
+GlusterFS disk images
1794
+---------------------
1795
+
1796
+GlusterFS is a user space distributed file system.
1797
+
1798
+You can boot from the GlusterFS disk image with the command:
1799
+
1800
+URI:
1801
+
1802
+.. parsed-literal::
1803
+
1804
+ |qemu_system| -drive file=gluster[+TYPE]://[HOST}[:PORT]]/VOLUME/PATH
1805
+ [?socket=...][,file.debug=9][,file.logfile=...]
1806
+
1807
+JSON:
1808
+
1809
+.. parsed-literal::
1810
+
1811
+ |qemu_system| 'json:{"driver":"qcow2",
1812
+ "file":{"driver":"gluster",
1813
+ "volume":"testvol","path":"a.img","debug":9,"logfile":"...",
1814
+ "server":[{"type":"tcp","host":"...","port":"..."},
1815
+ {"type":"unix","socket":"..."}]}}'
1816
+
1817
+*gluster* is the protocol.
1818
+
1819
+*TYPE* specifies the transport type used to connect to gluster
1820
+management daemon (glusterd). Valid transport types are
1821
+tcp and unix. In the URI form, if a transport type isn't specified,
1822
+then tcp type is assumed.
1823
+
1824
+*HOST* specifies the server where the volume file specification for
1825
+the given volume resides. This can be either a hostname or an ipv4 address.
1826
+If transport type is unix, then *HOST* field should not be specified.
1827
+Instead *socket* field needs to be populated with the path to unix domain
1828
+socket.
1829
+
1830
+*PORT* is the port number on which glusterd is listening. This is optional
1831
+and if not specified, it defaults to port 24007. If the transport type is unix,
1832
+then *PORT* should not be specified.
1833
+
1834
+*VOLUME* is the name of the gluster volume which contains the disk image.
1835
+
1836
+*PATH* is the path to the actual disk image that resides on gluster volume.
1837
+
1838
+*debug* is the logging level of the gluster protocol driver. Debug levels
1839
+are 0-9, with 9 being the most verbose, and 0 representing no debugging output.
1840
+The default level is 4. The current logging levels defined in the gluster source
1841
+are 0 - None, 1 - Emergency, 2 - Alert, 3 - Critical, 4 - Error, 5 - Warning,
1842
+6 - Notice, 7 - Info, 8 - Debug, 9 - Trace
1843
+
1844
+*logfile* is a commandline option to mention log file path which helps in
1845
+logging to the specified file and also help in persisting the gfapi logs. The
1846
+default is stderr.
1847
+
1848
+You can create a GlusterFS disk image with the command:
1849
+
1850
+.. parsed-literal::
1851
+
1852
+ qemu-img create gluster://HOST/VOLUME/PATH SIZE
1853
+
1854
+Examples
1855
+
1856
+.. parsed-literal::
1857
+
1858
+ |qemu_system| -drive file=gluster://1.2.3.4/testvol/a.img
1859
+ |qemu_system| -drive file=gluster+tcp://1.2.3.4/testvol/a.img
1860
+ |qemu_system| -drive file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
1861
+ |qemu_system| -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
1862
+ |qemu_system| -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
1863
+ |qemu_system| -drive file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
1864
+ |qemu_system| -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
1865
+ |qemu_system| -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
1866
+ |qemu_system| -drive file=gluster://1.2.3.4/testvol/a.img,file.debug=9,file.logfile=/var/log/qemu-gluster.log
1867
+ |qemu_system| 'json:{"driver":"qcow2",
1868
+ "file":{"driver":"gluster",
1869
+ "volume":"testvol","path":"a.img",
1870
+ "debug":9,"logfile":"/var/log/qemu-gluster.log",
1871
+ "server":[{"type":"tcp","host":"1.2.3.4","port":24007},
1872
+ {"type":"unix","socket":"/var/run/glusterd.socket"}]}}'
1873
+ |qemu_system| -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
1874
+ file.debug=9,file.logfile=/var/log/qemu-gluster.log,
1875
+ file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
1876
+ file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
1877
+
1878
+Secure Shell (ssh) disk images
1879
+------------------------------
1880
+
1881
+You can access disk images located on a remote ssh server
1882
+by using the ssh protocol:
1883
+
1884
+.. parsed-literal::
1885
+
1886
+ |qemu_system| -drive file=ssh://[USER@]SERVER[:PORT]/PATH[?host_key_check=HOST_KEY_CHECK]
1887
+
1888
+Alternative syntax using properties:
1889
+
1890
+.. parsed-literal::
1891
+
1892
+ |qemu_system| -drive file.driver=ssh[,file.user=USER],file.host=SERVER[,file.port=PORT],file.path=PATH[,file.host_key_check=HOST_KEY_CHECK]
1893
+
1894
+*ssh* is the protocol.
1895
+
1896
+*USER* is the remote user. If not specified, then the local
1897
+username is tried.
1898
+
1899
+*SERVER* specifies the remote ssh server. Any ssh server can be
1900
+used, but it must implement the sftp-server protocol. Most Unix/Linux
1901
+systems should work without requiring any extra configuration.
1902
+
1903
+*PORT* is the port number on which sshd is listening. By default
1904
+the standard ssh port (22) is used.
1905
+
1906
+*PATH* is the path to the disk image.
1907
+
1908
+The optional *HOST_KEY_CHECK* parameter controls how the remote
1909
+host's key is checked. The default is ``yes`` which means to use
1910
+the local ``.ssh/known_hosts`` file. Setting this to ``no``
1911
+turns off known-hosts checking. Or you can check that the host key
1912
+matches a specific fingerprint:
1913
+``host_key_check=md5:78:45:8e:14:57:4f:d5:45:83:0a:0e:f3:49:82:c9:c8``
1914
+(``sha1:`` can also be used as a prefix, but note that OpenSSH
1915
+tools only use MD5 to print fingerprints).
1916
+
1917
+Currently authentication must be done using ssh-agent. Other
1918
+authentication methods may be supported in future.
1919
+
1920
+Note: Many ssh servers do not support an ``fsync``-style operation.
1921
+The ssh driver cannot guarantee that disk flush requests are
1922
+obeyed, and this causes a risk of disk corruption if the remote
1923
+server or network goes down during writes. The driver will
1924
+print a warning when ``fsync`` is not supported:
1925
+
1926
+::
1927
+
1928
+ warning: ssh server ssh.example.com:22 does not support fsync
1929
+
1930
+With sufficiently new versions of libssh and OpenSSH, ``fsync`` is
1931
+supported.
1932
+
1933
+NVMe disk images
1934
+----------------
1935
+
1936
+NVM Express (NVMe) storage controllers can be accessed directly by a userspace
1937
+driver in QEMU. This bypasses the host kernel file system and block layers
1938
+while retaining QEMU block layer functionalities, such as block jobs, I/O
1939
+throttling, image formats, etc. Disk I/O performance is typically higher than
1940
+with ``-drive file=/dev/sda`` using either thread pool or linux-aio.
1941
+
1942
+The controller will be exclusively used by the QEMU process once started. To be
1943
+able to share storage between multiple VMs and other applications on the host,
1944
+please use the file based protocols.
1945
+
1946
+Before starting QEMU, bind the host NVMe controller to the host vfio-pci
1947
+driver. For example:
1948
+
1949
+.. parsed-literal::
1950
+
1951
+ # modprobe vfio-pci
1952
+ # lspci -n -s 0000:06:0d.0
1953
+ 06:0d.0 0401: 1102:0002 (rev 08)
1954
+ # echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
1955
+ # echo 1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
1956
+
1957
+ # |qemu_system| -drive file=nvme://HOST:BUS:SLOT.FUNC/NAMESPACE
1958
+
1959
+Alternative syntax using properties:
1960
+
1961
+.. parsed-literal::
1962
+
1963
+ |qemu_system| -drive file.driver=nvme,file.device=HOST:BUS:SLOT.FUNC,file.namespace=NAMESPACE
1964
+
1965
+*HOST*:*BUS*:*SLOT*.\ *FUNC* is the NVMe controller's PCI device
1966
+address on the host.
1967
+
1968
+*NAMESPACE* is the NVMe namespace number, starting from 1.
1969
+
1970
+Disk image file locking
1971
+-----------------------
1972
+
1973
+By default, QEMU tries to protect image files from unexpected concurrent
1974
+access, as long as it's supported by the block protocol driver and host
1975
+operating system. If multiple QEMU processes (including QEMU emulators and
1976
+utilities) try to open the same image with conflicting accessing modes, all but
1977
+the first one will get an error.
1978
+
1979
+This feature is currently supported by the file protocol on Linux with the Open
1980
+File Descriptor (OFD) locking API, and can be configured to fall back to POSIX
1981
+locking if the POSIX host doesn't support Linux OFD locking.
1982
+
1983
+To explicitly enable image locking, specify "locking=on" in the file protocol
1984
+driver options. If OFD locking is not possible, a warning will be printed and
1985
+the POSIX locking API will be used. In this case there is a risk that the lock
1986
+will get silently lost when doing hot plugging and block jobs, due to the
1987
+shortcomings of the POSIX locking API.
1988
+
1989
+QEMU transparently handles lock handover during shared storage migration. For
1990
+shared virtual disk images between multiple VMs, the "share-rw" device option
1991
+should be used.
1992
+
1993
+By default, the guest has exclusive write access to its disk image. If the
1994
+guest can safely share the disk image with other writers the
1995
+``-device ...,share-rw=on`` parameter can be used. This is only safe if
1996
+the guest is running software, such as a cluster file system, that
1997
+coordinates disk accesses to avoid corruption.
1998
+
1999
+Note that share-rw=on only declares the guest's ability to share the disk.
2000
+Some QEMU features, such as image file formats, require exclusive write access
2001
+to the disk image and this is unaffected by the share-rw=on option.
2002
+
2003
+Alternatively, locking can be fully disabled by "locking=off" block device
2004
+option. In the command line, the option is usually in the form of
2005
+"file.locking=off" as the protocol driver is normally placed as a "file" child
2006
+under a format driver. For example:
2007
+
2008
+::
2009
+
2010
+ -blockdev driver=qcow2,file.filename=/path/to/image,file.locking=off,file.driver=file
2011
+
2012
+To check if image locking is active, check the output of the "lslocks" command
2013
+on host and see if there are locks held by the QEMU process on the image file.
2014
+More than one byte could be locked by the QEMU instance, each byte of which
2015
+reflects a particular permission that is acquired or protected by the running
2016
+block driver.
2017
+
2018
+.. only:: man
2019
+
2020
+ See also
2021
+ --------
2022
+
2023
+ The HTML documentation of QEMU for more precise information and Linux
2024
+ user mode emulator invocation.
2025
diff --git a/qemu-doc.texi b/qemu-doc.texi
124
index XXXXXXX..XXXXXXX 100644
2026
index XXXXXXX..XXXXXXX 100644
125
--- a/include/hw/arm/smmu-common.h
2027
--- a/qemu-doc.texi
126
+++ b/include/hw/arm/smmu-common.h
2028
+++ b/qemu-doc.texi
127
@@ -XXX,XX +XXX,XX @@ static inline uint16_t smmu_get_sid(SMMUDevice *sdev)
2029
@@ -XXX,XX +XXX,XX @@ encrypted disk images.
128
{
2030
* disk_images_snapshot_mode:: Snapshot mode
129
return PCI_BUILD_BDF(pci_bus_num(sdev->bus), sdev->devfn);
2031
* vm_snapshots:: VM snapshots
130
}
2032
* qemu_img_invocation:: qemu-img Invocation
131
+
2033
-* disk_images_formats:: Disk image file formats
132
+/**
2034
-* host_drives:: Using host drives
133
+ * smmu_ptw - Perform the page table walk for a given iova / access flags
2035
-* disk_images_fat_images:: Virtual FAT disk images
134
+ * pair, according to @cfg translation config
2036
-* disk_images_nbd:: NBD access
135
+ */
2037
-* disk_images_sheepdog:: Sheepdog disk images
136
+int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
2038
-* disk_images_iscsi:: iSCSI LUNs
137
+ IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info);
2039
-* disk_images_gluster:: GlusterFS disk images
138
+
2040
-* disk_images_ssh:: Secure Shell (ssh) disk images
139
+/**
2041
-* disk_images_nvme:: NVMe userspace driver
140
+ * select_tt - compute which translation table shall be used according to
2042
-* disk_image_locking:: Disk image file locking
141
+ * the input iova and translation config and return the TT specific info
2043
@end menu
142
+ */
2044
143
+SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova);
2045
@node disk_images_quickstart
144
+
2046
@@ -XXX,XX +XXX,XX @@ state is not saved or restored properly (in particular USB).
145
#endif /* HW_ARM_SMMU_COMMON */
2047
146
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
2048
@include qemu-img.texi
2049
2050
-@include docs/qemu-block-drivers.texi
2051
-
2052
@node pcsys_network
2053
@section Network emulation
2054
2055
diff --git a/qemu-options.hx b/qemu-options.hx
147
index XXXXXXX..XXXXXXX 100644
2056
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/arm/smmu-common.c
2057
--- a/qemu-options.hx
149
+++ b/hw/arm/smmu-common.c
2058
+++ b/qemu-options.hx
150
@@ -XXX,XX +XXX,XX @@
2059
@@ -XXX,XX +XXX,XX @@ STEXI
151
2060
@findex -cdrom
152
#include "qemu/error-report.h"
2061
Use @var{file} as CD-ROM image (you cannot use @option{-hdc} and
153
#include "hw/arm/smmu-common.h"
2062
@option{-cdrom} at the same time). You can use the host CD-ROM by
154
+#include "smmu-internal.h"
2063
-using @file{/dev/cdrom} as filename (@pxref{host_drives}).
155
+
2064
+using @file{/dev/cdrom} as filename.
156
+/* VMSAv8-64 Translation */
2065
ETEXI
157
+
2066
158
+/**
2067
DEF("blockdev", HAS_ARG, QEMU_OPTION_blockdev,
159
+ * get_pte - Get the content of a page table entry located at
160
+ * @base_addr[@index]
161
+ */
162
+static int get_pte(dma_addr_t baseaddr, uint32_t index, uint64_t *pte,
163
+ SMMUPTWEventInfo *info)
164
+{
165
+ int ret;
166
+ dma_addr_t addr = baseaddr + index * sizeof(*pte);
167
+
168
+ /* TODO: guarantee 64-bit single-copy atomicity */
169
+ ret = dma_memory_read(&address_space_memory, addr,
170
+ (uint8_t *)pte, sizeof(*pte));
171
+
172
+ if (ret != MEMTX_OK) {
173
+ info->type = SMMU_PTW_ERR_WALK_EABT;
174
+ info->addr = addr;
175
+ return -EINVAL;
176
+ }
177
+ trace_smmu_get_pte(baseaddr, index, addr, *pte);
178
+ return 0;
179
+}
180
+
181
+/* VMSAv8-64 Translation Table Format Descriptor Decoding */
182
+
183
+/**
184
+ * get_page_pte_address - returns the L3 descriptor output address,
185
+ * ie. the page frame
186
+ * ARM ARM spec: Figure D4-17 VMSAv8-64 level 3 descriptor format
187
+ */
188
+static inline hwaddr get_page_pte_address(uint64_t pte, int granule_sz)
189
+{
190
+ return PTE_ADDRESS(pte, granule_sz);
191
+}
192
+
193
+/**
194
+ * get_table_pte_address - return table descriptor output address,
195
+ * ie. address of next level table
196
+ * ARM ARM Figure D4-16 VMSAv8-64 level0, level1, and level 2 descriptor formats
197
+ */
198
+static inline hwaddr get_table_pte_address(uint64_t pte, int granule_sz)
199
+{
200
+ return PTE_ADDRESS(pte, granule_sz);
201
+}
202
+
203
+/**
204
+ * get_block_pte_address - return block descriptor output address and block size
205
+ * ARM ARM Figure D4-16 VMSAv8-64 level0, level1, and level 2 descriptor formats
206
+ */
207
+static inline hwaddr get_block_pte_address(uint64_t pte, int level,
208
+ int granule_sz, uint64_t *bsz)
209
+{
210
+ int n = (granule_sz - 3) * (4 - level) + 3;
211
+
212
+ *bsz = 1 << n;
213
+ return PTE_ADDRESS(pte, n);
214
+}
215
+
216
+SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova)
217
+{
218
+ bool tbi = extract64(iova, 55, 1) ? TBI1(cfg->tbi) : TBI0(cfg->tbi);
219
+ uint8_t tbi_byte = tbi * 8;
220
+
221
+ if (cfg->tt[0].tsz &&
222
+ !extract64(iova, 64 - cfg->tt[0].tsz, cfg->tt[0].tsz - tbi_byte)) {
223
+ /* there is a ttbr0 region and we are in it (high bits all zero) */
224
+ return &cfg->tt[0];
225
+ } else if (cfg->tt[1].tsz &&
226
+ !extract64(iova, 64 - cfg->tt[1].tsz, cfg->tt[1].tsz - tbi_byte)) {
227
+ /* there is a ttbr1 region and we are in it (high bits all one) */
228
+ return &cfg->tt[1];
229
+ } else if (!cfg->tt[0].tsz) {
230
+ /* ttbr0 region is "everything not in the ttbr1 region" */
231
+ return &cfg->tt[0];
232
+ } else if (!cfg->tt[1].tsz) {
233
+ /* ttbr1 region is "everything not in the ttbr0 region" */
234
+ return &cfg->tt[1];
235
+ }
236
+ /* in the gap between the two regions, this is a Translation fault */
237
+ return NULL;
238
+}
239
+
240
+/**
241
+ * smmu_ptw_64 - VMSAv8-64 Walk of the page tables for a given IOVA
242
+ * @cfg: translation config
243
+ * @iova: iova to translate
244
+ * @perm: access type
245
+ * @tlbe: IOMMUTLBEntry (out)
246
+ * @info: handle to an error info
247
+ *
248
+ * Return 0 on success, < 0 on error. In case of error, @info is filled
249
+ * and tlbe->perm is set to IOMMU_NONE.
250
+ * Upon success, @tlbe is filled with translated_addr and entry
251
+ * permission rights.
252
+ */
253
+static int smmu_ptw_64(SMMUTransCfg *cfg,
254
+ dma_addr_t iova, IOMMUAccessFlags perm,
255
+ IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
256
+{
257
+ dma_addr_t baseaddr, indexmask;
258
+ int stage = cfg->stage;
259
+ SMMUTransTableInfo *tt = select_tt(cfg, iova);
260
+ uint8_t level, granule_sz, inputsize, stride;
261
+
262
+ if (!tt || tt->disabled) {
263
+ info->type = SMMU_PTW_ERR_TRANSLATION;
264
+ goto error;
265
+ }
266
+
267
+ granule_sz = tt->granule_sz;
268
+ stride = granule_sz - 3;
269
+ inputsize = 64 - tt->tsz;
270
+ level = 4 - (inputsize - 4) / stride;
271
+ indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
272
+ baseaddr = extract64(tt->ttb, 0, 48);
273
+ baseaddr &= ~indexmask;
274
+
275
+ tlbe->iova = iova;
276
+ tlbe->addr_mask = (1 << granule_sz) - 1;
277
+
278
+ while (level <= 3) {
279
+ uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
280
+ uint64_t mask = subpage_size - 1;
281
+ uint32_t offset = iova_level_offset(iova, inputsize, level, granule_sz);
282
+ uint64_t pte;
283
+ dma_addr_t pte_addr = baseaddr + offset * sizeof(pte);
284
+ uint8_t ap;
285
+
286
+ if (get_pte(baseaddr, offset, &pte, info)) {
287
+ goto error;
288
+ }
289
+ trace_smmu_ptw_level(level, iova, subpage_size,
290
+ baseaddr, offset, pte);
291
+
292
+ if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) {
293
+ trace_smmu_ptw_invalid_pte(stage, level, baseaddr,
294
+ pte_addr, offset, pte);
295
+ info->type = SMMU_PTW_ERR_TRANSLATION;
296
+ goto error;
297
+ }
298
+
299
+ if (is_page_pte(pte, level)) {
300
+ uint64_t gpa = get_page_pte_address(pte, granule_sz);
301
+
302
+ ap = PTE_AP(pte);
303
+ if (is_permission_fault(ap, perm)) {
304
+ info->type = SMMU_PTW_ERR_PERMISSION;
305
+ goto error;
306
+ }
307
+
308
+ tlbe->translated_addr = gpa + (iova & mask);
309
+ tlbe->perm = PTE_AP_TO_PERM(ap);
310
+ trace_smmu_ptw_page_pte(stage, level, iova,
311
+ baseaddr, pte_addr, pte, gpa);
312
+ return 0;
313
+ }
314
+ if (is_block_pte(pte, level)) {
315
+ uint64_t block_size;
316
+ hwaddr gpa = get_block_pte_address(pte, level, granule_sz,
317
+ &block_size);
318
+
319
+ ap = PTE_AP(pte);
320
+ if (is_permission_fault(ap, perm)) {
321
+ info->type = SMMU_PTW_ERR_PERMISSION;
322
+ goto error;
323
+ }
324
+
325
+ trace_smmu_ptw_block_pte(stage, level, baseaddr,
326
+ pte_addr, pte, iova, gpa,
327
+ block_size >> 20);
328
+
329
+ tlbe->translated_addr = gpa + (iova & mask);
330
+ tlbe->perm = PTE_AP_TO_PERM(ap);
331
+ return 0;
332
+ }
333
+
334
+ /* table pte */
335
+ ap = PTE_APTABLE(pte);
336
+
337
+ if (is_permission_fault(ap, perm)) {
338
+ info->type = SMMU_PTW_ERR_PERMISSION;
339
+ goto error;
340
+ }
341
+ baseaddr = get_table_pte_address(pte, granule_sz);
342
+ level++;
343
+ }
344
+
345
+ info->type = SMMU_PTW_ERR_TRANSLATION;
346
+
347
+error:
348
+ tlbe->perm = IOMMU_NONE;
349
+ return -EINVAL;
350
+}
351
+
352
+/**
353
+ * smmu_ptw - Walk the page tables for an IOVA, according to @cfg
354
+ *
355
+ * @cfg: translation configuration
356
+ * @iova: iova to translate
357
+ * @perm: tentative access type
358
+ * @tlbe: returned entry
359
+ * @info: ptw event handle
360
+ *
361
+ * return 0 on success
362
+ */
363
+inline int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
364
+ IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
365
+{
366
+ if (!cfg->aa64) {
367
+ /*
368
+ * This code path is not entered as we check this while decoding
369
+ * the configuration data in the derived SMMU model.
370
+ */
371
+ g_assert_not_reached();
372
+ }
373
+
374
+ return smmu_ptw_64(cfg, iova, perm, tlbe, info);
375
+}
376
377
/**
378
* The bus number is used for lookup when SID based invalidation occurs.
379
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
380
index XXXXXXX..XXXXXXX 100644
381
--- a/hw/arm/trace-events
382
+++ b/hw/arm/trace-events
383
@@ -XXX,XX +XXX,XX @@
384
virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
385
386
# hw/arm/smmu-common.c
387
-smmu_add_mr(const char *name) "%s"
388
\ No newline at end of file
389
+smmu_add_mr(const char *name) "%s"
390
+smmu_page_walk(int stage, uint64_t baseaddr, int first_level, uint64_t start, uint64_t end) "stage=%d, baseaddr=0x%"PRIx64", first level=%d, start=0x%"PRIx64", end=0x%"PRIx64
391
+smmu_lookup_table(int level, uint64_t baseaddr, int granule_sz, uint64_t start, uint64_t end, int flags, uint64_t subpage_size) "level=%d baseaddr=0x%"PRIx64" granule=%d, start=0x%"PRIx64" end=0x%"PRIx64" flags=%d subpage_size=0x%"PRIx64
392
+smmu_ptw_level(int level, uint64_t iova, size_t subpage_size, uint64_t baseaddr, uint32_t offset, uint64_t pte) "level=%d iova=0x%"PRIx64" subpage_sz=0x%lx baseaddr=0x%"PRIx64" offset=%d => pte=0x%"PRIx64
393
+smmu_ptw_invalid_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr, uint32_t offset, uint64_t pte) "stage=%d level=%d base@=0x%"PRIx64" pte@=0x%"PRIx64" offset=%d pte=0x%"PRIx64
394
+smmu_ptw_page_pte(int stage, int level, uint64_t iova, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t address) "stage=%d level=%d iova=0x%"PRIx64" base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" page address = 0x%"PRIx64
395
+smmu_ptw_block_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t iova, uint64_t gpa, int bsize_mb) "stage=%d level=%d base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" iova=0x%"PRIx64" block address = 0x%"PRIx64" block size = %d MiB"
396
+smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, uint64_t pte) "baseaddr=0x%"PRIx64" index=0x%x, pteaddr=0x%"PRIx64", pte=0x%"PRIx64
397
--
2068
--
398
2.17.0
2069
2.20.1
399
2070
400
2071
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
This patch implements the IOMMU Memory Region translate()
3
When dumping a guest with dump-guest-memory also dump the SVE
4
callback. Most of the code relates to the translation
4
registers if they are in use.
5
configuration decoding and check (STE, CD).
5
6
6
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
8
Message-id: 20200120101832.18781-1-drjones@redhat.com
9
Message-id: 1524665762-31355-10-git-send-email-eric.auger@redhat.com
9
[PMM: fixed checkpatch nits]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
hw/arm/smmuv3-internal.h | 160 +++++++++++++++++
12
include/elf.h | 1 +
14
hw/arm/smmuv3.c | 358 +++++++++++++++++++++++++++++++++++++++
13
target/arm/cpu.h | 25 +++++++++
15
hw/arm/trace-events | 9 +
14
target/arm/arch_dump.c | 124 ++++++++++++++++++++++++++++++++++++++++-
16
3 files changed, 527 insertions(+)
15
target/arm/kvm64.c | 24 --------
17
16
4 files changed, 148 insertions(+), 26 deletions(-)
18
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
17
19
index XXXXXXX..XXXXXXX 100644
18
diff --git a/include/elf.h b/include/elf.h
20
--- a/hw/arm/smmuv3-internal.h
19
index XXXXXXX..XXXXXXX 100644
21
+++ b/hw/arm/smmuv3-internal.h
20
--- a/include/elf.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUEventInfo {
21
+++ b/include/elf.h
23
22
@@ -XXX,XX +XXX,XX @@ typedef struct elf64_shdr {
24
void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
23
#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
25
24
#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
26
+/* Configuration Data */
25
#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */
27
+
26
+#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension regs */
28
+/* STE Level 1 Descriptor */
27
29
+typedef struct STEDesc {
28
/*
30
+ uint32_t word[2];
29
* Physical entry point into the kernel.
31
+} STEDesc;
30
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
+
31
index XXXXXXX..XXXXXXX 100644
33
+/* CD Level 1 Descriptor */
32
--- a/target/arm/cpu.h
34
+typedef struct CDDesc {
33
+++ b/target/arm/cpu.h
35
+ uint32_t word[2];
34
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
36
+} CDDesc;
35
void aarch64_sve_change_el(CPUARMState *env, int old_el,
37
+
36
int new_el, bool el0_a64);
38
+/* Stream Table Entry(STE) */
37
void aarch64_add_sve_properties(Object *obj);
39
+typedef struct STE {
38
+
40
+ uint32_t word[16];
39
+/*
41
+} STE;
40
+ * SVE registers are encoded in KVM's memory in an endianness-invariant format.
42
+
41
+ * The byte at offset i from the start of the in-memory representation contains
43
+/* Context Descriptor(CD) */
42
+ * the bits [(7 + 8 * i) : (8 * i)] of the register value. As this means the
44
+typedef struct CD {
43
+ * lowest offsets are stored in the lowest memory addresses, then that nearly
45
+ uint32_t word[16];
44
+ * matches QEMU's representation, which is to use an array of host-endian
46
+} CD;
45
+ * uint64_t's, where the lower offsets are at the lower indices. To complete
47
+
46
+ * the translation we just need to byte swap the uint64_t's on big-endian hosts.
48
+/* STE fields */
49
+
50
+#define STE_VALID(x) extract32((x)->word[0], 0, 1)
51
+
52
+#define STE_CONFIG(x) extract32((x)->word[0], 1, 3)
53
+#define STE_CFG_S1_ENABLED(config) (config & 0x1)
54
+#define STE_CFG_S2_ENABLED(config) (config & 0x2)
55
+#define STE_CFG_ABORT(config) (!(config & 0x4))
56
+#define STE_CFG_BYPASS(config) (config == 0x4)
57
+
58
+#define STE_S1FMT(x) extract32((x)->word[0], 4 , 2)
59
+#define STE_S1CDMAX(x) extract32((x)->word[1], 27, 5)
60
+#define STE_S1STALLD(x) extract32((x)->word[2], 27, 1)
61
+#define STE_EATS(x) extract32((x)->word[2], 28, 2)
62
+#define STE_STRW(x) extract32((x)->word[2], 30, 2)
63
+#define STE_S2VMID(x) extract32((x)->word[4], 0 , 16)
64
+#define STE_S2T0SZ(x) extract32((x)->word[5], 0 , 6)
65
+#define STE_S2SL0(x) extract32((x)->word[5], 6 , 2)
66
+#define STE_S2TG(x) extract32((x)->word[5], 14, 2)
67
+#define STE_S2PS(x) extract32((x)->word[5], 16, 3)
68
+#define STE_S2AA64(x) extract32((x)->word[5], 19, 1)
69
+#define STE_S2HD(x) extract32((x)->word[5], 24, 1)
70
+#define STE_S2HA(x) extract32((x)->word[5], 25, 1)
71
+#define STE_S2S(x) extract32((x)->word[5], 26, 1)
72
+#define STE_CTXPTR(x) \
73
+ ({ \
74
+ unsigned long addr; \
75
+ addr = (uint64_t)extract32((x)->word[1], 0, 16) << 32; \
76
+ addr |= (uint64_t)((x)->word[0] & 0xffffffc0); \
77
+ addr; \
78
+ })
79
+
80
+#define STE_S2TTB(x) \
81
+ ({ \
82
+ unsigned long addr; \
83
+ addr = (uint64_t)extract32((x)->word[7], 0, 16) << 32; \
84
+ addr |= (uint64_t)((x)->word[6] & 0xfffffff0); \
85
+ addr; \
86
+ })
87
+
88
+static inline int oas2bits(int oas_field)
89
+{
90
+ switch (oas_field) {
91
+ case 0:
92
+ return 32;
93
+ case 1:
94
+ return 36;
95
+ case 2:
96
+ return 40;
97
+ case 3:
98
+ return 42;
99
+ case 4:
100
+ return 44;
101
+ case 5:
102
+ return 48;
103
+ }
104
+ return -1;
105
+}
106
+
107
+static inline int pa_range(STE *ste)
108
+{
109
+ int oas_field = MIN(STE_S2PS(ste), SMMU_IDR5_OAS);
110
+
111
+ if (!STE_S2AA64(ste)) {
112
+ return 40;
113
+ }
114
+
115
+ return oas2bits(oas_field);
116
+}
117
+
118
+#define MAX_PA(ste) ((1 << pa_range(ste)) - 1)
119
+
120
+/* CD fields */
121
+
122
+#define CD_VALID(x) extract32((x)->word[0], 30, 1)
123
+#define CD_ASID(x) extract32((x)->word[1], 16, 16)
124
+#define CD_TTB(x, sel) \
125
+ ({ \
126
+ uint64_t hi, lo; \
127
+ hi = extract32((x)->word[(sel) * 2 + 3], 0, 19); \
128
+ hi <<= 32; \
129
+ lo = (x)->word[(sel) * 2 + 2] & ~0xfULL; \
130
+ hi | lo; \
131
+ })
132
+
133
+#define CD_TSZ(x, sel) extract32((x)->word[0], (16 * (sel)) + 0, 6)
134
+#define CD_TG(x, sel) extract32((x)->word[0], (16 * (sel)) + 6, 2)
135
+#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
136
+#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
137
+#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
138
+#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
139
+#define CD_HD(x) extract32((x)->word[1], 10 , 1)
140
+#define CD_HA(x) extract32((x)->word[1], 11 , 1)
141
+#define CD_S(x) extract32((x)->word[1], 12, 1)
142
+#define CD_R(x) extract32((x)->word[1], 13, 1)
143
+#define CD_A(x) extract32((x)->word[1], 14, 1)
144
+#define CD_AARCH64(x) extract32((x)->word[1], 9 , 1)
145
+
146
+#define CDM_VALID(x) ((x)->word[0] & 0x1)
147
+
148
+static inline int is_cd_valid(SMMUv3State *s, STE *ste, CD *cd)
149
+{
150
+ return CD_VALID(cd);
151
+}
152
+
153
+/**
154
+ * tg2granule - Decodes the CD translation granule size field according
155
+ * to the ttbr in use
156
+ * @bits: TG0/1 fields
157
+ * @ttbr: ttbr index in use
158
+ */
47
+ */
159
+static inline int tg2granule(int bits, int ttbr)
48
+static inline uint64_t *sve_bswap64(uint64_t *dst, uint64_t *src, int nr)
160
+{
49
+{
161
+ switch (bits) {
50
+#ifdef HOST_WORDS_BIGENDIAN
162
+ case 0:
51
+ int i;
163
+ return ttbr ? 0 : 12;
52
+
164
+ case 1:
53
+ for (i = 0; i < nr; ++i) {
165
+ return ttbr ? 14 : 16;
54
+ dst[i] = bswap64(src[i]);
166
+ case 2:
55
+ }
167
+ return ttbr ? 12 : 14;
56
+
168
+ case 3:
57
+ return dst;
169
+ return ttbr ? 16 : 0;
58
+#else
170
+ default:
59
+ return src;
171
+ return 0;
60
+#endif
172
+ }
61
+}
173
+}
62
+
174
+
63
#else
175
+static inline uint64_t l1std_l2ptr(STEDesc *desc)
64
static inline void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq) { }
176
+{
65
static inline void aarch64_sve_change_el(CPUARMState *env, int o,
177
+ uint64_t hi, lo;
66
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
178
+
67
index XXXXXXX..XXXXXXX 100644
179
+ hi = desc->word[1];
68
--- a/target/arm/arch_dump.c
180
+ lo = desc->word[0] & ~0x1fULL;
69
+++ b/target/arm/arch_dump.c
181
+ return hi << 32 | lo;
70
@@ -XXX,XX +XXX,XX @@ struct aarch64_user_vfp_state {
182
+}
71
183
+
72
QEMU_BUILD_BUG_ON(sizeof(struct aarch64_user_vfp_state) != 528);
184
+#define L1STD_SPAN(stm) (extract32((stm)->word[0], 0, 4))
73
185
+
74
+/* struct user_sve_header from arch/arm64/include/uapi/asm/ptrace.h */
186
#endif
75
+struct aarch64_user_sve_header {
187
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
76
+ uint32_t size;
188
index XXXXXXX..XXXXXXX 100644
77
+ uint32_t max_size;
189
--- a/hw/arm/smmuv3.c
78
+ uint16_t vl;
190
+++ b/hw/arm/smmuv3.c
79
+ uint16_t max_vl;
191
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
80
+ uint16_t flags;
192
s->sid_split = 0;
81
+ uint16_t reserved;
82
+} QEMU_PACKED;
83
+
84
struct aarch64_note {
85
Elf64_Nhdr hdr;
86
char name[8]; /* align_up(sizeof("CORE"), 4) */
87
union {
88
struct aarch64_elf_prstatus prstatus;
89
struct aarch64_user_vfp_state vfp;
90
+ struct aarch64_user_sve_header sve;
91
};
92
} QEMU_PACKED;
93
94
@@ -XXX,XX +XXX,XX @@ struct aarch64_note {
95
(AARCH64_NOTE_HEADER_SIZE + sizeof(struct aarch64_elf_prstatus))
96
#define AARCH64_PRFPREG_NOTE_SIZE \
97
(AARCH64_NOTE_HEADER_SIZE + sizeof(struct aarch64_user_vfp_state))
98
+#define AARCH64_SVE_NOTE_SIZE(env) \
99
+ (AARCH64_NOTE_HEADER_SIZE + sve_size(env))
100
101
static void aarch64_note_init(struct aarch64_note *note, DumpState *s,
102
const char *name, Elf64_Word namesz,
103
@@ -XXX,XX +XXX,XX @@ static int aarch64_write_elf64_prfpreg(WriteCoreDumpFunction f,
104
return 0;
193
}
105
}
194
106
195
+static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf,
107
+#ifdef TARGET_AARCH64
196
+ SMMUEventInfo *event)
108
+static off_t sve_zreg_offset(uint32_t vq, int n)
197
+{
109
+{
198
+ int ret;
110
+ off_t off = sizeof(struct aarch64_user_sve_header);
199
+
111
+ return ROUND_UP(off, 16) + vq * 16 * n;
200
+ trace_smmuv3_get_ste(addr);
112
+}
201
+ /* TODO: guarantee 64-bit single-copy atomicity */
113
+
202
+ ret = dma_memory_read(&address_space_memory, addr,
114
+static off_t sve_preg_offset(uint32_t vq, int n)
203
+ (void *)buf, sizeof(*buf));
115
+{
204
+ if (ret != MEMTX_OK) {
116
+ return sve_zreg_offset(vq, 32) + vq * 16 / 8 * n;
205
+ qemu_log_mask(LOG_GUEST_ERROR,
117
+}
206
+ "Cannot fetch pte at address=0x%"PRIx64"\n", addr);
118
+
207
+ event->type = SMMU_EVT_F_STE_FETCH;
119
+static off_t sve_fpsr_offset(uint32_t vq)
208
+ event->u.f_ste_fetch.addr = addr;
120
+{
209
+ return -EINVAL;
121
+ off_t off = sve_preg_offset(vq, 17);
210
+ }
122
+ return ROUND_UP(off, 16);
123
+}
124
+
125
+static off_t sve_fpcr_offset(uint32_t vq)
126
+{
127
+ return sve_fpsr_offset(vq) + sizeof(uint32_t);
128
+}
129
+
130
+static uint32_t sve_current_vq(CPUARMState *env)
131
+{
132
+ return sve_zcr_len_for_el(env, arm_current_el(env)) + 1;
133
+}
134
+
135
+static size_t sve_size_vq(uint32_t vq)
136
+{
137
+ off_t off = sve_fpcr_offset(vq) + sizeof(uint32_t);
138
+ return ROUND_UP(off, 16);
139
+}
140
+
141
+static size_t sve_size(CPUARMState *env)
142
+{
143
+ return sve_size_vq(sve_current_vq(env));
144
+}
145
+
146
+static int aarch64_write_elf64_sve(WriteCoreDumpFunction f,
147
+ CPUARMState *env, int cpuid,
148
+ DumpState *s)
149
+{
150
+ struct aarch64_note *note;
151
+ ARMCPU *cpu = env_archcpu(env);
152
+ uint32_t vq = sve_current_vq(env);
153
+ uint64_t tmp[ARM_MAX_VQ * 2], *r;
154
+ uint32_t fpr;
155
+ uint8_t *buf;
156
+ int ret, i;
157
+
158
+ note = g_malloc0(AARCH64_SVE_NOTE_SIZE(env));
159
+ buf = (uint8_t *)&note->sve;
160
+
161
+ aarch64_note_init(note, s, "LINUX", 6, NT_ARM_SVE, sve_size_vq(vq));
162
+
163
+ note->sve.size = cpu_to_dump32(s, sve_size_vq(vq));
164
+ note->sve.max_size = cpu_to_dump32(s, sve_size_vq(cpu->sve_max_vq));
165
+ note->sve.vl = cpu_to_dump16(s, vq * 16);
166
+ note->sve.max_vl = cpu_to_dump16(s, cpu->sve_max_vq * 16);
167
+ note->sve.flags = cpu_to_dump16(s, 1);
168
+
169
+ for (i = 0; i < 32; ++i) {
170
+ r = sve_bswap64(tmp, &env->vfp.zregs[i].d[0], vq * 2);
171
+ memcpy(&buf[sve_zreg_offset(vq, i)], r, vq * 16);
172
+ }
173
+
174
+ for (i = 0; i < 17; ++i) {
175
+ r = sve_bswap64(tmp, r = &env->vfp.pregs[i].p[0],
176
+ DIV_ROUND_UP(vq * 2, 8));
177
+ memcpy(&buf[sve_preg_offset(vq, i)], r, vq * 16 / 8);
178
+ }
179
+
180
+ fpr = cpu_to_dump32(s, vfp_get_fpsr(env));
181
+ memcpy(&buf[sve_fpsr_offset(vq)], &fpr, sizeof(uint32_t));
182
+
183
+ fpr = cpu_to_dump32(s, vfp_get_fpcr(env));
184
+ memcpy(&buf[sve_fpcr_offset(vq)], &fpr, sizeof(uint32_t));
185
+
186
+ ret = f(note, AARCH64_SVE_NOTE_SIZE(env), s);
187
+ g_free(note);
188
+
189
+ if (ret < 0) {
190
+ return -1;
191
+ }
192
+
211
+ return 0;
193
+ return 0;
212
+
194
+}
213
+}
195
+#endif
214
+
196
+
215
+/* @ssid > 0 not supported yet */
197
int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
216
+static int smmu_get_cd(SMMUv3State *s, STE *ste, uint32_t ssid,
198
int cpuid, void *opaque)
217
+ CD *buf, SMMUEventInfo *event)
199
{
218
+{
200
struct aarch64_note note;
219
+ dma_addr_t addr = STE_CTXPTR(ste);
201
- CPUARMState *env = &ARM_CPU(cs)->env;
220
+ int ret;
202
+ ARMCPU *cpu = ARM_CPU(cs);
221
+
203
+ CPUARMState *env = &cpu->env;
222
+ trace_smmuv3_get_cd(addr);
204
DumpState *s = opaque;
223
+ /* TODO: guarantee 64-bit single-copy atomicity */
205
uint64_t pstate, sp;
224
+ ret = dma_memory_read(&address_space_memory, addr,
206
int ret, i;
225
+ (void *)buf, sizeof(*buf));
207
@@ -XXX,XX +XXX,XX @@ int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
226
+ if (ret != MEMTX_OK) {
208
return -1;
227
+ qemu_log_mask(LOG_GUEST_ERROR,
209
}
228
+ "Cannot fetch pte at address=0x%"PRIx64"\n", addr);
210
229
+ event->type = SMMU_EVT_F_CD_FETCH;
211
- return aarch64_write_elf64_prfpreg(f, env, cpuid, s);
230
+ event->u.f_ste_fetch.addr = addr;
212
+ ret = aarch64_write_elf64_prfpreg(f, env, cpuid, s);
231
+ return -EINVAL;
213
+ if (ret) {
232
+ }
233
+ return 0;
234
+}
235
+
236
+/* Returns <0 if the caller has no need to continue the translation */
237
+static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
238
+ STE *ste, SMMUEventInfo *event)
239
+{
240
+ uint32_t config;
241
+ int ret = -EINVAL;
242
+
243
+ if (!STE_VALID(ste)) {
244
+ goto bad_ste;
245
+ }
246
+
247
+ config = STE_CONFIG(ste);
248
+
249
+ if (STE_CFG_ABORT(config)) {
250
+ cfg->aborted = true; /* abort but don't record any event */
251
+ return ret;
214
+ return ret;
252
+ }
215
+ }
253
+
216
+
254
+ if (STE_CFG_BYPASS(config)) {
217
+#ifdef TARGET_AARCH64
255
+ cfg->bypassed = true;
218
+ if (cpu_isar_feature(aa64_sve, cpu)) {
256
+ return ret;
219
+ ret = aarch64_write_elf64_sve(f, env, cpuid, s);
257
+ }
220
+ }
258
+
221
+#endif
259
+ if (STE_CFG_S2_ENABLED(config)) {
222
+
260
+ qemu_log_mask(LOG_UNIMP, "SMMUv3 does not support stage 2 yet\n");
223
+ return ret;
261
+ goto bad_ste;
224
}
262
+ }
225
263
+
226
/* struct pt_regs from arch/arm/include/asm/ptrace.h */
264
+ if (STE_S1CDMAX(ste) != 0) {
227
@@ -XXX,XX +XXX,XX @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
265
+ qemu_log_mask(LOG_UNIMP,
228
if (class == ELFCLASS64) {
266
+ "SMMUv3 does not support multiple context descriptors yet\n");
229
note_size = AARCH64_PRSTATUS_NOTE_SIZE;
267
+ goto bad_ste;
230
note_size += AARCH64_PRFPREG_NOTE_SIZE;
268
+ }
231
+#ifdef TARGET_AARCH64
269
+
232
+ if (cpu_isar_feature(aa64_sve, cpu)) {
270
+ if (STE_S1STALLD(ste)) {
233
+ note_size += AARCH64_SVE_NOTE_SIZE(env);
271
+ qemu_log_mask(LOG_UNIMP,
272
+ "SMMUv3 S1 stalling fault model not allowed yet\n");
273
+ goto bad_ste;
274
+ }
275
+ return 0;
276
+
277
+bad_ste:
278
+ event->type = SMMU_EVT_C_BAD_STE;
279
+ return -EINVAL;
280
+}
281
+
282
+/**
283
+ * smmu_find_ste - Return the stream table entry associated
284
+ * to the sid
285
+ *
286
+ * @s: smmuv3 handle
287
+ * @sid: stream ID
288
+ * @ste: returned stream table entry
289
+ * @event: handle to an event info
290
+ *
291
+ * Supports linear and 2-level stream table
292
+ * Return 0 on success, -EINVAL otherwise
293
+ */
294
+static int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste,
295
+ SMMUEventInfo *event)
296
+{
297
+ dma_addr_t addr;
298
+ int ret;
299
+
300
+ trace_smmuv3_find_ste(sid, s->features, s->sid_split);
301
+ /* Check SID range */
302
+ if (sid > (1 << SMMU_IDR1_SIDSIZE)) {
303
+ event->type = SMMU_EVT_C_BAD_STREAMID;
304
+ return -EINVAL;
305
+ }
306
+ if (s->features & SMMU_FEATURE_2LVL_STE) {
307
+ int l1_ste_offset, l2_ste_offset, max_l2_ste, span;
308
+ dma_addr_t strtab_base, l1ptr, l2ptr;
309
+ STEDesc l1std;
310
+
311
+ strtab_base = s->strtab_base & SMMU_BASE_ADDR_MASK;
312
+ l1_ste_offset = sid >> s->sid_split;
313
+ l2_ste_offset = sid & ((1 << s->sid_split) - 1);
314
+ l1ptr = (dma_addr_t)(strtab_base + l1_ste_offset * sizeof(l1std));
315
+ /* TODO: guarantee 64-bit single-copy atomicity */
316
+ ret = dma_memory_read(&address_space_memory, l1ptr,
317
+ (uint8_t *)&l1std, sizeof(l1std));
318
+ if (ret != MEMTX_OK) {
319
+ qemu_log_mask(LOG_GUEST_ERROR,
320
+ "Could not read L1PTR at 0X%"PRIx64"\n", l1ptr);
321
+ event->type = SMMU_EVT_F_STE_FETCH;
322
+ event->u.f_ste_fetch.addr = l1ptr;
323
+ return -EINVAL;
324
+ }
234
+ }
325
+
235
+#endif
326
+ span = L1STD_SPAN(&l1std);
236
} else {
327
+
237
note_size = ARM_PRSTATUS_NOTE_SIZE;
328
+ if (!span) {
238
if (arm_feature(env, ARM_FEATURE_VFP)) {
329
+ /* l2ptr is not valid */
239
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
330
+ qemu_log_mask(LOG_GUEST_ERROR,
240
index XXXXXXX..XXXXXXX 100644
331
+ "invalid sid=%d (L1STD span=0)\n", sid);
241
--- a/target/arm/kvm64.c
332
+ event->type = SMMU_EVT_C_BAD_STREAMID;
242
+++ b/target/arm/kvm64.c
333
+ return -EINVAL;
243
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_fpsimd(CPUState *cs)
334
+ }
244
return 0;
335
+ max_l2_ste = (1 << span) - 1;
336
+ l2ptr = l1std_l2ptr(&l1std);
337
+ trace_smmuv3_find_ste_2lvl(s->strtab_base, l1ptr, l1_ste_offset,
338
+ l2ptr, l2_ste_offset, max_l2_ste);
339
+ if (l2_ste_offset > max_l2_ste) {
340
+ qemu_log_mask(LOG_GUEST_ERROR,
341
+ "l2_ste_offset=%d > max_l2_ste=%d\n",
342
+ l2_ste_offset, max_l2_ste);
343
+ event->type = SMMU_EVT_C_BAD_STE;
344
+ return -EINVAL;
345
+ }
346
+ addr = l2ptr + l2_ste_offset * sizeof(*ste);
347
+ } else {
348
+ addr = s->strtab_base + sid * sizeof(*ste);
349
+ }
350
+
351
+ if (smmu_get_ste(s, addr, ste, event)) {
352
+ return -EINVAL;
353
+ }
354
+
355
+ return 0;
356
+}
357
+
358
+static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
359
+{
360
+ int ret = -EINVAL;
361
+ int i;
362
+
363
+ if (!CD_VALID(cd) || !CD_AARCH64(cd)) {
364
+ goto bad_cd;
365
+ }
366
+ if (!CD_A(cd)) {
367
+ goto bad_cd; /* SMMU_IDR0.TERM_MODEL == 1 */
368
+ }
369
+ if (CD_S(cd)) {
370
+ goto bad_cd; /* !STE_SECURE && SMMU_IDR0.STALL_MODEL == 1 */
371
+ }
372
+ if (CD_HA(cd) || CD_HD(cd)) {
373
+ goto bad_cd; /* HTTU = 0 */
374
+ }
375
+
376
+ /* we support only those at the moment */
377
+ cfg->aa64 = true;
378
+ cfg->stage = 1;
379
+
380
+ cfg->oas = oas2bits(CD_IPS(cd));
381
+ cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
382
+ cfg->tbi = CD_TBI(cd);
383
+ cfg->asid = CD_ASID(cd);
384
+
385
+ trace_smmuv3_decode_cd(cfg->oas);
386
+
387
+ /* decode data dependent on TT */
388
+ for (i = 0; i <= 1; i++) {
389
+ int tg, tsz;
390
+ SMMUTransTableInfo *tt = &cfg->tt[i];
391
+
392
+ cfg->tt[i].disabled = CD_EPD(cd, i);
393
+ if (cfg->tt[i].disabled) {
394
+ continue;
395
+ }
396
+
397
+ tsz = CD_TSZ(cd, i);
398
+ if (tsz < 16 || tsz > 39) {
399
+ goto bad_cd;
400
+ }
401
+
402
+ tg = CD_TG(cd, i);
403
+ tt->granule_sz = tg2granule(tg, i);
404
+ if ((tt->granule_sz != 12 && tt->granule_sz != 16) || CD_ENDI(cd)) {
405
+ goto bad_cd;
406
+ }
407
+
408
+ tt->tsz = tsz;
409
+ tt->ttb = CD_TTB(cd, i);
410
+ if (tt->ttb & ~(MAKE_64BIT_MASK(0, cfg->oas))) {
411
+ goto bad_cd;
412
+ }
413
+ trace_smmuv3_decode_cd_tt(i, tt->tsz, tt->ttb, tt->granule_sz);
414
+ }
415
+
416
+ event->record_trans_faults = CD_R(cd);
417
+
418
+ return 0;
419
+
420
+bad_cd:
421
+ event->type = SMMU_EVT_C_BAD_CD;
422
+ return ret;
423
+}
424
+
425
+/**
426
+ * smmuv3_decode_config - Prepare the translation configuration
427
+ * for the @mr iommu region
428
+ * @mr: iommu memory region the translation config must be prepared for
429
+ * @cfg: output translation configuration which is populated through
430
+ * the different configuration decoding steps
431
+ * @event: must be zero'ed by the caller
432
+ *
433
+ * return < 0 if the translation needs to be aborted (@event is filled
434
+ * accordingly). Return 0 otherwise.
435
+ */
436
+static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
437
+ SMMUEventInfo *event)
438
+{
439
+ SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
440
+ uint32_t sid = smmu_get_sid(sdev);
441
+ SMMUv3State *s = sdev->smmu;
442
+ int ret = -EINVAL;
443
+ STE ste;
444
+ CD cd;
445
+
446
+ if (smmu_find_ste(s, sid, &ste, event)) {
447
+ return ret;
448
+ }
449
+
450
+ if (decode_ste(s, cfg, &ste, event)) {
451
+ return ret;
452
+ }
453
+
454
+ if (smmu_get_cd(s, &ste, 0 /* ssid */, &cd, event)) {
455
+ return ret;
456
+ }
457
+
458
+ return decode_cd(cfg, &cd, event);
459
+}
460
+
461
+static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
462
+ IOMMUAccessFlags flag)
463
+{
464
+ SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
465
+ SMMUv3State *s = sdev->smmu;
466
+ uint32_t sid = smmu_get_sid(sdev);
467
+ SMMUEventInfo event = {.type = SMMU_EVT_OK, .sid = sid};
468
+ SMMUPTWEventInfo ptw_info = {};
469
+ SMMUTransCfg cfg = {};
470
+ IOMMUTLBEntry entry = {
471
+ .target_as = &address_space_memory,
472
+ .iova = addr,
473
+ .translated_addr = addr,
474
+ .addr_mask = ~(hwaddr)0,
475
+ .perm = IOMMU_NONE,
476
+ };
477
+ int ret = 0;
478
+
479
+ if (!smmu_enabled(s)) {
480
+ goto out;
481
+ }
482
+
483
+ ret = smmuv3_decode_config(mr, &cfg, &event);
484
+ if (ret) {
485
+ goto out;
486
+ }
487
+
488
+ if (cfg.aborted) {
489
+ goto out;
490
+ }
491
+
492
+ ret = smmu_ptw(&cfg, addr, flag, &entry, &ptw_info);
493
+ if (ret) {
494
+ switch (ptw_info.type) {
495
+ case SMMU_PTW_ERR_WALK_EABT:
496
+ event.type = SMMU_EVT_F_WALK_EABT;
497
+ event.u.f_walk_eabt.addr = addr;
498
+ event.u.f_walk_eabt.rnw = flag & 0x1;
499
+ event.u.f_walk_eabt.class = 0x1;
500
+ event.u.f_walk_eabt.addr2 = ptw_info.addr;
501
+ break;
502
+ case SMMU_PTW_ERR_TRANSLATION:
503
+ if (event.record_trans_faults) {
504
+ event.type = SMMU_EVT_F_TRANSLATION;
505
+ event.u.f_translation.addr = addr;
506
+ event.u.f_translation.rnw = flag & 0x1;
507
+ }
508
+ break;
509
+ case SMMU_PTW_ERR_ADDR_SIZE:
510
+ if (event.record_trans_faults) {
511
+ event.type = SMMU_EVT_F_ADDR_SIZE;
512
+ event.u.f_addr_size.addr = addr;
513
+ event.u.f_addr_size.rnw = flag & 0x1;
514
+ }
515
+ break;
516
+ case SMMU_PTW_ERR_ACCESS:
517
+ if (event.record_trans_faults) {
518
+ event.type = SMMU_EVT_F_ACCESS;
519
+ event.u.f_access.addr = addr;
520
+ event.u.f_access.rnw = flag & 0x1;
521
+ }
522
+ break;
523
+ case SMMU_PTW_ERR_PERMISSION:
524
+ if (event.record_trans_faults) {
525
+ event.type = SMMU_EVT_F_PERMISSION;
526
+ event.u.f_permission.addr = addr;
527
+ event.u.f_permission.rnw = flag & 0x1;
528
+ }
529
+ break;
530
+ default:
531
+ g_assert_not_reached();
532
+ }
533
+ }
534
+out:
535
+ if (ret) {
536
+ qemu_log_mask(LOG_GUEST_ERROR,
537
+ "%s translation failed for iova=0x%"PRIx64"(%d)\n",
538
+ mr->parent_obj.name, addr, ret);
539
+ entry.perm = IOMMU_NONE;
540
+ smmuv3_record_event(s, &event);
541
+ } else if (!cfg.aborted) {
542
+ entry.perm = flag;
543
+ trace_smmuv3_translate(mr->parent_obj.name, sid, addr,
544
+ entry.translated_addr, entry.perm);
545
+ }
546
+
547
+ return entry;
548
+}
549
+
550
static int smmuv3_cmdq_consume(SMMUv3State *s)
551
{
552
SMMUCmdError cmd_error = SMMU_CERROR_NONE;
553
@@ -XXX,XX +XXX,XX @@ static void smmuv3_class_init(ObjectClass *klass, void *data)
554
static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
555
void *data)
556
{
557
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
558
+
559
+ imrc->translate = smmuv3_translate;
560
}
245
}
561
246
562
static const TypeInfo smmuv3_type_info = {
247
-/*
563
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
248
- * SVE registers are encoded in KVM's memory in an endianness-invariant format.
564
index XXXXXXX..XXXXXXX 100644
249
- * The byte at offset i from the start of the in-memory representation contains
565
--- a/hw/arm/trace-events
250
- * the bits [(7 + 8 * i) : (8 * i)] of the register value. As this means the
566
+++ b/hw/arm/trace-events
251
- * lowest offsets are stored in the lowest memory addresses, then that nearly
567
@@ -XXX,XX +XXX,XX @@ smmuv3_write_mmio_idr(uint64_t addr, uint64_t val) "write to RO/Unimpl reg 0x%lx
252
- * matches QEMU's representation, which is to use an array of host-endian
568
smmuv3_write_mmio_evtq_cons_bef_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "Before clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
253
- * uint64_t's, where the lower offsets are at the lower indices. To complete
569
smmuv3_write_mmio_evtq_cons_after_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "after clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
254
- * the translation we just need to byte swap the uint64_t's on big-endian hosts.
570
smmuv3_record_event(const char *type, uint32_t sid) "%s sid=%d"
255
- */
571
+smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "SID:0x%x features:0x%x, sid_split:0x%x"
256
-static uint64_t *sve_bswap64(uint64_t *dst, uint64_t *src, int nr)
572
+smmuv3_find_ste_2lvl(uint64_t strtab_base, uint64_t l1ptr, int l1_ste_offset, uint64_t l2ptr, int l2_ste_offset, int max_l2_ste) "strtab_base:0x%lx l1ptr:0x%"PRIx64" l1_off:0x%x, l2ptr:0x%"PRIx64" l2_off:0x%x max_l2_ste:%d"
257
-{
573
+smmuv3_get_ste(uint64_t addr) "STE addr: 0x%"PRIx64
258
-#ifdef HOST_WORDS_BIGENDIAN
574
+smmuv3_translate_bypass(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d bypass iova:0x%"PRIx64" is_write=%d"
259
- int i;
575
+smmuv3_translate_in(uint16_t sid, int pci_bus_num, uint64_t strtab_base) "SID:0x%x bus:%d strtab_base:0x%"PRIx64
260
-
576
+smmuv3_get_cd(uint64_t addr) "CD addr: 0x%"PRIx64
261
- for (i = 0; i < nr; ++i) {
577
+smmuv3_translate(const char *n, uint16_t sid, uint64_t iova, uint64_t translated, int perm) "%s sid=%d iova=0x%"PRIx64" translated=0x%"PRIx64" perm=0x%x"
262
- dst[i] = bswap64(src[i]);
578
+smmuv3_decode_cd(uint32_t oas) "oas=%d"
263
- }
579
+smmuv3_decode_cd_tt(int i, uint32_t tsz, uint64_t ttb, uint32_t granule_sz) "TT[%d]:tsz:%d ttb:0x%"PRIx64" granule_sz:%d"
264
-
265
- return dst;
266
-#else
267
- return src;
268
-#endif
269
-}
270
-
271
/*
272
* KVM SVE registers come in slices where ZREGs have a slice size of 2048 bits
273
* and PREGS and the FFR have a slice size of 256 bits. However we simply hard
580
--
274
--
581
2.17.0
275
2.20.1
582
276
583
277
diff view generated by jsdifflib
1
From: Prem Mallappa <prem.mallappa@broadcom.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Add code to instantiate an smmuv3 in virt machine. A new iommu
3
Missed in 870c034da0b, hopefully reported by Coverity.
4
integer member is introduced in VirtMachineState to store the type
5
of the iommu in use.
6
4
7
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
5
Fixes: Coverity CID 1412793 (Incorrect expression)
8
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 1524665762-31355-13-git-send-email-eric.auger@redhat.com
8
Reviewed-by: Thomas Huth <thuth@redhat.com>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20200121213853.9601-1-f4bug@amsat.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
include/hw/arm/virt.h | 10 +++++++
13
hw/misc/stm32f4xx_syscfg.c | 2 +-
14
hw/arm/virt.c | 64 ++++++++++++++++++++++++++++++++++++++++++-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
2 files changed, 73 insertions(+), 1 deletion(-)
16
15
17
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
16
diff --git a/hw/misc/stm32f4xx_syscfg.c b/hw/misc/stm32f4xx_syscfg.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/virt.h
18
--- a/hw/misc/stm32f4xx_syscfg.c
20
+++ b/include/hw/arm/virt.h
19
+++ b/hw/misc/stm32f4xx_syscfg.c
21
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void stm32f4xx_syscfg_set_irq(void *opaque, int irq, int level)
22
21
STM32F4xxSyscfgState *s = opaque;
23
#define NUM_GICV2M_SPIS 64
22
int icrreg = irq / 4;
24
#define NUM_VIRTIO_TRANSPORTS 32
23
int startbit = (irq & 3) * 4;
25
+#define NUM_SMMU_IRQS 4
24
- uint8_t config = config = irq / 16;
26
25
+ uint8_t config = irq / 16;
27
#define ARCH_GICV3_MAINT_IRQ 9
26
28
27
trace_stm32f4xx_syscfg_set_irq(irq / 16, irq % 16, level);
29
@@ -XXX,XX +XXX,XX @@ enum {
30
VIRT_GIC_V2M,
31
VIRT_GIC_ITS,
32
VIRT_GIC_REDIST,
33
+ VIRT_SMMU,
34
VIRT_UART,
35
VIRT_MMIO,
36
VIRT_RTC,
37
@@ -XXX,XX +XXX,XX @@ enum {
38
VIRT_SECURE_MEM,
39
};
40
41
+typedef enum VirtIOMMUType {
42
+ VIRT_IOMMU_NONE,
43
+ VIRT_IOMMU_SMMUV3,
44
+ VIRT_IOMMU_VIRTIO,
45
+} VirtIOMMUType;
46
+
47
typedef struct MemMapEntry {
48
hwaddr base;
49
hwaddr size;
50
@@ -XXX,XX +XXX,XX @@ typedef struct {
51
bool its;
52
bool virt;
53
int32_t gic_version;
54
+ VirtIOMMUType iommu;
55
struct arm_boot_info bootinfo;
56
const MemMapEntry *memmap;
57
const int *irqmap;
58
@@ -XXX,XX +XXX,XX @@ typedef struct {
59
uint32_t clock_phandle;
60
uint32_t gic_phandle;
61
uint32_t msi_phandle;
62
+ uint32_t iommu_phandle;
63
int psci_conduit;
64
} VirtMachineState;
65
66
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/virt.c
69
+++ b/hw/arm/virt.c
70
@@ -XXX,XX +XXX,XX @@
71
#include "hw/smbios/smbios.h"
72
#include "qapi/visitor.h"
73
#include "standard-headers/linux/input.h"
74
+#include "hw/arm/smmuv3.h"
75
76
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
77
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
78
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry a15memmap[] = {
79
[VIRT_FW_CFG] = { 0x09020000, 0x00000018 },
80
[VIRT_GPIO] = { 0x09030000, 0x00001000 },
81
[VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
82
+ [VIRT_SMMU] = { 0x09050000, 0x00020000 },
83
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
84
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
85
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
86
@@ -XXX,XX +XXX,XX @@ static const int a15irqmap[] = {
87
[VIRT_SECURE_UART] = 8,
88
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
89
[VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
90
+ [VIRT_SMMU] = 74, /* ...to 74 + NUM_SMMU_IRQS - 1 */
91
[VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */
92
};
93
94
@@ -XXX,XX +XXX,XX @@ static void create_pcie_irq_map(const VirtMachineState *vms,
95
0x7 /* PCI irq */);
96
}
97
98
-static void create_pcie(const VirtMachineState *vms, qemu_irq *pic)
99
+static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
100
+ PCIBus *bus)
101
+{
102
+ char *node;
103
+ const char compat[] = "arm,smmu-v3";
104
+ int irq = vms->irqmap[VIRT_SMMU];
105
+ int i;
106
+ hwaddr base = vms->memmap[VIRT_SMMU].base;
107
+ hwaddr size = vms->memmap[VIRT_SMMU].size;
108
+ const char irq_names[] = "eventq\0priq\0cmdq-sync\0gerror";
109
+ DeviceState *dev;
110
+
111
+ if (vms->iommu != VIRT_IOMMU_SMMUV3 || !vms->iommu_phandle) {
112
+ return;
113
+ }
114
+
115
+ dev = qdev_create(NULL, "arm-smmuv3");
116
+
117
+ object_property_set_link(OBJECT(dev), OBJECT(bus), "primary-bus",
118
+ &error_abort);
119
+ qdev_init_nofail(dev);
120
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
121
+ for (i = 0; i < NUM_SMMU_IRQS; i++) {
122
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
123
+ }
124
+
125
+ node = g_strdup_printf("/smmuv3@%" PRIx64, base);
126
+ qemu_fdt_add_subnode(vms->fdt, node);
127
+ qemu_fdt_setprop(vms->fdt, node, "compatible", compat, sizeof(compat));
128
+ qemu_fdt_setprop_sized_cells(vms->fdt, node, "reg", 2, base, 2, size);
129
+
130
+ qemu_fdt_setprop_cells(vms->fdt, node, "interrupts",
131
+ GIC_FDT_IRQ_TYPE_SPI, irq , GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
132
+ GIC_FDT_IRQ_TYPE_SPI, irq + 1, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
133
+ GIC_FDT_IRQ_TYPE_SPI, irq + 2, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
134
+ GIC_FDT_IRQ_TYPE_SPI, irq + 3, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
135
+
136
+ qemu_fdt_setprop(vms->fdt, node, "interrupt-names", irq_names,
137
+ sizeof(irq_names));
138
+
139
+ qemu_fdt_setprop_cell(vms->fdt, node, "clocks", vms->clock_phandle);
140
+ qemu_fdt_setprop_string(vms->fdt, node, "clock-names", "apb_pclk");
141
+ qemu_fdt_setprop(vms->fdt, node, "dma-coherent", NULL, 0);
142
+
143
+ qemu_fdt_setprop_cell(vms->fdt, node, "#iommu-cells", 1);
144
+
145
+ qemu_fdt_setprop_cell(vms->fdt, node, "phandle", vms->iommu_phandle);
146
+ g_free(node);
147
+}
148
+
149
+static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
150
{
151
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
152
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
153
@@ -XXX,XX +XXX,XX @@ static void create_pcie(const VirtMachineState *vms, qemu_irq *pic)
154
qemu_fdt_setprop_cell(vms->fdt, nodename, "#interrupt-cells", 1);
155
create_pcie_irq_map(vms, vms->gic_phandle, irq, nodename);
156
157
+ if (vms->iommu) {
158
+ vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt);
159
+
160
+ create_smmu(vms, pic, pci->bus);
161
+
162
+ qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map",
163
+ 0x0, vms->iommu_phandle, 0x0, 0x10000);
164
+ }
165
+
166
g_free(nodename);
167
}
168
28
169
--
29
--
170
2.17.0
30
2.20.1
171
31
172
32
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
We introduce some helpers to handle wired IRQs and especially
3
Replace debug logging code with tracing.
4
GERROR interrupt. SMMU writes GERROR register on GERROR event
4
5
and SW acks GERROR interrupts by setting GERRORn.
6
7
The Wired interrupts are edge sensitive hence the pulse usage.
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1524665762-31355-6-git-send-email-eric.auger@redhat.com
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
7
Message-id: 20200123052540.6132-2-linux@roeck-us.net
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
9
---
15
hw/arm/smmuv3-internal.h | 14 +++++++++
10
hw/dma/pl330.c | 88 ++++++++++++++++++++++++---------------------
16
hw/arm/smmuv3.c | 64 ++++++++++++++++++++++++++++++++++++++++
11
hw/dma/trace-events | 24 +++++++++++++
17
hw/arm/trace-events | 3 ++
12
2 files changed, 72 insertions(+), 40 deletions(-)
18
3 files changed, 81 insertions(+)
13
19
14
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
20
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/smmuv3-internal.h
16
--- a/hw/dma/pl330.c
23
+++ b/hw/arm/smmuv3-internal.h
17
+++ b/hw/dma/pl330.c
24
@@ -XXX,XX +XXX,XX @@ static inline uint32_t smmuv3_idreg(int regoffset)
18
@@ -XXX,XX +XXX,XX @@
25
return smmuv3_ids[regoffset / 4];
19
#include "sysemu/dma.h"
26
}
20
#include "qemu/log.h"
27
21
#include "qemu/module.h"
28
+static inline bool smmuv3_eventq_irq_enabled(SMMUv3State *s)
22
+#include "trace.h"
23
24
#ifndef PL330_ERR_DEBUG
25
#define PL330_ERR_DEBUG 0
26
#endif
27
28
-#define DB_PRINT_L(lvl, fmt, args...) do {\
29
- if (PL330_ERR_DEBUG >= lvl) {\
30
- fprintf(stderr, "PL330: %s:" fmt, __func__, ## args);\
31
- } \
32
-} while (0)
33
-
34
-#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
35
-
36
#define PL330_PERIPH_NUM 32
37
#define PL330_MAX_BURST_LEN 128
38
#define PL330_INSN_MAXSIZE 6
39
@@ -XXX,XX +XXX,XX @@ typedef struct PL330InsnDesc {
40
void (*exec)(PL330Chan *, uint8_t opcode, uint8_t *args, int len);
41
} PL330InsnDesc;
42
43
+static void pl330_hexdump(uint8_t *buf, size_t size)
29
+{
44
+{
30
+ return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN);
45
+ unsigned int b, i, len;
31
+}
46
+ char tmpbuf[80];
32
+
47
+
33
+static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
48
+ for (b = 0; b < size; b += 16) {
34
+{
49
+ len = size - b;
35
+ return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN);
50
+ if (len > 16) {
36
+}
51
+ len = 16;
37
+
38
+/* public until callers get introduced */
39
+void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask);
40
+void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn);
41
+
42
#endif
43
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/arm/smmuv3.c
46
+++ b/hw/arm/smmuv3.c
47
@@ -XXX,XX +XXX,XX @@
48
#include "hw/arm/smmuv3.h"
49
#include "smmuv3-internal.h"
50
51
+/**
52
+ * smmuv3_trigger_irq - pulse @irq if enabled and update
53
+ * GERROR register in case of GERROR interrupt
54
+ *
55
+ * @irq: irq type
56
+ * @gerror_mask: mask of gerrors to toggle (relevant if @irq is GERROR)
57
+ */
58
+void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask)
59
+{
60
+
61
+ bool pulse = false;
62
+
63
+ switch (irq) {
64
+ case SMMU_IRQ_EVTQ:
65
+ pulse = smmuv3_eventq_irq_enabled(s);
66
+ break;
67
+ case SMMU_IRQ_PRIQ:
68
+ qemu_log_mask(LOG_UNIMP, "PRI not yet supported\n");
69
+ break;
70
+ case SMMU_IRQ_CMD_SYNC:
71
+ pulse = true;
72
+ break;
73
+ case SMMU_IRQ_GERROR:
74
+ {
75
+ uint32_t pending = s->gerror ^ s->gerrorn;
76
+ uint32_t new_gerrors = ~pending & gerror_mask;
77
+
78
+ if (!new_gerrors) {
79
+ /* only toggle non pending errors */
80
+ return;
81
+ }
52
+ }
82
+ s->gerror ^= new_gerrors;
53
+ tmpbuf[0] = '\0';
83
+ trace_smmuv3_write_gerror(new_gerrors, s->gerror);
54
+ for (i = 0; i < len; i++) {
84
+
55
+ if ((i % 4) == 0) {
85
+ pulse = smmuv3_gerror_irq_enabled(s);
56
+ strcat(tmpbuf, " ");
86
+ break;
57
+ }
87
+ }
58
+ sprintf(tmpbuf + strlen(tmpbuf), " %02x", buf[b + i]);
88
+ }
59
+ }
89
+ if (pulse) {
60
+ trace_pl330_hexdump(b, tmpbuf);
90
+ trace_smmuv3_trigger_irq(irq);
91
+ qemu_irq_pulse(s->irq[irq]);
92
+ }
61
+ }
93
+}
62
+}
63
64
/* MFIFO Implementation
65
*
66
@@ -XXX,XX +XXX,XX @@ static inline void pl330_queue_remove_tagged(PL330Queue *s, uint8_t tag)
67
68
static inline void pl330_fault(PL330Chan *ch, uint32_t flags)
69
{
70
- DB_PRINT("ch: %p, flags: %" PRIx32 "\n", ch, flags);
71
+ trace_pl330_fault(ch, flags);
72
ch->fault_type |= flags;
73
if (ch->state == pl330_chan_fault) {
74
return;
75
@@ -XXX,XX +XXX,XX @@ static inline void pl330_fault(PL330Chan *ch, uint32_t flags)
76
ch->state = pl330_chan_fault;
77
ch->parent->num_faulting++;
78
if (ch->parent->num_faulting == 1) {
79
- DB_PRINT("abort interrupt raised\n");
80
+ trace_pl330_fault_abort();
81
qemu_irq_raise(ch->parent->irq_abort);
82
}
83
}
84
@@ -XXX,XX +XXX,XX @@ static void pl330_dmaend(PL330Chan *ch, uint8_t opcode,
85
return;
86
}
87
}
88
- DB_PRINT("DMA ending!\n");
89
+ trace_pl330_dmaend();
90
pl330_fifo_tagged_remove(&s->fifo, ch->tag);
91
pl330_queue_remove_tagged(&s->read_queue, ch->tag);
92
pl330_queue_remove_tagged(&s->write_queue, ch->tag);
93
@@ -XXX,XX +XXX,XX @@ static void pl330_dmago(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
94
uint32_t pc;
95
PL330Chan *s;
96
97
- DB_PRINT("\n");
98
+ trace_pl330_dmago();
99
100
if (!ch->is_manager) {
101
pl330_fault(ch, PL330_FAULT_UNDEF_INSTR);
102
@@ -XXX,XX +XXX,XX @@ static void pl330_dmald(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
103
ch->stall = pl330_queue_put_insn(&ch->parent->read_queue, ch->src,
104
size, num, inc, 0, ch->tag);
105
if (!ch->stall) {
106
- DB_PRINT("channel:%" PRId8 " address:%08" PRIx32 " size:%" PRIx32
107
- " num:%" PRId32 " %c\n",
108
- ch->tag, ch->src, size, num, inc ? 'Y' : 'N');
109
+ trace_pl330_dmald(ch->tag, ch->src, size, num, inc ? 'Y' : 'N');
110
ch->src += inc ? size * num - (ch->src & (size - 1)) : 0;
111
}
112
}
113
@@ -XXX,XX +XXX,XX @@ static void pl330_dmakill(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
114
ch->fault_type = 0;
115
ch->parent->num_faulting--;
116
if (ch->parent->num_faulting == 0) {
117
- DB_PRINT("abort interrupt lowered\n");
118
+ trace_pl330_dmakill();
119
qemu_irq_lower(ch->parent->irq_abort);
120
}
121
}
122
@@ -XXX,XX +XXX,XX @@ static void pl330_dmalpend(PL330Chan *ch, uint8_t opcode,
123
uint8_t bs = opcode & 3;
124
uint8_t lc = (opcode & 4) >> 2;
125
126
+ trace_pl330_dmalpend(nf, bs, lc, ch->lc[lc], ch->request_flag);
94
+
127
+
95
+void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
128
if (bs == 2) {
96
+{
129
pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
97
+ uint32_t pending = s->gerror ^ s->gerrorn;
130
return;
98
+ uint32_t toggled = s->gerrorn ^ new_gerrorn;
131
@@ -XXX,XX +XXX,XX @@ static void pl330_dmalpend(PL330Chan *ch, uint8_t opcode,
132
if (nf) {
133
ch->lc[lc]--;
134
}
135
- DB_PRINT("loop reiteration\n");
136
+ trace_pl330_dmalpiter();
137
ch->pc -= args[0];
138
ch->pc -= len + 1;
139
/* "ch->pc -= args[0] + len + 1" is incorrect when args[0] == 256 */
140
} else {
141
- DB_PRINT("loop fallthrough\n");
142
+ trace_pl330_dmalpfallthrough();
143
}
144
}
145
146
@@ -XXX,XX +XXX,XX @@ static void pl330_dmasev(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
147
}
148
if (ch->parent->inten & (1 << ev_id)) {
149
ch->parent->int_status |= (1 << ev_id);
150
- DB_PRINT("event interrupt raised %" PRId8 "\n", ev_id);
151
+ trace_pl330_dmasev_evirq(ev_id);
152
qemu_irq_raise(ch->parent->irq[ev_id]);
153
}
154
- DB_PRINT("event raised %" PRId8 "\n", ev_id);
155
+ trace_pl330_dmasev_event(ev_id);
156
ch->parent->ev_status |= (1 << ev_id);
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static void pl330_dmast(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
160
ch->stall = pl330_queue_put_insn(&ch->parent->write_queue, ch->dst,
161
size, num, inc, 0, ch->tag);
162
if (!ch->stall) {
163
- DB_PRINT("channel:%" PRId8 " address:%08" PRIx32 " size:%" PRIx32
164
- " num:%" PRId32 " %c\n",
165
- ch->tag, ch->dst, size, num, inc ? 'Y' : 'N');
166
+ trace_pl330_dmast(ch->tag, ch->dst, size, num, inc ? 'Y' : 'N');
167
ch->dst += inc ? size * num - (ch->dst & (size - 1)) : 0;
168
}
169
}
170
@@ -XXX,XX +XXX,XX @@ static void pl330_dmawfe(PL330Chan *ch, uint8_t opcode,
171
}
172
}
173
ch->parent->ev_status &= ~(1 << ev_id);
174
- DB_PRINT("event lowered %" PRIx8 "\n", ev_id);
175
+ trace_pl330_dmawfe(ev_id);
176
} else {
177
ch->stall = 1;
178
}
179
@@ -XXX,XX +XXX,XX @@ static int pl330_chan_exec(PL330Chan *ch)
180
ch->stall = 0;
181
insn = pl330_fetch_insn(ch);
182
if (!insn) {
183
- DB_PRINT("pl330 undefined instruction\n");
184
+ trace_pl330_chan_exec_undef();
185
pl330_fault(ch, PL330_FAULT_UNDEF_INSTR);
186
return 0;
187
}
188
@@ -XXX,XX +XXX,XX @@ static int pl330_exec_cycle(PL330Chan *channel)
189
int len = q->len - (q->addr & (q->len - 1));
190
191
dma_memory_read(&address_space_memory, q->addr, buf, len);
192
- if (PL330_ERR_DEBUG > 1) {
193
- DB_PRINT("PL330 read from memory @%08" PRIx32 " (size = %08x):\n",
194
- q->addr, len);
195
- qemu_hexdump((char *)buf, stderr, "", len);
196
+ trace_pl330_exec_cycle(q->addr, len);
197
+ if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) {
198
+ pl330_hexdump(buf, len);
199
}
200
fifo_res = pl330_fifo_push(&s->fifo, buf, len, q->tag);
201
if (fifo_res == PL330_FIFO_OK) {
202
@@ -XXX,XX +XXX,XX @@ static int pl330_exec_cycle(PL330Chan *channel)
203
}
204
if (fifo_res == PL330_FIFO_OK || q->z) {
205
dma_memory_write(&address_space_memory, q->addr, buf, len);
206
- if (PL330_ERR_DEBUG > 1) {
207
- DB_PRINT("PL330 read from memory @%08" PRIx32
208
- " (size = %08x):\n", q->addr, len);
209
- qemu_hexdump((char *)buf, stderr, "", len);
210
+ trace_pl330_exec_cycle(q->addr, len);
211
+ if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) {
212
+ pl330_hexdump(buf, len);
213
}
214
if (q->inc) {
215
q->addr += len;
216
@@ -XXX,XX +XXX,XX @@ static int pl330_exec_channel(PL330Chan *channel)
217
218
static inline void pl330_exec(PL330State *s)
219
{
220
- DB_PRINT("\n");
221
int i, insr_exec;
222
+ trace_pl330_exec();
223
do {
224
insr_exec = pl330_exec_channel(&s->manager);
225
226
@@ -XXX,XX +XXX,XX @@ static void pl330_debug_exec(PL330State *s)
227
args[2] = (s->dbg[1] >> 8) & 0xff;
228
args[3] = (s->dbg[1] >> 16) & 0xff;
229
args[4] = (s->dbg[1] >> 24) & 0xff;
230
- DB_PRINT("chan id: %" PRIx8 "\n", chan_id);
231
+ trace_pl330_debug_exec(chan_id);
232
if (s->dbg[0] & 1) {
233
ch = &s->chan[chan_id];
234
} else {
235
@@ -XXX,XX +XXX,XX @@ static void pl330_debug_exec(PL330State *s)
236
ch->fault_type |= PL330_FAULT_DBG_INSTR;
237
}
238
if (ch->stall) {
239
+ trace_pl330_debug_exec_stall();
240
qemu_log_mask(LOG_UNIMP, "pl330: stall of debug instruction not "
241
"implemented\n");
242
}
243
@@ -XXX,XX +XXX,XX @@ static void pl330_iomem_write(void *opaque, hwaddr offset,
244
PL330State *s = (PL330State *) opaque;
245
int i;
246
247
- DB_PRINT("addr: %08x data: %08x\n", (unsigned)offset, (unsigned)value);
248
+ trace_pl330_iomem_write((unsigned)offset, (unsigned)value);
249
250
switch (offset) {
251
case PL330_REG_INTEN:
252
@@ -XXX,XX +XXX,XX @@ static void pl330_iomem_write(void *opaque, hwaddr offset,
253
case PL330_REG_INTCLR:
254
for (i = 0; i < s->num_events; i++) {
255
if (s->int_status & s->inten & value & (1 << i)) {
256
- DB_PRINT("event interrupt lowered %d\n", i);
257
+ trace_pl330_iomem_write_clr(i);
258
qemu_irq_lower(s->irq[i]);
259
}
260
}
261
@@ -XXX,XX +XXX,XX @@ static void pl330_iomem_write(void *opaque, hwaddr offset,
262
}
263
break;
264
case PL330_REG_DBGINST0:
265
- DB_PRINT("s->dbg[0] = %08x\n", (unsigned)value);
266
s->dbg[0] = value;
267
break;
268
case PL330_REG_DBGINST1:
269
- DB_PRINT("s->dbg[1] = %08x\n", (unsigned)value);
270
s->dbg[1] = value;
271
break;
272
default:
273
@@ -XXX,XX +XXX,XX @@ static uint64_t pl330_iomem_read(void *opaque, hwaddr offset,
274
unsigned size)
275
{
276
uint32_t ret = pl330_iomem_read_imp(opaque, offset);
277
- DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx32 "\n", offset, ret);
278
+ trace_pl330_iomem_read((uint32_t)offset, ret);
279
return ret;
280
}
281
282
diff --git a/hw/dma/trace-events b/hw/dma/trace-events
283
index XXXXXXX..XXXXXXX 100644
284
--- a/hw/dma/trace-events
285
+++ b/hw/dma/trace-events
286
@@ -XXX,XX +XXX,XX @@ sparc32_dma_enable_lower(void) "Lower DMA enable"
287
288
# i8257.c
289
i8257_unregistered_dma(int nchan, int dma_pos, int dma_len) "unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d"
99
+
290
+
100
+ if (toggled & ~pending) {
291
+# pl330.c
101
+ qemu_log_mask(LOG_GUEST_ERROR,
292
+pl330_fault(void *ptr, uint32_t flags) "ch: %p, flags: 0x%"PRIx32
102
+ "guest toggles non pending errors = 0x%x\n",
293
+pl330_fault_abort(void) "abort interrupt raised"
103
+ toggled & ~pending);
294
+pl330_dmaend(void) "DMA ending"
104
+ }
295
+pl330_dmago(void) "DMA run"
105
+
296
+pl330_dmald(uint32_t chan, uint32_t addr, uint32_t size, uint32_t num, uint32_t ch) "channel:%"PRId8" address:0x%08"PRIx32" size:0x%"PRIx32" num:%"PRId32"%c"
106
+ /*
297
+pl330_dmakill(void) "abort interrupt lowered"
107
+ * We do not raise any error in case guest toggles bits corresponding
298
+pl330_dmalpend(uint8_t nf, uint8_t bs, uint8_t lc, uint8_t ch, uint8_t flag) "nf=0x%02x bs=0x%02x lc=0x%02x ch=0x%02x flag=0x%02x"
108
+ * to not active IRQs (CONSTRAINED UNPREDICTABLE)
299
+pl330_dmalpiter(void) "loop reiteration"
109
+ */
300
+pl330_dmalpfallthrough(void) "loop fallthrough"
110
+ s->gerrorn = new_gerrorn;
301
+pl330_dmasev_evirq(uint8_t ev_id) "event interrupt raised %"PRId8
111
+
302
+pl330_dmasev_event(uint8_t ev_id) "event raised %"PRId8
112
+ trace_smmuv3_write_gerrorn(toggled & pending, s->gerrorn);
303
+pl330_dmast(uint32_t chn, uint32_t addr, uint32_t sz, uint32_t num, uint32_t c) "channel:%"PRId8" address:0x%08"PRIx32" size:0x%"PRIx32" num:%"PRId32" %c"
113
+}
304
+pl330_dmawfe(uint8_t ev_id) "event lowered 0x%"PRIx8
114
+
305
+pl330_chan_exec_undef(void) "undefined instruction"
115
static void smmuv3_init_regs(SMMUv3State *s)
306
+pl330_exec_cycle(uint32_t addr, uint32_t size) "PL330 read from memory @0x%08"PRIx32" (size = 0x%08"PRIx32")"
116
{
307
+pl330_hexdump(uint32_t offset, char *str) " 0x%04"PRIx32":%s"
117
/**
308
+pl330_exec(void) "pl330_exec"
118
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
309
+pl330_debug_exec(uint8_t ch) "chan id: 0x%"PRIx8
119
index XXXXXXX..XXXXXXX 100644
310
+pl330_debug_exec_stall(void) "stall of debug instruction not implemented"
120
--- a/hw/arm/trace-events
311
+pl330_iomem_write(uint32_t offset, uint32_t value) "addr: 0x%08"PRIx32" data: 0x%08"PRIx32
121
+++ b/hw/arm/trace-events
312
+pl330_iomem_write_clr(int i) "event interrupt lowered %d"
122
@@ -XXX,XX +XXX,XX @@ smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, uint64_t pte) "base
313
+pl330_iomem_read(uint32_t addr, uint32_t data) "addr: 0x%08"PRIx32" data: 0x%08"PRIx32
123
124
#hw/arm/smmuv3.c
125
smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
126
+smmuv3_trigger_irq(int irq) "irq=%d"
127
+smmuv3_write_gerror(uint32_t toggled, uint32_t gerror) "toggled=0x%x, new GERROR=0x%x"
128
+smmuv3_write_gerrorn(uint32_t acked, uint32_t gerrorn) "acked=0x%x, new GERRORN=0x%x"
129
--
314
--
130
2.17.0
315
2.20.1
131
316
132
317
diff view generated by jsdifflib
1
Convert the tusb6010 device away from using the old_mmio field
1
From: Guenter Roeck <linux@roeck-us.net>
2
of MemoryRegionOps. This device is used only in the n800 and n810
3
boards.
4
2
3
Exynos DMA requires up to 33 interrupt lines (32 event interrupts
4
plus abort interrupt), which all need to be wired together. Increase
5
the maximum number of or-irq lines to 48 to support this configuration.
6
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20200123052540.6132-3-linux@roeck-us.net
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20180427173611.10281-2-peter.maydell@linaro.org
8
---
11
---
9
hw/usb/tusb6010.c | 40 ++++++++++++++++++++++++++++++++++++----
12
include/hw/or-irq.h | 2 +-
10
1 file changed, 36 insertions(+), 4 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
11
14
12
diff --git a/hw/usb/tusb6010.c b/hw/usb/tusb6010.c
15
diff --git a/include/hw/or-irq.h b/include/hw/or-irq.h
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/usb/tusb6010.c
17
--- a/include/hw/or-irq.h
15
+++ b/hw/usb/tusb6010.c
18
+++ b/include/hw/or-irq.h
16
@@ -XXX,XX +XXX,XX @@ static void tusb_async_writew(void *opaque, hwaddr addr,
19
@@ -XXX,XX +XXX,XX @@
17
}
20
/* This can safely be increased if necessary without breaking
18
}
21
* migration compatibility (as long as it remains greater than 15).
19
22
*/
20
+static uint64_t tusb_async_readfn(void *opaque, hwaddr addr, unsigned size)
23
-#define MAX_OR_LINES 32
21
+{
24
+#define MAX_OR_LINES 48
22
+ switch (size) {
25
23
+ case 1:
26
typedef struct OrIRQState qemu_or_irq;
24
+ return tusb_async_readb(opaque, addr);
25
+ case 2:
26
+ return tusb_async_readh(opaque, addr);
27
+ case 4:
28
+ return tusb_async_readw(opaque, addr);
29
+ default:
30
+ g_assert_not_reached();
31
+ }
32
+}
33
+
34
+static void tusb_async_writefn(void *opaque, hwaddr addr,
35
+ uint64_t value, unsigned size)
36
+{
37
+ switch (size) {
38
+ case 1:
39
+ tusb_async_writeb(opaque, addr, value);
40
+ break;
41
+ case 2:
42
+ tusb_async_writeh(opaque, addr, value);
43
+ break;
44
+ case 4:
45
+ tusb_async_writew(opaque, addr, value);
46
+ break;
47
+ default:
48
+ g_assert_not_reached();
49
+ }
50
+}
51
+
52
static const MemoryRegionOps tusb_async_ops = {
53
- .old_mmio = {
54
- .read = { tusb_async_readb, tusb_async_readh, tusb_async_readw, },
55
- .write = { tusb_async_writeb, tusb_async_writeh, tusb_async_writew, },
56
- },
57
+ .read = tusb_async_readfn,
58
+ .write = tusb_async_writefn,
59
+ .valid.min_access_size = 1,
60
+ .valid.max_access_size = 4,
61
.endianness = DEVICE_NATIVE_ENDIAN,
62
};
63
27
64
--
28
--
65
2.17.0
29
2.20.1
66
30
67
31
diff view generated by jsdifflib
1
Convert the smc91c111 device away from using the old_mmio field of
1
From: Guenter Roeck <linux@roeck-us.net>
2
MemoryRegionOps. This device is used by several Arm board models.
3
2
3
First parameter to exynos4210_get_irq() is not the SPI port number,
4
but the interrupt group number. Interrupt groups are 20 for mdma
5
and 21 for pdma. Interrupts are not inverted. Controllers support 32
6
events (pdma) or 31 events (mdma). Events must all be routed to a single
7
interrupt line. Set other parameters as documented in Exynos4210 datasheet,
8
section 8 (DMA controller).
9
10
Fixes: 59520dc65e ("hw/arm/exynos4210: Add DMA support for the Exynos4210")
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
13
Message-id: 20200123052540.6132-4-linux@roeck-us.net
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180427173611.10281-3-peter.maydell@linaro.org
7
---
15
---
8
hw/net/smc91c111.c | 54 +++++++++++++++++++++-------------------------
16
include/hw/arm/exynos4210.h | 4 +++
9
1 file changed, 25 insertions(+), 29 deletions(-)
17
hw/arm/exynos4210.c | 51 +++++++++++++++++++++++++++++++------
18
2 files changed, 47 insertions(+), 8 deletions(-)
10
19
11
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
20
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/net/smc91c111.c
22
--- a/include/hw/arm/exynos4210.h
14
+++ b/hw/net/smc91c111.c
23
+++ b/include/hw/arm/exynos4210.h
15
@@ -XXX,XX +XXX,XX @@ static uint32_t smc91c111_readb(void *opaque, hwaddr offset)
24
@@ -XXX,XX +XXX,XX @@
16
return 0;
25
#ifndef EXYNOS4210_H
26
#define EXYNOS4210_H
27
28
+#include "hw/or-irq.h"
29
#include "hw/sysbus.h"
30
#include "target/arm/cpu-qom.h"
31
32
@@ -XXX,XX +XXX,XX @@
33
34
#define EXYNOS4210_I2C_NUMBER 9
35
36
+#define EXYNOS4210_NUM_DMA 3
37
+
38
typedef struct Exynos4210Irq {
39
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
40
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
41
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210State {
42
MemoryRegion boot_secondary;
43
MemoryRegion bootreg_mem;
44
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
45
+ qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
46
} Exynos4210State;
47
48
#define TYPE_EXYNOS4210_SOC "exynos4210"
49
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/exynos4210.c
52
+++ b/hw/arm/exynos4210.c
53
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_calc_affinity(int cpu)
54
return (0x9 << ARM_AFF1_SHIFT) | cpu;
17
}
55
}
18
56
19
-static void smc91c111_writew(void *opaque, hwaddr offset,
57
-static void pl330_create(uint32_t base, qemu_irq irq, int nreq)
20
- uint32_t value)
58
+static void pl330_create(uint32_t base, qemu_or_irq *orgate, qemu_irq irq,
21
+static uint64_t smc91c111_readfn(void *opaque, hwaddr addr, unsigned size)
59
+ int nreq, int nevents, int width)
22
{
60
{
23
- smc91c111_writeb(opaque, offset, value & 0xff);
61
SysBusDevice *busdev;
24
- smc91c111_writeb(opaque, offset + 1, value >> 8);
62
DeviceState *dev;
25
+ int i;
63
+ int i;
26
+ uint32_t val = 0;
64
65
dev = qdev_create(NULL, "pl330");
66
+ qdev_prop_set_uint8(dev, "num_events", nevents);
67
+ qdev_prop_set_uint8(dev, "num_chnls", 8);
68
qdev_prop_set_uint8(dev, "num_periph_req", nreq);
27
+
69
+
28
+ for (i = 0; i < size; i++) {
70
+ qdev_prop_set_uint8(dev, "wr_cap", 4);
29
+ val |= smc91c111_readb(opaque, addr + i) << (i * 8);
71
+ qdev_prop_set_uint8(dev, "wr_q_dep", 8);
72
+ qdev_prop_set_uint8(dev, "rd_cap", 4);
73
+ qdev_prop_set_uint8(dev, "rd_q_dep", 8);
74
+ qdev_prop_set_uint8(dev, "data_width", width);
75
+ qdev_prop_set_uint16(dev, "data_buffer_dep", width);
76
qdev_init_nofail(dev);
77
busdev = SYS_BUS_DEVICE(dev);
78
sysbus_mmio_map(busdev, 0, base);
79
- sysbus_connect_irq(busdev, 0, irq);
80
+
81
+ object_property_set_int(OBJECT(orgate), nevents + 1, "num-lines",
82
+ &error_abort);
83
+ object_property_set_bool(OBJECT(orgate), true, "realized", &error_abort);
84
+
85
+ for (i = 0; i < nevents + 1; i++) {
86
+ sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i));
30
+ }
87
+ }
31
+ return val;
88
+ qdev_connect_gpio_out(DEVICE(orgate), 0, irq);
32
}
89
}
33
90
34
-static void smc91c111_writel(void *opaque, hwaddr offset,
91
static void exynos4210_realize(DeviceState *socdev, Error **errp)
35
- uint32_t value)
92
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
36
+static void smc91c111_writefn(void *opaque, hwaddr addr,
93
s->irq_table[exynos4210_get_irq(28, 3)]);
37
+ uint64_t value, unsigned size)
94
38
{
95
/*** DMA controllers ***/
39
+ int i = 0;
96
- pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
97
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(35, 1)]), 32);
98
- pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
99
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(36, 1)]), 32);
100
- pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
101
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(34, 1)]), 1);
102
+ pl330_create(EXYNOS4210_PL330_BASE0_ADDR, &s->pl330_irq_orgate[0],
103
+ s->irq_table[exynos4210_get_irq(21, 0)], 32, 32, 32);
104
+ pl330_create(EXYNOS4210_PL330_BASE1_ADDR, &s->pl330_irq_orgate[1],
105
+ s->irq_table[exynos4210_get_irq(21, 1)], 32, 32, 32);
106
+ pl330_create(EXYNOS4210_PL330_BASE2_ADDR, &s->pl330_irq_orgate[2],
107
+ s->irq_table[exynos4210_get_irq(20, 1)], 1, 31, 64);
108
+}
40
+
109
+
41
/* 32-bit writes to offset 0xc only actually write to the bank select
110
+static void exynos4210_init(Object *obj)
42
- register (offset 0xe) */
111
+{
43
- if (offset != 0xc)
112
+ Exynos4210State *s = EXYNOS4210_SOC(obj);
44
- smc91c111_writew(opaque, offset, value & 0xffff);
113
+ int i;
45
- smc91c111_writew(opaque, offset + 2, value >> 16);
114
+
46
-}
115
+ for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) {
47
+ * register (offset 0xe), so skip the first two bytes we would write.
116
+ char *name = g_strdup_printf("pl330-irq-orgate%d", i);
48
+ */
117
+ qemu_or_irq *orgate = &s->pl330_irq_orgate[i];
49
+ if (addr == 0xc && size == 4) {
118
+
50
+ i += 2;
119
+ object_initialize_child(obj, name, orgate, sizeof(*orgate),
51
+ }
120
+ TYPE_OR_IRQ, &error_abort, NULL);
52
121
+ g_free(name);
53
-static uint32_t smc91c111_readw(void *opaque, hwaddr offset)
54
-{
55
- uint32_t val;
56
- val = smc91c111_readb(opaque, offset);
57
- val |= smc91c111_readb(opaque, offset + 1) << 8;
58
- return val;
59
-}
60
-
61
-static uint32_t smc91c111_readl(void *opaque, hwaddr offset)
62
-{
63
- uint32_t val;
64
- val = smc91c111_readw(opaque, offset);
65
- val |= smc91c111_readw(opaque, offset + 2) << 16;
66
- return val;
67
+ for (; i < size; i++) {
68
+ smc91c111_writeb(opaque, addr + i,
69
+ extract32(value, i * 8, 8));
70
+ }
122
+ }
71
}
123
}
72
124
73
static int smc91c111_can_receive_nc(NetClientState *nc)
125
static void exynos4210_class_init(ObjectClass *klass, void *data)
74
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps smc91c111_mem_ops = {
126
@@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_info = {
75
/* The special case for 32 bit writes to 0xc means we can't just
127
.name = TYPE_EXYNOS4210_SOC,
76
* set .impl.min/max_access_size to 1, unfortunately
128
.parent = TYPE_SYS_BUS_DEVICE,
77
*/
129
.instance_size = sizeof(Exynos4210State),
78
- .old_mmio = {
130
+ .instance_init = exynos4210_init,
79
- .read = { smc91c111_readb, smc91c111_readw, smc91c111_readl, },
131
.class_init = exynos4210_class_init,
80
- .write = { smc91c111_writeb, smc91c111_writew, smc91c111_writel, },
81
- },
82
+ .read = smc91c111_readfn,
83
+ .write = smc91c111_writefn,
84
+ .valid.min_access_size = 1,
85
+ .valid.max_access_size = 4,
86
.endianness = DEVICE_NATIVE_ENDIAN,
87
};
132
};
88
133
89
--
134
--
90
2.17.0
135
2.20.1
91
136
92
137
diff view generated by jsdifflib
1
From: Igor Mammedov <imammedo@redhat.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
Even though nothing is currently broken (since all boards
3
Replace debug code with tracing to aid debugging.
4
use first_cpu as boot cpu), make sure that boot_info is set
4
5
on all CPUs.
6
If some board would like support heterogenuos setup (i.e.
7
init boot_info on subset of CPUs) in future, it should add
8
a reasonable API to do it, instead of starting assigning
9
boot_info from some CPU and till the end of present CPUs
10
list.
11
12
Ref:
13
"Message-ID: <CAFEAcA_NMWuA8WSs3cNeY6xX1kerO_uAcN_3=fK02BEhHJW86g@mail.gmail.com>"
14
15
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 1525176522-200354-5-git-send-email-imammedo@redhat.com
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
7
Message-id: 20200123052540.6132-5-linux@roeck-us.net
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
9
---
20
hw/arm/boot.c | 2 +-
10
hw/char/exynos4210_uart.c | 96 ++++++++++++---------------------------
21
1 file changed, 1 insertion(+), 1 deletion(-)
11
hw/char/trace-events | 17 +++++++
22
12
2 files changed, 47 insertions(+), 66 deletions(-)
23
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
13
14
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/boot.c
16
--- a/hw/char/exynos4210_uart.c
26
+++ b/hw/arm/boot.c
17
+++ b/hw/char/exynos4210_uart.c
27
@@ -XXX,XX +XXX,XX @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
18
@@ -XXX,XX +XXX,XX @@
19
#include "hw/irq.h"
20
#include "hw/qdev-properties.h"
21
22
-#undef DEBUG_UART
23
-#undef DEBUG_UART_EXTEND
24
-#undef DEBUG_IRQ
25
-#undef DEBUG_Rx_DATA
26
-#undef DEBUG_Tx_DATA
27
-
28
-#define DEBUG_UART 0
29
-#define DEBUG_UART_EXTEND 0
30
-#define DEBUG_IRQ 0
31
-#define DEBUG_Rx_DATA 0
32
-#define DEBUG_Tx_DATA 0
33
-
34
-#if DEBUG_UART
35
-#define PRINT_DEBUG(fmt, args...) \
36
- do { \
37
- fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \
38
- } while (0)
39
-
40
-#if DEBUG_UART_EXTEND
41
-#define PRINT_DEBUG_EXTEND(fmt, args...) \
42
- do { \
43
- fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \
44
- } while (0)
45
-#else
46
-#define PRINT_DEBUG_EXTEND(fmt, args...) \
47
- do {} while (0)
48
-#endif /* EXTEND */
49
-
50
-#else
51
-#define PRINT_DEBUG(fmt, args...) \
52
- do {} while (0)
53
-#define PRINT_DEBUG_EXTEND(fmt, args...) \
54
- do {} while (0)
55
-#endif
56
-
57
-#define PRINT_ERROR(fmt, args...) \
58
- do { \
59
- fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \
60
- } while (0)
61
+#include "trace.h"
62
63
/*
64
* Offsets for UART registers relative to SFR base address
65
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210UartState {
66
} Exynos4210UartState;
67
68
69
-#if DEBUG_UART
70
-/* Used only for debugging inside PRINT_DEBUG_... macros */
71
+/* Used only for tracing */
72
static const char *exynos4210_uart_regname(hwaddr offset)
73
{
74
75
@@ -XXX,XX +XXX,XX @@ static const char *exynos4210_uart_regname(hwaddr offset)
76
77
return NULL;
78
}
79
-#endif
80
81
82
static void fifo_store(Exynos4210UartFIFO *q, uint8_t ch)
83
@@ -XXX,XX +XXX,XX @@ static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState
84
break;
85
default:
86
level = 0;
87
- PRINT_ERROR("Wrong UART channel number: %d\n", s->channel);
88
+ trace_exynos_uart_channel_error(s->channel);
28
}
89
}
29
info->is_linux = is_linux;
90
30
91
return level;
31
- for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
92
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s)
32
+ for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
93
33
ARM_CPU(cs)->env.boot_info = info;
94
if (s->reg[I_(UINTP)]) {
95
qemu_irq_raise(s->irq);
96
-
97
-#if DEBUG_IRQ
98
- fprintf(stderr, "UART%d: IRQ has been raised: %08x\n",
99
- s->channel, s->reg[I_(UINTP)]);
100
-#endif
101
-
102
+ trace_exynos_uart_irq_raised(s->channel, s->reg[I_(UINTP)]);
103
} else {
104
qemu_irq_lower(s->irq);
105
+ trace_exynos_uart_irq_lowered(s->channel);
34
}
106
}
35
}
107
}
108
109
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_update_parameters(Exynos4210UartState *s)
110
111
qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
112
113
- PRINT_DEBUG("UART%d: speed: %d, parity: %c, data: %d, stop: %d\n",
114
+ trace_exynos_uart_update_params(
115
s->channel, speed, parity, data_bits, stop_bits);
116
}
117
118
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
119
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
120
uint8_t ch;
121
122
- PRINT_DEBUG_EXTEND("UART%d: <0x%04x> %s <- 0x%08llx\n", s->channel,
123
- offset, exynos4210_uart_regname(offset), (long long unsigned int)val);
124
+ trace_exynos_uart_write(s->channel, offset,
125
+ exynos4210_uart_regname(offset), val);
126
127
switch (offset) {
128
case ULCON:
129
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
130
if (val & UFCON_Rx_FIFO_RESET) {
131
fifo_reset(&s->rx);
132
s->reg[I_(UFCON)] &= ~UFCON_Rx_FIFO_RESET;
133
- PRINT_DEBUG("UART%d: Rx FIFO Reset\n", s->channel);
134
+ trace_exynos_uart_rx_fifo_reset(s->channel);
135
}
136
if (val & UFCON_Tx_FIFO_RESET) {
137
fifo_reset(&s->tx);
138
s->reg[I_(UFCON)] &= ~UFCON_Tx_FIFO_RESET;
139
- PRINT_DEBUG("UART%d: Tx FIFO Reset\n", s->channel);
140
+ trace_exynos_uart_tx_fifo_reset(s->channel);
141
}
142
break;
143
144
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
145
/* XXX this blocks entire thread. Rewrite to use
146
* qemu_chr_fe_write and background I/O callbacks */
147
qemu_chr_fe_write_all(&s->chr, &ch, 1);
148
-#if DEBUG_Tx_DATA
149
- fprintf(stderr, "%c", ch);
150
-#endif
151
+ trace_exynos_uart_tx(s->channel, ch);
152
s->reg[I_(UTRSTAT)] |= UTRSTAT_TRANSMITTER_EMPTY |
153
UTRSTAT_Tx_BUFFER_EMPTY;
154
s->reg[I_(UINTSP)] |= UINTSP_TXD;
155
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
156
case UINTP:
157
s->reg[I_(UINTP)] &= ~val;
158
s->reg[I_(UINTSP)] &= ~val;
159
- PRINT_DEBUG("UART%d: UINTP [%04x] have been cleared: %08x\n",
160
- s->channel, offset, s->reg[I_(UINTP)]);
161
+ trace_exynos_uart_intclr(s->channel, s->reg[I_(UINTP)]);
162
exynos4210_uart_update_irq(s);
163
break;
164
case UTRSTAT:
165
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
166
case UFSTAT:
167
case UMSTAT:
168
case URXH:
169
- PRINT_DEBUG("UART%d: Trying to write into RO register: %s [%04x]\n",
170
+ trace_exynos_uart_ro_write(
171
s->channel, exynos4210_uart_regname(offset), offset);
172
break;
173
case UINTSP:
174
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset,
175
case UERSTAT: /* Read Only */
176
res = s->reg[I_(UERSTAT)];
177
s->reg[I_(UERSTAT)] = 0;
178
+ trace_exynos_uart_read(s->channel, offset,
179
+ exynos4210_uart_regname(offset), res);
180
return res;
181
case UFSTAT: /* Read Only */
182
s->reg[I_(UFSTAT)] = fifo_elements_number(&s->rx) & 0xff;
183
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset,
184
s->reg[I_(UFSTAT)] |= UFSTAT_Rx_FIFO_FULL;
185
s->reg[I_(UFSTAT)] &= ~0xff;
186
}
187
+ trace_exynos_uart_read(s->channel, offset,
188
+ exynos4210_uart_regname(offset),
189
+ s->reg[I_(UFSTAT)]);
190
return s->reg[I_(UFSTAT)];
191
case URXH:
192
if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
193
if (fifo_elements_number(&s->rx)) {
194
res = fifo_retrieve(&s->rx);
195
-#if DEBUG_Rx_DATA
196
- fprintf(stderr, "%c", res);
197
-#endif
198
+ trace_exynos_uart_rx(s->channel, res);
199
if (!fifo_elements_number(&s->rx)) {
200
s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY;
201
} else {
202
s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY;
203
}
204
} else {
205
+ trace_exynos_uart_rx_error(s->channel);
206
s->reg[I_(UINTSP)] |= UINTSP_ERROR;
207
exynos4210_uart_update_irq(s);
208
res = 0;
209
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset,
210
s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY;
211
res = s->reg[I_(URXH)];
212
}
213
+ trace_exynos_uart_read(s->channel, offset,
214
+ exynos4210_uart_regname(offset), res);
215
return res;
216
case UTXH:
217
- PRINT_DEBUG("UART%d: Trying to read from WO register: %s [%04x]\n",
218
- s->channel, exynos4210_uart_regname(offset), offset);
219
+ trace_exynos_uart_wo_read(s->channel, exynos4210_uart_regname(offset),
220
+ offset);
221
break;
222
default:
223
+ trace_exynos_uart_read(s->channel, offset,
224
+ exynos4210_uart_regname(offset),
225
+ s->reg[I_(offset)]);
226
return s->reg[I_(offset)];
227
}
228
229
+ trace_exynos_uart_read(s->channel, offset, exynos4210_uart_regname(offset),
230
+ 0);
231
return 0;
232
}
233
234
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_reset(DeviceState *dev)
235
fifo_reset(&s->rx);
236
fifo_reset(&s->tx);
237
238
- PRINT_DEBUG("UART%d: Rx FIFO size: %d\n", s->channel, s->rx.size);
239
+ trace_exynos_uart_rxsize(s->channel, s->rx.size);
240
}
241
242
static const VMStateDescription vmstate_exynos4210_uart_fifo = {
243
diff --git a/hw/char/trace-events b/hw/char/trace-events
244
index XXXXXXX..XXXXXXX 100644
245
--- a/hw/char/trace-events
246
+++ b/hw/char/trace-events
247
@@ -XXX,XX +XXX,XX @@ cmsdk_apb_uart_set_params(int speed) "CMSDK APB UART: params set to %d 8N1"
248
# nrf51_uart.c
249
nrf51_uart_read(uint64_t addr, uint64_t r, unsigned int size) "addr 0x%" PRIx64 " value 0x%" PRIx64 " size %u"
250
nrf51_uart_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%" PRIx64 " value 0x%" PRIx64 " size %u"
251
+
252
+# exynos4210_uart.c
253
+exynos_uart_irq_raised(uint32_t channel, uint32_t reg) "UART%d: IRQ raised: 0x%08"PRIx32
254
+exynos_uart_irq_lowered(uint32_t channel) "UART%d: IRQ lowered"
255
+exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int data, int stop) "UART%d: speed: %d, parity: %c, data bits: %d, stop bits: %d"
256
+exynos_uart_write(uint32_t channel, uint32_t offset, const char *name, uint64_t val) "UART%d: <0x%04x> %s <- 0x%" PRIx64
257
+exynos_uart_read(uint32_t channel, uint32_t offset, const char *name, uint64_t val) "UART%d: <0x%04x> %s -> 0x%" PRIx64
258
+exynos_uart_rx_fifo_reset(uint32_t channel) "UART%d: Rx FIFO Reset"
259
+exynos_uart_tx_fifo_reset(uint32_t channel) "UART%d: Tx FIFO Reset"
260
+exynos_uart_tx(uint32_t channel, uint8_t ch) "UART%d: Tx 0x%02"PRIx32
261
+exynos_uart_intclr(uint32_t channel, uint32_t reg) "UART%d: interrupts cleared: 0x%08"PRIx32
262
+exynos_uart_ro_write(uint32_t channel, const char *name, uint32_t reg) "UART%d: Trying to write into RO register: %s [0x%04"PRIx32"]"
263
+exynos_uart_rx(uint32_t channel, uint8_t ch) "UART%d: Rx 0x%02"PRIx32
264
+exynos_uart_rx_error(uint32_t channel) "UART%d: Rx error"
265
+exynos_uart_wo_read(uint32_t channel, const char *name, uint32_t reg) "UART%d: Trying to read from WO register: %s [0x%04"PRIx32"]"
266
+exynos_uart_rxsize(uint32_t channel, uint32_t size) "UART%d: Rx FIFO size: %d"
267
+exynos_uart_channel_error(uint32_t channel) "Wrong UART channel number: %d"
36
--
268
--
37
2.17.0
269
2.20.1
38
270
39
271
diff view generated by jsdifflib
Deleted patch
1
From: Thomas Huth <thuth@redhat.com>
2
1
3
When running omap1/2 or pxa2xx based ARM machines with -nodefaults,
4
they bail out immediately complaining about a "missing SecureDigital
5
device". That's not how the "default" devices in vl.c are meant to
6
work - it should be possible for a board to also start up without
7
default devices. So let's turn the error message and exit() into
8
a warning instead.
9
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
11
Message-id: 1525326811-3233-1-git-send-email-thuth@redhat.com
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/arm/omap1.c | 8 ++++----
17
hw/arm/omap2.c | 8 ++++----
18
hw/arm/pxa2xx.c | 15 +++++++--------
19
3 files changed, 15 insertions(+), 16 deletions(-)
20
21
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/omap1.c
24
+++ b/hw/arm/omap1.c
25
@@ -XXX,XX +XXX,XX @@
26
#include "hw/arm/soc_dma.h"
27
#include "sysemu/block-backend.h"
28
#include "sysemu/blockdev.h"
29
+#include "sysemu/qtest.h"
30
#include "qemu/range.h"
31
#include "hw/sysbus.h"
32
#include "qemu/cutils.h"
33
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
34
omap_findclk(s, "dpll3"));
35
36
dinfo = drive_get(IF_SD, 0, 0);
37
- if (!dinfo) {
38
- error_report("missing SecureDigital device");
39
- exit(1);
40
+ if (!dinfo && !qtest_enabled()) {
41
+ warn_report("missing SecureDigital device");
42
}
43
s->mmc = omap_mmc_init(0xfffb7800, system_memory,
44
- blk_by_legacy_dinfo(dinfo),
45
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
46
qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
47
&s->drq[OMAP_DMA_MMC_TX],
48
omap_findclk(s, "mmc_ck"));
49
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/omap2.c
52
+++ b/hw/arm/omap2.c
53
@@ -XXX,XX +XXX,XX @@
54
#include "cpu.h"
55
#include "sysemu/block-backend.h"
56
#include "sysemu/blockdev.h"
57
+#include "sysemu/qtest.h"
58
#include "hw/boards.h"
59
#include "hw/hw.h"
60
#include "hw/arm/arm.h"
61
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
62
s->drq[OMAP24XX_DMA_GPMC]);
63
64
dinfo = drive_get(IF_SD, 0, 0);
65
- if (!dinfo) {
66
- error_report("missing SecureDigital device");
67
- exit(1);
68
+ if (!dinfo && !qtest_enabled()) {
69
+ warn_report("missing SecureDigital device");
70
}
71
s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9),
72
- blk_by_legacy_dinfo(dinfo),
73
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
74
qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ),
75
&s->drq[OMAP24XX_DMA_MMC1_TX],
76
omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
77
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/pxa2xx.c
80
+++ b/hw/arm/pxa2xx.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "chardev/char-fe.h"
83
#include "sysemu/block-backend.h"
84
#include "sysemu/blockdev.h"
85
+#include "sysemu/qtest.h"
86
#include "qemu/cutils.h"
87
88
static struct {
89
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
90
s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 121);
91
92
dinfo = drive_get(IF_SD, 0, 0);
93
- if (!dinfo) {
94
- error_report("missing SecureDigital device");
95
- exit(1);
96
+ if (!dinfo && !qtest_enabled()) {
97
+ warn_report("missing SecureDigital device");
98
}
99
s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
100
- blk_by_legacy_dinfo(dinfo),
101
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
102
qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
103
qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
104
qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
105
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
106
s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 85);
107
108
dinfo = drive_get(IF_SD, 0, 0);
109
- if (!dinfo) {
110
- error_report("missing SecureDigital device");
111
- exit(1);
112
+ if (!dinfo && !qtest_enabled()) {
113
+ warn_report("missing SecureDigital device");
114
}
115
s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
116
- blk_by_legacy_dinfo(dinfo),
117
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
118
qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
119
qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
120
qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
121
--
122
2.17.0
123
124
diff view generated by jsdifflib
Deleted patch
1
For v8M the instructions VLLDM and VLSTM support lazy saving
2
and restoring of the secure floating-point registers. Even
3
if the floating point extension is not implemented, these
4
instructions must act as NOPs in Secure state, so they can
5
be used as part of the secure-to-nonsecure call sequence.
6
1
7
Fixes: https://bugs.launchpad.net/qemu/+bug/1768295
8
Cc: qemu-stable@nongnu.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180503105730.5958-1-peter.maydell@linaro.org
12
---
13
target/arm/translate.c | 17 ++++++++++++++++-
14
1 file changed, 16 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
19
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
21
/* Coprocessor. */
22
if (arm_dc_feature(s, ARM_FEATURE_M)) {
23
/* We don't currently implement M profile FP support,
24
- * so this entire space should give a NOCP fault.
25
+ * so this entire space should give a NOCP fault, with
26
+ * the exception of the v8M VLLDM and VLSTM insns, which
27
+ * must be NOPs in Secure state and UNDEF in Nonsecure state.
28
*/
29
+ if (arm_dc_feature(s, ARM_FEATURE_V8) &&
30
+ (insn & 0xffa00f00) == 0xec200a00) {
31
+ /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
32
+ * - VLLDM, VLSTM
33
+ * We choose to UNDEF if the RAZ bits are non-zero.
34
+ */
35
+ if (!s->v8m_secure || (insn & 0x0040f0ff)) {
36
+ goto illegal_op;
37
+ }
38
+ /* Just NOP since FP support is not implemented */
39
+ break;
40
+ }
41
+ /* All other insns: NOCP */
42
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
43
default_exception_el(s));
44
break;
45
--
46
2.17.0
47
48
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
We set up the infrastructure to enumerate all the PCI devices
4
attached to the SMMU and create an associated IOMMU memory
5
region and address space.
6
7
Those info are stored in SMMUDevice objects. The devices are
8
grouped according to the PCIBus they belong to. A hash table
9
indexed by the PCIBus pointer is used. Also an array indexed by
10
the bus number allows to find the list of SMMUDevices.
11
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 1524665762-31355-3-git-send-email-eric.auger@redhat.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
include/hw/arm/smmu-common.h | 8 +++++
19
hw/arm/smmu-common.c | 69 ++++++++++++++++++++++++++++++++++++
20
hw/arm/trace-events | 3 ++
21
3 files changed, 80 insertions(+)
22
23
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/smmu-common.h
26
+++ b/include/hw/arm/smmu-common.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct {
28
#define ARM_SMMU_GET_CLASS(obj) \
29
OBJECT_GET_CLASS(SMMUBaseClass, (obj), TYPE_ARM_SMMU)
30
31
+/* Return the SMMUPciBus handle associated to a PCI bus number */
32
+SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num);
33
+
34
+/* Return the stream ID of an SMMU device */
35
+static inline uint16_t smmu_get_sid(SMMUDevice *sdev)
36
+{
37
+ return PCI_BUILD_BDF(pci_bus_num(sdev->bus), sdev->devfn);
38
+}
39
#endif /* HW_ARM_SMMU_COMMON */
40
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/smmu-common.c
43
+++ b/hw/arm/smmu-common.c
44
@@ -XXX,XX +XXX,XX @@
45
#include "qemu/error-report.h"
46
#include "hw/arm/smmu-common.h"
47
48
+/**
49
+ * The bus number is used for lookup when SID based invalidation occurs.
50
+ * In that case we lazily populate the SMMUPciBus array from the bus hash
51
+ * table. At the time the SMMUPciBus is created (smmu_find_add_as), the bus
52
+ * numbers may not be always initialized yet.
53
+ */
54
+SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num)
55
+{
56
+ SMMUPciBus *smmu_pci_bus = s->smmu_pcibus_by_bus_num[bus_num];
57
+
58
+ if (!smmu_pci_bus) {
59
+ GHashTableIter iter;
60
+
61
+ g_hash_table_iter_init(&iter, s->smmu_pcibus_by_busptr);
62
+ while (g_hash_table_iter_next(&iter, NULL, (void **)&smmu_pci_bus)) {
63
+ if (pci_bus_num(smmu_pci_bus->bus) == bus_num) {
64
+ s->smmu_pcibus_by_bus_num[bus_num] = smmu_pci_bus;
65
+ return smmu_pci_bus;
66
+ }
67
+ }
68
+ }
69
+ return smmu_pci_bus;
70
+}
71
+
72
+static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
73
+{
74
+ SMMUState *s = opaque;
75
+ SMMUPciBus *sbus = g_hash_table_lookup(s->smmu_pcibus_by_busptr, bus);
76
+ SMMUDevice *sdev;
77
+
78
+ if (!sbus) {
79
+ sbus = g_malloc0(sizeof(SMMUPciBus) +
80
+ sizeof(SMMUDevice *) * SMMU_PCI_DEVFN_MAX);
81
+ sbus->bus = bus;
82
+ g_hash_table_insert(s->smmu_pcibus_by_busptr, bus, sbus);
83
+ }
84
+
85
+ sdev = sbus->pbdev[devfn];
86
+ if (!sdev) {
87
+ char *name = g_strdup_printf("%s-%d-%d",
88
+ s->mrtypename,
89
+ pci_bus_num(bus), devfn);
90
+ sdev = sbus->pbdev[devfn] = g_new0(SMMUDevice, 1);
91
+
92
+ sdev->smmu = s;
93
+ sdev->bus = bus;
94
+ sdev->devfn = devfn;
95
+
96
+ memory_region_init_iommu(&sdev->iommu, sizeof(sdev->iommu),
97
+ s->mrtypename,
98
+ OBJECT(s), name, 1ULL << SMMU_MAX_VA_BITS);
99
+ address_space_init(&sdev->as,
100
+ MEMORY_REGION(&sdev->iommu), name);
101
+ trace_smmu_add_mr(name);
102
+ g_free(name);
103
+ }
104
+
105
+ return &sdev->as;
106
+}
107
+
108
static void smmu_base_realize(DeviceState *dev, Error **errp)
109
{
110
+ SMMUState *s = ARM_SMMU(dev);
111
SMMUBaseClass *sbc = ARM_SMMU_GET_CLASS(dev);
112
Error *local_err = NULL;
113
114
@@ -XXX,XX +XXX,XX @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
115
error_propagate(errp, local_err);
116
return;
117
}
118
+
119
+ s->smmu_pcibus_by_busptr = g_hash_table_new(NULL, NULL);
120
+
121
+ if (s->primary_bus) {
122
+ pci_setup_iommu(s->primary_bus, smmu_find_add_as, s);
123
+ } else {
124
+ error_setg(errp, "SMMU is not attached to any PCI bus!");
125
+ }
126
}
127
128
static void smmu_base_reset(DeviceState *dev)
129
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/arm/trace-events
132
+++ b/hw/arm/trace-events
133
@@ -XXX,XX +XXX,XX @@
134
135
# hw/arm/virt-acpi-build.c
136
virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
137
+
138
+# hw/arm/smmu-common.c
139
+smmu_add_mr(const char *name) "%s"
140
\ No newline at end of file
141
--
142
2.17.0
143
144
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
We introduce helpers to read/write into the command and event
3
After restoring a VM, serial parameters need to be updated to reflect
4
circular queues.
4
restored register values. Implement a post_load function to handle this
5
situation.
5
6
6
smmuv3_write_eventq and smmuv3_cmq_consume will become static
7
in subsequent patches.
8
9
Invalidation commands are not yet dealt with. We do not cache
10
data that need to be invalidated. This will change with vhost
11
integration.
12
13
Signed-off-by: Eric Auger <eric.auger@redhat.com>
14
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Message-id: 1524665762-31355-7-git-send-email-eric.auger@redhat.com
8
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Message-id: 20200123052540.6132-6-linux@roeck-us.net
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
11
---
19
hw/arm/smmuv3-internal.h | 163 +++++++++++++++++++++++++++++++++++++++
12
hw/char/exynos4210_uart.c | 10 ++++++++++
20
hw/arm/smmuv3.c | 136 ++++++++++++++++++++++++++++++++
13
1 file changed, 10 insertions(+)
21
hw/arm/trace-events | 5 ++
22
3 files changed, 304 insertions(+)
23
14
24
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
15
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/smmuv3-internal.h
17
--- a/hw/char/exynos4210_uart.c
27
+++ b/hw/arm/smmuv3-internal.h
18
+++ b/hw/char/exynos4210_uart.c
28
@@ -XXX,XX +XXX,XX @@ static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
19
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_reset(DeviceState *dev)
29
void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask);
20
trace_exynos_uart_rxsize(s->channel, s->rx.size);
30
void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn);
21
}
31
22
32
+/* Queue Handling */
23
+static int exynos4210_uart_post_load(void *opaque, int version_id)
24
+{
25
+ Exynos4210UartState *s = (Exynos4210UartState *)opaque;
33
+
26
+
34
+#define Q_BASE(q) ((q)->base & SMMU_BASE_ADDR_MASK)
27
+ exynos4210_uart_update_parameters(s);
35
+#define WRAP_MASK(q) (1 << (q)->log2size)
36
+#define INDEX_MASK(q) (((1 << (q)->log2size)) - 1)
37
+#define WRAP_INDEX_MASK(q) ((1 << ((q)->log2size + 1)) - 1)
38
+
39
+#define Q_CONS(q) ((q)->cons & INDEX_MASK(q))
40
+#define Q_PROD(q) ((q)->prod & INDEX_MASK(q))
41
+
42
+#define Q_CONS_ENTRY(q) (Q_BASE(q) + (q)->entry_size * Q_CONS(q))
43
+#define Q_PROD_ENTRY(q) (Q_BASE(q) + (q)->entry_size * Q_PROD(q))
44
+
45
+#define Q_CONS_WRAP(q) (((q)->cons & WRAP_MASK(q)) >> (q)->log2size)
46
+#define Q_PROD_WRAP(q) (((q)->prod & WRAP_MASK(q)) >> (q)->log2size)
47
+
48
+static inline bool smmuv3_q_full(SMMUQueue *q)
49
+{
50
+ return ((q->cons ^ q->prod) & WRAP_INDEX_MASK(q)) == WRAP_MASK(q);
51
+}
52
+
53
+static inline bool smmuv3_q_empty(SMMUQueue *q)
54
+{
55
+ return (q->cons & WRAP_INDEX_MASK(q)) == (q->prod & WRAP_INDEX_MASK(q));
56
+}
57
+
58
+static inline void queue_prod_incr(SMMUQueue *q)
59
+{
60
+ q->prod = (q->prod + 1) & WRAP_INDEX_MASK(q);
61
+}
62
+
63
+static inline void queue_cons_incr(SMMUQueue *q)
64
+{
65
+ /*
66
+ * We have to use deposit for the CONS registers to preserve
67
+ * the ERR field in the high bits.
68
+ */
69
+ q->cons = deposit32(q->cons, 0, q->log2size + 1, q->cons + 1);
70
+}
71
+
72
+static inline bool smmuv3_cmdq_enabled(SMMUv3State *s)
73
+{
74
+ return FIELD_EX32(s->cr[0], CR0, CMDQEN);
75
+}
76
+
77
+static inline bool smmuv3_eventq_enabled(SMMUv3State *s)
78
+{
79
+ return FIELD_EX32(s->cr[0], CR0, EVENTQEN);
80
+}
81
+
82
+static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type)
83
+{
84
+ s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
85
+}
86
+
87
+void smmuv3_write_eventq(SMMUv3State *s, Evt *evt);
88
+
89
+/* Commands */
90
+
91
+typedef enum SMMUCommandType {
92
+ SMMU_CMD_NONE = 0x00,
93
+ SMMU_CMD_PREFETCH_CONFIG ,
94
+ SMMU_CMD_PREFETCH_ADDR,
95
+ SMMU_CMD_CFGI_STE,
96
+ SMMU_CMD_CFGI_STE_RANGE,
97
+ SMMU_CMD_CFGI_CD,
98
+ SMMU_CMD_CFGI_CD_ALL,
99
+ SMMU_CMD_CFGI_ALL,
100
+ SMMU_CMD_TLBI_NH_ALL = 0x10,
101
+ SMMU_CMD_TLBI_NH_ASID,
102
+ SMMU_CMD_TLBI_NH_VA,
103
+ SMMU_CMD_TLBI_NH_VAA,
104
+ SMMU_CMD_TLBI_EL3_ALL = 0x18,
105
+ SMMU_CMD_TLBI_EL3_VA = 0x1a,
106
+ SMMU_CMD_TLBI_EL2_ALL = 0x20,
107
+ SMMU_CMD_TLBI_EL2_ASID,
108
+ SMMU_CMD_TLBI_EL2_VA,
109
+ SMMU_CMD_TLBI_EL2_VAA,
110
+ SMMU_CMD_TLBI_S12_VMALL = 0x28,
111
+ SMMU_CMD_TLBI_S2_IPA = 0x2a,
112
+ SMMU_CMD_TLBI_NSNH_ALL = 0x30,
113
+ SMMU_CMD_ATC_INV = 0x40,
114
+ SMMU_CMD_PRI_RESP,
115
+ SMMU_CMD_RESUME = 0x44,
116
+ SMMU_CMD_STALL_TERM,
117
+ SMMU_CMD_SYNC,
118
+} SMMUCommandType;
119
+
120
+static const char *cmd_stringify[] = {
121
+ [SMMU_CMD_PREFETCH_CONFIG] = "SMMU_CMD_PREFETCH_CONFIG",
122
+ [SMMU_CMD_PREFETCH_ADDR] = "SMMU_CMD_PREFETCH_ADDR",
123
+ [SMMU_CMD_CFGI_STE] = "SMMU_CMD_CFGI_STE",
124
+ [SMMU_CMD_CFGI_STE_RANGE] = "SMMU_CMD_CFGI_STE_RANGE",
125
+ [SMMU_CMD_CFGI_CD] = "SMMU_CMD_CFGI_CD",
126
+ [SMMU_CMD_CFGI_CD_ALL] = "SMMU_CMD_CFGI_CD_ALL",
127
+ [SMMU_CMD_CFGI_ALL] = "SMMU_CMD_CFGI_ALL",
128
+ [SMMU_CMD_TLBI_NH_ALL] = "SMMU_CMD_TLBI_NH_ALL",
129
+ [SMMU_CMD_TLBI_NH_ASID] = "SMMU_CMD_TLBI_NH_ASID",
130
+ [SMMU_CMD_TLBI_NH_VA] = "SMMU_CMD_TLBI_NH_VA",
131
+ [SMMU_CMD_TLBI_NH_VAA] = "SMMU_CMD_TLBI_NH_VAA",
132
+ [SMMU_CMD_TLBI_EL3_ALL] = "SMMU_CMD_TLBI_EL3_ALL",
133
+ [SMMU_CMD_TLBI_EL3_VA] = "SMMU_CMD_TLBI_EL3_VA",
134
+ [SMMU_CMD_TLBI_EL2_ALL] = "SMMU_CMD_TLBI_EL2_ALL",
135
+ [SMMU_CMD_TLBI_EL2_ASID] = "SMMU_CMD_TLBI_EL2_ASID",
136
+ [SMMU_CMD_TLBI_EL2_VA] = "SMMU_CMD_TLBI_EL2_VA",
137
+ [SMMU_CMD_TLBI_EL2_VAA] = "SMMU_CMD_TLBI_EL2_VAA",
138
+ [SMMU_CMD_TLBI_S12_VMALL] = "SMMU_CMD_TLBI_S12_VMALL",
139
+ [SMMU_CMD_TLBI_S2_IPA] = "SMMU_CMD_TLBI_S2_IPA",
140
+ [SMMU_CMD_TLBI_NSNH_ALL] = "SMMU_CMD_TLBI_NSNH_ALL",
141
+ [SMMU_CMD_ATC_INV] = "SMMU_CMD_ATC_INV",
142
+ [SMMU_CMD_PRI_RESP] = "SMMU_CMD_PRI_RESP",
143
+ [SMMU_CMD_RESUME] = "SMMU_CMD_RESUME",
144
+ [SMMU_CMD_STALL_TERM] = "SMMU_CMD_STALL_TERM",
145
+ [SMMU_CMD_SYNC] = "SMMU_CMD_SYNC",
146
+};
147
+
148
+static inline const char *smmu_cmd_string(SMMUCommandType type)
149
+{
150
+ if (type > SMMU_CMD_NONE && type < ARRAY_SIZE(cmd_stringify)) {
151
+ return cmd_stringify[type] ? cmd_stringify[type] : "UNKNOWN";
152
+ } else {
153
+ return "INVALID";
154
+ }
155
+}
156
+
157
+/* CMDQ fields */
158
+
159
+typedef enum {
160
+ SMMU_CERROR_NONE = 0,
161
+ SMMU_CERROR_ILL,
162
+ SMMU_CERROR_ABT,
163
+ SMMU_CERROR_ATC_INV_SYNC,
164
+} SMMUCmdError;
165
+
166
+enum { /* Command completion notification */
167
+ CMD_SYNC_SIG_NONE,
168
+ CMD_SYNC_SIG_IRQ,
169
+ CMD_SYNC_SIG_SEV,
170
+};
171
+
172
+#define CMD_TYPE(x) extract32((x)->word[0], 0 , 8)
173
+#define CMD_SSEC(x) extract32((x)->word[0], 10, 1)
174
+#define CMD_SSV(x) extract32((x)->word[0], 11, 1)
175
+#define CMD_RESUME_AC(x) extract32((x)->word[0], 12, 1)
176
+#define CMD_RESUME_AB(x) extract32((x)->word[0], 13, 1)
177
+#define CMD_SYNC_CS(x) extract32((x)->word[0], 12, 2)
178
+#define CMD_SSID(x) extract32((x)->word[0], 12, 20)
179
+#define CMD_SID(x) ((x)->word[1])
180
+#define CMD_VMID(x) extract32((x)->word[1], 0 , 16)
181
+#define CMD_ASID(x) extract32((x)->word[1], 16, 16)
182
+#define CMD_RESUME_STAG(x) extract32((x)->word[2], 0 , 16)
183
+#define CMD_RESP(x) extract32((x)->word[2], 11, 2)
184
+#define CMD_LEAF(x) extract32((x)->word[2], 0 , 1)
185
+#define CMD_STE_RANGE(x) extract32((x)->word[2], 0 , 5)
186
+#define CMD_ADDR(x) ({ \
187
+ uint64_t high = (uint64_t)(x)->word[3]; \
188
+ uint64_t low = extract32((x)->word[2], 12, 20); \
189
+ uint64_t addr = high << 32 | (low << 12); \
190
+ addr; \
191
+ })
192
+
193
+int smmuv3_cmdq_consume(SMMUv3State *s);
194
+
195
#endif
196
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/hw/arm/smmuv3.c
199
+++ b/hw/arm/smmuv3.c
200
@@ -XXX,XX +XXX,XX @@ void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
201
trace_smmuv3_write_gerrorn(toggled & pending, s->gerrorn);
202
}
203
204
+static inline MemTxResult queue_read(SMMUQueue *q, void *data)
205
+{
206
+ dma_addr_t addr = Q_CONS_ENTRY(q);
207
+
208
+ return dma_memory_read(&address_space_memory, addr, data, q->entry_size);
209
+}
210
+
211
+static MemTxResult queue_write(SMMUQueue *q, void *data)
212
+{
213
+ dma_addr_t addr = Q_PROD_ENTRY(q);
214
+ MemTxResult ret;
215
+
216
+ ret = dma_memory_write(&address_space_memory, addr, data, q->entry_size);
217
+ if (ret != MEMTX_OK) {
218
+ return ret;
219
+ }
220
+
221
+ queue_prod_incr(q);
222
+ return MEMTX_OK;
223
+}
224
+
225
+void smmuv3_write_eventq(SMMUv3State *s, Evt *evt)
226
+{
227
+ SMMUQueue *q = &s->eventq;
228
+
229
+ if (!smmuv3_eventq_enabled(s)) {
230
+ return;
231
+ }
232
+
233
+ if (smmuv3_q_full(q)) {
234
+ return;
235
+ }
236
+
237
+ queue_write(q, evt);
238
+
239
+ if (smmuv3_q_empty(q)) {
240
+ smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0);
241
+ }
242
+}
243
+
244
static void smmuv3_init_regs(SMMUv3State *s)
245
{
246
/**
247
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
248
s->sid_split = 0;
249
}
250
251
+int smmuv3_cmdq_consume(SMMUv3State *s)
252
+{
253
+ SMMUCmdError cmd_error = SMMU_CERROR_NONE;
254
+ SMMUQueue *q = &s->cmdq;
255
+ SMMUCommandType type = 0;
256
+
257
+ if (!smmuv3_cmdq_enabled(s)) {
258
+ return 0;
259
+ }
260
+ /*
261
+ * some commands depend on register values, typically CR0. In case those
262
+ * register values change while handling the command, spec says it
263
+ * is UNPREDICTABLE whether the command is interpreted under the new
264
+ * or old value.
265
+ */
266
+
267
+ while (!smmuv3_q_empty(q)) {
268
+ uint32_t pending = s->gerror ^ s->gerrorn;
269
+ Cmd cmd;
270
+
271
+ trace_smmuv3_cmdq_consume(Q_PROD(q), Q_CONS(q),
272
+ Q_PROD_WRAP(q), Q_CONS_WRAP(q));
273
+
274
+ if (FIELD_EX32(pending, GERROR, CMDQ_ERR)) {
275
+ break;
276
+ }
277
+
278
+ if (queue_read(q, &cmd) != MEMTX_OK) {
279
+ cmd_error = SMMU_CERROR_ABT;
280
+ break;
281
+ }
282
+
283
+ type = CMD_TYPE(&cmd);
284
+
285
+ trace_smmuv3_cmdq_opcode(smmu_cmd_string(type));
286
+
287
+ switch (type) {
288
+ case SMMU_CMD_SYNC:
289
+ if (CMD_SYNC_CS(&cmd) & CMD_SYNC_SIG_IRQ) {
290
+ smmuv3_trigger_irq(s, SMMU_IRQ_CMD_SYNC, 0);
291
+ }
292
+ break;
293
+ case SMMU_CMD_PREFETCH_CONFIG:
294
+ case SMMU_CMD_PREFETCH_ADDR:
295
+ case SMMU_CMD_CFGI_STE:
296
+ case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */
297
+ case SMMU_CMD_CFGI_CD:
298
+ case SMMU_CMD_CFGI_CD_ALL:
299
+ case SMMU_CMD_TLBI_NH_ALL:
300
+ case SMMU_CMD_TLBI_NH_ASID:
301
+ case SMMU_CMD_TLBI_NH_VA:
302
+ case SMMU_CMD_TLBI_NH_VAA:
303
+ case SMMU_CMD_TLBI_EL3_ALL:
304
+ case SMMU_CMD_TLBI_EL3_VA:
305
+ case SMMU_CMD_TLBI_EL2_ALL:
306
+ case SMMU_CMD_TLBI_EL2_ASID:
307
+ case SMMU_CMD_TLBI_EL2_VA:
308
+ case SMMU_CMD_TLBI_EL2_VAA:
309
+ case SMMU_CMD_TLBI_S12_VMALL:
310
+ case SMMU_CMD_TLBI_S2_IPA:
311
+ case SMMU_CMD_TLBI_NSNH_ALL:
312
+ case SMMU_CMD_ATC_INV:
313
+ case SMMU_CMD_PRI_RESP:
314
+ case SMMU_CMD_RESUME:
315
+ case SMMU_CMD_STALL_TERM:
316
+ trace_smmuv3_unhandled_cmd(type);
317
+ break;
318
+ default:
319
+ cmd_error = SMMU_CERROR_ILL;
320
+ qemu_log_mask(LOG_GUEST_ERROR,
321
+ "Illegal command type: %d\n", CMD_TYPE(&cmd));
322
+ break;
323
+ }
324
+ if (cmd_error) {
325
+ break;
326
+ }
327
+ /*
328
+ * We only increment the cons index after the completion of
329
+ * the command. We do that because the SYNC returns immediately
330
+ * and does not check the completion of previous commands
331
+ */
332
+ queue_cons_incr(q);
333
+ }
334
+
335
+ if (cmd_error) {
336
+ trace_smmuv3_cmdq_consume_error(smmu_cmd_string(type), cmd_error);
337
+ smmu_write_cmdq_err(s, cmd_error);
338
+ smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_CMDQ_ERR_MASK);
339
+ }
340
+
341
+ trace_smmuv3_cmdq_consume_out(Q_PROD(q), Q_CONS(q),
342
+ Q_PROD_WRAP(q), Q_CONS_WRAP(q));
343
+
28
+
344
+ return 0;
29
+ return 0;
345
+}
30
+}
346
+
31
+
347
static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data,
32
static const VMStateDescription vmstate_exynos4210_uart_fifo = {
348
unsigned size, MemTxAttrs attrs)
33
.name = "exynos4210.uart.fifo",
349
{
34
.version_id = 1,
350
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
35
.minimum_version_id = 1,
351
index XXXXXXX..XXXXXXX 100644
36
+ .post_load = exynos4210_uart_post_load,
352
--- a/hw/arm/trace-events
37
.fields = (VMStateField[]) {
353
+++ b/hw/arm/trace-events
38
VMSTATE_UINT32(sp, Exynos4210UartFIFO),
354
@@ -XXX,XX +XXX,XX @@ smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr:
39
VMSTATE_UINT32(rp, Exynos4210UartFIFO),
355
smmuv3_trigger_irq(int irq) "irq=%d"
356
smmuv3_write_gerror(uint32_t toggled, uint32_t gerror) "toggled=0x%x, new GERROR=0x%x"
357
smmuv3_write_gerrorn(uint32_t acked, uint32_t gerrorn) "acked=0x%x, new GERRORN=0x%x"
358
+smmuv3_unhandled_cmd(uint32_t type) "Unhandled command type=%d"
359
+smmuv3_cmdq_consume(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod=%d cons=%d prod.wrap=%d cons.wrap=%d"
360
+smmuv3_cmdq_opcode(const char *opcode) "<--- %s"
361
+smmuv3_cmdq_consume_out(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod:%d, cons:%d, prod_wrap:%d, cons_wrap:%d "
362
+smmuv3_cmdq_consume_error(const char *cmd_name, uint8_t cmd_error) "Error on %s command execution: %d"
363
--
40
--
364
2.17.0
41
2.20.1
365
42
366
43
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
At the moment, the SMMUv3 does not support notification on
3
The driver already implements a receive FIFO, but it does not
4
TLB invalidation. So let's log an error as soon as such notifier
4
handle receive FIFO trigger levels and timeout. Implement the
5
gets enabled.
5
missing functionality.
6
6
7
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20200123052540.6132-7-linux@roeck-us.net
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 1524665762-31355-11-git-send-email-eric.auger@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/arm/smmuv3.c | 11 +++++++++++
12
hw/char/exynos4210_uart.c | 117 ++++++++++++++++++++++++++++++--------
13
1 file changed, 11 insertions(+)
13
hw/char/trace-events | 3 +-
14
14
2 files changed, 94 insertions(+), 26 deletions(-)
15
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
15
16
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/smmuv3.c
18
--- a/hw/char/exynos4210_uart.c
18
+++ b/hw/arm/smmuv3.c
19
+++ b/hw/char/exynos4210_uart.c
19
@@ -XXX,XX +XXX,XX @@ static void smmuv3_class_init(ObjectClass *klass, void *data)
20
@@ -XXX,XX +XXX,XX @@
20
dc->realize = smmu_realize;
21
#include "migration/vmstate.h"
21
}
22
#include "qemu/error-report.h"
22
23
#include "qemu/module.h"
23
+static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
24
+#include "qemu/timer.h"
24
+ IOMMUNotifierFlag old,
25
#include "chardev/char-fe.h"
25
+ IOMMUNotifierFlag new)
26
#include "chardev/char-serial.h"
26
+{
27
27
+ if (old == IOMMU_NOTIFIER_NONE) {
28
@@ -XXX,XX +XXX,XX @@ static const Exynos4210UartReg exynos4210_uart_regs[] = {
28
+ warn_report("SMMUV3 does not support vhost/vfio integration yet: "
29
#define ULCON_STOP_BIT_SHIFT 1
29
+ "devices of those types will not function properly");
30
31
/* UART Tx/Rx Status */
32
+#define UTRSTAT_Rx_TIMEOUT 0x8
33
#define UTRSTAT_TRANSMITTER_EMPTY 0x4
34
#define UTRSTAT_Tx_BUFFER_EMPTY 0x2
35
#define UTRSTAT_Rx_BUFFER_DATA_READY 0x1
36
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210UartState {
37
Exynos4210UartFIFO rx;
38
Exynos4210UartFIFO tx;
39
40
+ QEMUTimer *fifo_timeout_timer;
41
+ uint64_t wordtime; /* word time in ns */
42
+
43
CharBackend chr;
44
qemu_irq irq;
45
46
@@ -XXX,XX +XXX,XX @@ static void fifo_reset(Exynos4210UartFIFO *q)
47
q->rp = 0;
48
}
49
50
-static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState *s)
51
+static uint32_t exynos4210_uart_FIFO_trigger_level(uint32_t channel,
52
+ uint32_t reg)
53
{
54
- uint32_t level = 0;
55
- uint32_t reg;
56
+ uint32_t level;
57
58
- reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >>
59
- UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT;
60
-
61
- switch (s->channel) {
62
+ switch (channel) {
63
case 0:
64
level = reg * 32;
65
break;
66
@@ -XXX,XX +XXX,XX @@ static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState
67
break;
68
default:
69
level = 0;
70
- trace_exynos_uart_channel_error(s->channel);
71
+ trace_exynos_uart_channel_error(channel);
72
+ break;
73
}
74
-
75
return level;
76
}
77
78
+static uint32_t
79
+exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState *s)
80
+{
81
+ uint32_t reg;
82
+
83
+ reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >>
84
+ UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT;
85
+
86
+ return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
87
+}
88
+
89
+static uint32_t
90
+exynos4210_uart_Rx_FIFO_trigger_level(const Exynos4210UartState *s)
91
+{
92
+ uint32_t reg;
93
+
94
+ reg = ((s->reg[I_(UFCON)] & UFCON_Rx_FIFO_TRIGGER_LEVEL) >>
95
+ UFCON_Rx_FIFO_TRIGGER_LEVEL_SHIFT) + 1;
96
+
97
+ return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
98
+}
99
+
100
static void exynos4210_uart_update_irq(Exynos4210UartState *s)
101
{
102
/*
103
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s)
104
* transmit FIFO is smaller than the trigger level.
105
*/
106
if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
107
-
108
uint32_t count = (s->reg[I_(UFSTAT)] & UFSTAT_Tx_FIFO_COUNT) >>
109
UFSTAT_Tx_FIFO_COUNT_SHIFT;
110
111
if (count <= exynos4210_uart_Tx_FIFO_trigger_level(s)) {
112
s->reg[I_(UINTSP)] |= UINTSP_TXD;
113
}
114
+
115
+ /*
116
+ * Rx interrupt if trigger level is reached or if rx timeout
117
+ * interrupt is disabled and there is data in the receive buffer
118
+ */
119
+ count = fifo_elements_number(&s->rx);
120
+ if ((count && !(s->reg[I_(UCON)] & 0x80)) ||
121
+ count >= exynos4210_uart_Rx_FIFO_trigger_level(s)) {
122
+ s->reg[I_(UINTSP)] |= UINTSP_RXD;
123
+ timer_del(s->fifo_timeout_timer);
124
+ }
125
+ } else if (s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) {
126
+ s->reg[I_(UINTSP)] |= UINTSP_RXD;
127
}
128
129
s->reg[I_(UINTP)] = s->reg[I_(UINTSP)] & ~s->reg[I_(UINTM)];
130
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s)
131
}
132
}
133
134
+static void exynos4210_uart_timeout_int(void *opaque)
135
+{
136
+ Exynos4210UartState *s = opaque;
137
+
138
+ trace_exynos_uart_rx_timeout(s->channel, s->reg[I_(UTRSTAT)],
139
+ s->reg[I_(UINTSP)]);
140
+
141
+ if ((s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) ||
142
+ (s->reg[I_(UCON)] & (1 << 11))) {
143
+ s->reg[I_(UINTSP)] |= UINTSP_RXD;
144
+ s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_TIMEOUT;
145
+ exynos4210_uart_update_irq(s);
30
+ }
146
+ }
31
+}
147
+}
32
+
148
+
33
static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
149
static void exynos4210_uart_update_parameters(Exynos4210UartState *s)
34
void *data)
150
{
35
{
151
int speed, parity, data_bits, stop_bits;
36
IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
152
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_update_parameters(Exynos4210UartState *s)
37
153
ssp.data_bits = data_bits;
38
imrc->translate = smmuv3_translate;
154
ssp.stop_bits = stop_bits;
39
+ imrc->notify_flag_changed = smmuv3_notify_flag_changed;
155
40
}
156
+ s->wordtime = NANOSECONDS_PER_SECOND * (data_bits + stop_bits + 1) / speed;
41
157
+
42
static const TypeInfo smmuv3_type_info = {
158
qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
159
160
trace_exynos_uart_update_params(
161
- s->channel, speed, parity, data_bits, stop_bits);
162
+ s->channel, speed, parity, data_bits, stop_bits, s->wordtime);
163
+}
164
+
165
+static void exynos4210_uart_rx_timeout_set(Exynos4210UartState *s)
166
+{
167
+ if (s->reg[I_(UCON)] & 0x80) {
168
+ uint32_t timeout = ((s->reg[I_(UCON)] >> 12) & 0x0f) * s->wordtime;
169
+
170
+ timer_mod(s->fifo_timeout_timer,
171
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
172
+ } else {
173
+ timer_del(s->fifo_timeout_timer);
174
+ }
175
}
176
177
static void exynos4210_uart_write(void *opaque, hwaddr offset,
178
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
179
exynos4210_uart_update_irq(s);
180
break;
181
case UTRSTAT:
182
+ if (val & UTRSTAT_Rx_TIMEOUT) {
183
+ s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_TIMEOUT;
184
+ }
185
+ break;
186
case UERSTAT:
187
case UFSTAT:
188
case UMSTAT:
189
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
190
break;
191
}
192
}
193
+
194
static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset,
195
unsigned size)
196
{
197
@@ -XXX,XX +XXX,XX @@ static int exynos4210_uart_can_receive(void *opaque)
198
return fifo_empty_elements_number(&s->rx);
199
}
200
201
-
202
static void exynos4210_uart_receive(void *opaque, const uint8_t *buf, int size)
203
{
204
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
205
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_receive(void *opaque, const uint8_t *buf, int size)
206
207
if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
208
if (fifo_empty_elements_number(&s->rx) < size) {
209
- for (i = 0; i < fifo_empty_elements_number(&s->rx); i++) {
210
- fifo_store(&s->rx, buf[i]);
211
- }
212
+ size = fifo_empty_elements_number(&s->rx);
213
s->reg[I_(UINTSP)] |= UINTSP_ERROR;
214
- s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY;
215
- } else {
216
- for (i = 0; i < size; i++) {
217
- fifo_store(&s->rx, buf[i]);
218
- }
219
- s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY;
220
}
221
- /* XXX: Around here we maybe should check Rx trigger level */
222
- s->reg[I_(UINTSP)] |= UINTSP_RXD;
223
+ for (i = 0; i < size; i++) {
224
+ fifo_store(&s->rx, buf[i]);
225
+ }
226
+ exynos4210_uart_rx_timeout_set(s);
227
} else {
228
s->reg[I_(URXH)] = buf[0];
229
- s->reg[I_(UINTSP)] |= UINTSP_RXD;
230
- s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY;
231
}
232
+ s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY;
233
234
exynos4210_uart_update_irq(s);
235
}
236
@@ -XXX,XX +XXX,XX @@ static int exynos4210_uart_post_load(void *opaque, int version_id)
237
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
238
239
exynos4210_uart_update_parameters(s);
240
+ exynos4210_uart_rx_timeout_set(s);
241
242
return 0;
243
}
244
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_init(Object *obj)
245
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
246
Exynos4210UartState *s = EXYNOS4210_UART(dev);
247
248
+ s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
249
+ exynos4210_uart_timeout_int, s);
250
+ s->wordtime = NANOSECONDS_PER_SECOND * 10 / 9600;
251
+
252
/* memory mapping */
253
memory_region_init_io(&s->iomem, obj, &exynos4210_uart_ops, s,
254
"exynos4210.uart", EXYNOS4210_UART_REGS_MEM_SIZE);
255
diff --git a/hw/char/trace-events b/hw/char/trace-events
256
index XXXXXXX..XXXXXXX 100644
257
--- a/hw/char/trace-events
258
+++ b/hw/char/trace-events
259
@@ -XXX,XX +XXX,XX @@ nrf51_uart_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%" PR
260
# exynos4210_uart.c
261
exynos_uart_irq_raised(uint32_t channel, uint32_t reg) "UART%d: IRQ raised: 0x%08"PRIx32
262
exynos_uart_irq_lowered(uint32_t channel) "UART%d: IRQ lowered"
263
-exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int data, int stop) "UART%d: speed: %d, parity: %c, data bits: %d, stop bits: %d"
264
+exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int data, int stop, uint64_t wordtime) "UART%d: speed: %d, parity: %c, data bits: %d, stop bits: %d wordtime: %"PRId64"ns"
265
exynos_uart_write(uint32_t channel, uint32_t offset, const char *name, uint64_t val) "UART%d: <0x%04x> %s <- 0x%" PRIx64
266
exynos_uart_read(uint32_t channel, uint32_t offset, const char *name, uint64_t val) "UART%d: <0x%04x> %s -> 0x%" PRIx64
267
exynos_uart_rx_fifo_reset(uint32_t channel) "UART%d: Rx FIFO Reset"
268
@@ -XXX,XX +XXX,XX @@ exynos_uart_rx_error(uint32_t channel) "UART%d: Rx error"
269
exynos_uart_wo_read(uint32_t channel, const char *name, uint32_t reg) "UART%d: Trying to read from WO register: %s [0x%04"PRIx32"]"
270
exynos_uart_rxsize(uint32_t channel, uint32_t size) "UART%d: Rx FIFO size: %d"
271
exynos_uart_channel_error(uint32_t channel) "Wrong UART channel number: %d"
272
+exynos_uart_rx_timeout(uint32_t channel, uint32_t stat, uint32_t intsp) "UART%d: Rx timeout stat=0x%x intsp=0x%x"
43
--
273
--
44
2.17.0
274
2.20.1
45
275
46
276
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
ARM virt machine now exposes a new "iommu" option.
3
To support receive DMA, we need to inform the DMA controller if receive data
4
The SMMUv3 IOMMU is instantiated using -machine virt,iommu=smmuv3.
4
is available. Otherwise the DMA controller keeps requesting data, causing
5
receive errors.
5
6
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Implement this using an interrupt line. The instantiating code then needs
7
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
8
to connect the interrupt with the matching DMA controller GPIO pin.
9
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 1524665762-31355-15-git-send-email-eric.auger@redhat.com
11
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
12
Message-id: 20200123052540.6132-8-linux@roeck-us.net
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
hw/arm/virt.c | 36 ++++++++++++++++++++++++++++++++++++
15
hw/char/exynos4210_uart.c | 24 ++++++++++++++++++++++++
13
1 file changed, 36 insertions(+)
16
hw/char/trace-events | 2 ++
17
2 files changed, 26 insertions(+)
14
18
15
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
19
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/virt.c
21
--- a/hw/char/exynos4210_uart.c
18
+++ b/hw/arm/virt.c
22
+++ b/hw/char/exynos4210_uart.c
19
@@ -XXX,XX +XXX,XX @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
23
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210UartState {
20
}
24
25
CharBackend chr;
26
qemu_irq irq;
27
+ qemu_irq dmairq;
28
29
uint32_t channel;
30
31
@@ -XXX,XX +XXX,XX @@ exynos4210_uart_Rx_FIFO_trigger_level(const Exynos4210UartState *s)
32
return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
21
}
33
}
22
34
23
+static char *virt_get_iommu(Object *obj, Error **errp)
35
+/*
36
+ * Update Rx DMA busy signal if Rx DMA is enabled. For simplicity,
37
+ * mark DMA as busy if DMA is enabled and the receive buffer is empty.
38
+ */
39
+static void exynos4210_uart_update_dmabusy(Exynos4210UartState *s)
24
+{
40
+{
25
+ VirtMachineState *vms = VIRT_MACHINE(obj);
41
+ bool rx_dma_enabled = (s->reg[I_(UCON)] & 0x03) == 0x02;
42
+ uint32_t count = fifo_elements_number(&s->rx);
26
+
43
+
27
+ switch (vms->iommu) {
44
+ if (rx_dma_enabled && !count) {
28
+ case VIRT_IOMMU_NONE:
45
+ qemu_irq_raise(s->dmairq);
29
+ return g_strdup("none");
46
+ trace_exynos_uart_dmabusy(s->channel);
30
+ case VIRT_IOMMU_SMMUV3:
47
+ } else {
31
+ return g_strdup("smmuv3");
48
+ qemu_irq_lower(s->dmairq);
32
+ default:
49
+ trace_exynos_uart_dmaready(s->channel);
33
+ g_assert_not_reached();
34
+ }
50
+ }
35
+}
51
+}
36
+
52
+
37
+static void virt_set_iommu(Object *obj, const char *value, Error **errp)
53
static void exynos4210_uart_update_irq(Exynos4210UartState *s)
38
+{
39
+ VirtMachineState *vms = VIRT_MACHINE(obj);
40
+
41
+ if (!strcmp(value, "smmuv3")) {
42
+ vms->iommu = VIRT_IOMMU_SMMUV3;
43
+ } else if (!strcmp(value, "none")) {
44
+ vms->iommu = VIRT_IOMMU_NONE;
45
+ } else {
46
+ error_setg(errp, "Invalid iommu value");
47
+ error_append_hint(errp, "Valid values are none, smmuv3.\n");
48
+ }
49
+}
50
+
51
static CpuInstanceProperties
52
virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
53
{
54
{
54
@@ -XXX,XX +XXX,XX @@ static void virt_2_12_instance_init(Object *obj)
55
/*
55
NULL);
56
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s)
57
count = fifo_elements_number(&s->rx);
58
if ((count && !(s->reg[I_(UCON)] & 0x80)) ||
59
count >= exynos4210_uart_Rx_FIFO_trigger_level(s)) {
60
+ exynos4210_uart_update_dmabusy(s);
61
s->reg[I_(UINTSP)] |= UINTSP_RXD;
62
timer_del(s->fifo_timeout_timer);
63
}
64
} else if (s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) {
65
+ exynos4210_uart_update_dmabusy(s);
66
s->reg[I_(UINTSP)] |= UINTSP_RXD;
56
}
67
}
57
68
58
+ /* Default disallows iommu instantiation */
69
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_timeout_int(void *opaque)
59
+ vms->iommu = VIRT_IOMMU_NONE;
70
(s->reg[I_(UCON)] & (1 << 11))) {
60
+ object_property_add_str(obj, "iommu", virt_get_iommu, virt_set_iommu, NULL);
71
s->reg[I_(UINTSP)] |= UINTSP_RXD;
61
+ object_property_set_description(obj, "iommu",
72
s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_TIMEOUT;
62
+ "Set the IOMMU type. "
73
+ exynos4210_uart_update_dmabusy(s);
63
+ "Valid values are none and smmuv3",
74
exynos4210_uart_update_irq(s);
64
+ NULL);
75
}
65
+
66
vms->memmap = a15memmap;
67
vms->irqmap = a15irqmap;
68
}
76
}
77
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset,
78
s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY;
79
res = s->reg[I_(URXH)];
80
}
81
+ exynos4210_uart_update_dmabusy(s);
82
trace_exynos_uart_read(s->channel, offset,
83
exynos4210_uart_regname(offset), res);
84
return res;
85
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_init(Object *obj)
86
sysbus_init_mmio(dev, &s->iomem);
87
88
sysbus_init_irq(dev, &s->irq);
89
+ sysbus_init_irq(dev, &s->dmairq);
90
}
91
92
static void exynos4210_uart_realize(DeviceState *dev, Error **errp)
93
diff --git a/hw/char/trace-events b/hw/char/trace-events
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/char/trace-events
96
+++ b/hw/char/trace-events
97
@@ -XXX,XX +XXX,XX @@ nrf51_uart_read(uint64_t addr, uint64_t r, unsigned int size) "addr 0x%" PRIx64
98
nrf51_uart_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%" PRIx64 " value 0x%" PRIx64 " size %u"
99
100
# exynos4210_uart.c
101
+exynos_uart_dmabusy(uint32_t channel) "UART%d: DMA busy (Rx buffer empty)"
102
+exynos_uart_dmaready(uint32_t channel) "UART%d: DMA ready"
103
exynos_uart_irq_raised(uint32_t channel, uint32_t reg) "UART%d: IRQ raised: 0x%08"PRIx32
104
exynos_uart_irq_lowered(uint32_t channel) "UART%d: IRQ lowered"
105
exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int data, int stop, uint64_t wordtime) "UART%d: speed: %d, parity: %c, data bits: %d, stop bits: %d wordtime: %"PRId64"ns"
69
--
106
--
70
2.17.0
107
2.20.1
71
108
72
109
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
Let's introduce a helper function aiming at recording an
3
The Exynos4210 serial driver uses an interrupt line to signal if receive
4
event in the event queue.
4
data is available. Connect that interrupt with the DMA controller's
5
'peripheral busy' gpio pin to stop the DMA if there is no more receive
6
data available. Without this patch, receive DMA runs wild and fills the
7
entire receive DMA buffer with invalid data.
5
8
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1524665762-31355-9-git-send-email-eric.auger@redhat.com
10
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
11
Message-id: 20200123052540.6132-9-linux@roeck-us.net
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
hw/arm/smmuv3-internal.h | 148 ++++++++++++++++++++++++++++++++++++++-
14
hw/arm/exynos4210.c | 42 +++++++++++++++++++++++++++++-------------
12
hw/arm/smmuv3.c | 108 ++++++++++++++++++++++++++--
15
1 file changed, 29 insertions(+), 13 deletions(-)
13
hw/arm/trace-events | 1 +
14
3 files changed, 249 insertions(+), 8 deletions(-)
15
16
16
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
17
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/smmuv3-internal.h
19
--- a/hw/arm/exynos4210.c
19
+++ b/hw/arm/smmuv3-internal.h
20
+++ b/hw/arm/exynos4210.c
20
@@ -XXX,XX +XXX,XX @@ static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type)
21
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_calc_affinity(int cpu)
21
s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
22
return (0x9 << ARM_AFF1_SHIFT) | cpu;
22
}
23
}
23
24
24
-void smmuv3_write_eventq(SMMUv3State *s, Evt *evt);
25
-static void pl330_create(uint32_t base, qemu_or_irq *orgate, qemu_irq irq,
25
-
26
- int nreq, int nevents, int width)
26
/* Commands */
27
+static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate,
27
28
+ qemu_irq irq, int nreq, int nevents, int width)
28
typedef enum SMMUCommandType {
29
{
29
@@ -XXX,XX +XXX,XX @@ enum { /* Command completion notification */
30
SysBusDevice *busdev;
30
31
DeviceState *dev;
31
#define SMMU_FEATURE_2LVL_STE (1 << 0)
32
@@ -XXX,XX +XXX,XX @@ static void pl330_create(uint32_t base, qemu_or_irq *orgate, qemu_irq irq,
32
33
sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i));
33
+/* Events */
34
}
35
qdev_connect_gpio_out(DEVICE(orgate), 0, irq);
36
+ return dev;
37
}
38
39
static void exynos4210_realize(DeviceState *socdev, Error **errp)
40
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
41
MemoryRegion *system_mem = get_system_memory();
42
qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
43
SysBusDevice *busdev;
44
- DeviceState *dev;
45
+ DeviceState *dev, *uart[4], *pl330[3];
46
int i, n;
47
48
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
49
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
50
51
52
/*** UARTs ***/
53
- exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
54
+ uart[0] = exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
55
EXYNOS4210_UART0_FIFO_SIZE, 0, serial_hd(0),
56
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);
57
58
- exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
59
+ uart[1] = exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
60
EXYNOS4210_UART1_FIFO_SIZE, 1, serial_hd(1),
61
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);
62
63
- exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
64
+ uart[2] = exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
65
EXYNOS4210_UART2_FIFO_SIZE, 2, serial_hd(2),
66
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);
67
68
- exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
69
+ uart[3] = exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
70
EXYNOS4210_UART3_FIFO_SIZE, 3, serial_hd(3),
71
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);
72
73
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
74
s->irq_table[exynos4210_get_irq(28, 3)]);
75
76
/*** DMA controllers ***/
77
- pl330_create(EXYNOS4210_PL330_BASE0_ADDR, &s->pl330_irq_orgate[0],
78
- s->irq_table[exynos4210_get_irq(21, 0)], 32, 32, 32);
79
- pl330_create(EXYNOS4210_PL330_BASE1_ADDR, &s->pl330_irq_orgate[1],
80
- s->irq_table[exynos4210_get_irq(21, 1)], 32, 32, 32);
81
- pl330_create(EXYNOS4210_PL330_BASE2_ADDR, &s->pl330_irq_orgate[2],
82
- s->irq_table[exynos4210_get_irq(20, 1)], 1, 31, 64);
83
+ pl330[0] = pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
84
+ &s->pl330_irq_orgate[0],
85
+ s->irq_table[exynos4210_get_irq(21, 0)],
86
+ 32, 32, 32);
87
+ pl330[1] = pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
88
+ &s->pl330_irq_orgate[1],
89
+ s->irq_table[exynos4210_get_irq(21, 1)],
90
+ 32, 32, 32);
91
+ pl330[2] = pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
92
+ &s->pl330_irq_orgate[2],
93
+ s->irq_table[exynos4210_get_irq(20, 1)],
94
+ 1, 31, 64);
34
+
95
+
35
+typedef enum SMMUEventType {
96
+ sysbus_connect_irq(SYS_BUS_DEVICE(uart[0]), 1,
36
+ SMMU_EVT_OK = 0x00,
97
+ qdev_get_gpio_in(pl330[0], 15));
37
+ SMMU_EVT_F_UUT ,
98
+ sysbus_connect_irq(SYS_BUS_DEVICE(uart[1]), 1,
38
+ SMMU_EVT_C_BAD_STREAMID ,
99
+ qdev_get_gpio_in(pl330[1], 15));
39
+ SMMU_EVT_F_STE_FETCH ,
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(uart[2]), 1,
40
+ SMMU_EVT_C_BAD_STE ,
101
+ qdev_get_gpio_in(pl330[0], 17));
41
+ SMMU_EVT_F_BAD_ATS_TREQ ,
102
+ sysbus_connect_irq(SYS_BUS_DEVICE(uart[3]), 1,
42
+ SMMU_EVT_F_STREAM_DISABLED ,
103
+ qdev_get_gpio_in(pl330[1], 17));
43
+ SMMU_EVT_F_TRANS_FORBIDDEN ,
44
+ SMMU_EVT_C_BAD_SUBSTREAMID ,
45
+ SMMU_EVT_F_CD_FETCH ,
46
+ SMMU_EVT_C_BAD_CD ,
47
+ SMMU_EVT_F_WALK_EABT ,
48
+ SMMU_EVT_F_TRANSLATION = 0x10,
49
+ SMMU_EVT_F_ADDR_SIZE ,
50
+ SMMU_EVT_F_ACCESS ,
51
+ SMMU_EVT_F_PERMISSION ,
52
+ SMMU_EVT_F_TLB_CONFLICT = 0x20,
53
+ SMMU_EVT_F_CFG_CONFLICT ,
54
+ SMMU_EVT_E_PAGE_REQ = 0x24,
55
+} SMMUEventType;
56
+
57
+static const char *event_stringify[] = {
58
+ [SMMU_EVT_OK] = "SMMU_EVT_OK",
59
+ [SMMU_EVT_F_UUT] = "SMMU_EVT_F_UUT",
60
+ [SMMU_EVT_C_BAD_STREAMID] = "SMMU_EVT_C_BAD_STREAMID",
61
+ [SMMU_EVT_F_STE_FETCH] = "SMMU_EVT_F_STE_FETCH",
62
+ [SMMU_EVT_C_BAD_STE] = "SMMU_EVT_C_BAD_STE",
63
+ [SMMU_EVT_F_BAD_ATS_TREQ] = "SMMU_EVT_F_BAD_ATS_TREQ",
64
+ [SMMU_EVT_F_STREAM_DISABLED] = "SMMU_EVT_F_STREAM_DISABLED",
65
+ [SMMU_EVT_F_TRANS_FORBIDDEN] = "SMMU_EVT_F_TRANS_FORBIDDEN",
66
+ [SMMU_EVT_C_BAD_SUBSTREAMID] = "SMMU_EVT_C_BAD_SUBSTREAMID",
67
+ [SMMU_EVT_F_CD_FETCH] = "SMMU_EVT_F_CD_FETCH",
68
+ [SMMU_EVT_C_BAD_CD] = "SMMU_EVT_C_BAD_CD",
69
+ [SMMU_EVT_F_WALK_EABT] = "SMMU_EVT_F_WALK_EABT",
70
+ [SMMU_EVT_F_TRANSLATION] = "SMMU_EVT_F_TRANSLATION",
71
+ [SMMU_EVT_F_ADDR_SIZE] = "SMMU_EVT_F_ADDR_SIZE",
72
+ [SMMU_EVT_F_ACCESS] = "SMMU_EVT_F_ACCESS",
73
+ [SMMU_EVT_F_PERMISSION] = "SMMU_EVT_F_PERMISSION",
74
+ [SMMU_EVT_F_TLB_CONFLICT] = "SMMU_EVT_F_TLB_CONFLICT",
75
+ [SMMU_EVT_F_CFG_CONFLICT] = "SMMU_EVT_F_CFG_CONFLICT",
76
+ [SMMU_EVT_E_PAGE_REQ] = "SMMU_EVT_E_PAGE_REQ",
77
+};
78
+
79
+static inline const char *smmu_event_string(SMMUEventType type)
80
+{
81
+ if (type < ARRAY_SIZE(event_stringify)) {
82
+ return event_stringify[type] ? event_stringify[type] : "UNKNOWN";
83
+ } else {
84
+ return "INVALID";
85
+ }
86
+}
87
+
88
+/* Encode an event record */
89
+typedef struct SMMUEventInfo {
90
+ SMMUEventType type;
91
+ uint32_t sid;
92
+ bool recorded;
93
+ bool record_trans_faults;
94
+ union {
95
+ struct {
96
+ uint32_t ssid;
97
+ bool ssv;
98
+ dma_addr_t addr;
99
+ bool rnw;
100
+ bool pnu;
101
+ bool ind;
102
+ } f_uut;
103
+ struct SSIDInfo {
104
+ uint32_t ssid;
105
+ bool ssv;
106
+ } c_bad_streamid;
107
+ struct SSIDAddrInfo {
108
+ uint32_t ssid;
109
+ bool ssv;
110
+ dma_addr_t addr;
111
+ } f_ste_fetch;
112
+ struct SSIDInfo c_bad_ste;
113
+ struct {
114
+ dma_addr_t addr;
115
+ bool rnw;
116
+ } f_transl_forbidden;
117
+ struct {
118
+ uint32_t ssid;
119
+ } c_bad_substream;
120
+ struct SSIDAddrInfo f_cd_fetch;
121
+ struct SSIDInfo c_bad_cd;
122
+ struct FullInfo {
123
+ bool stall;
124
+ uint16_t stag;
125
+ uint32_t ssid;
126
+ bool ssv;
127
+ bool s2;
128
+ dma_addr_t addr;
129
+ bool rnw;
130
+ bool pnu;
131
+ bool ind;
132
+ uint8_t class;
133
+ dma_addr_t addr2;
134
+ } f_walk_eabt;
135
+ struct FullInfo f_translation;
136
+ struct FullInfo f_addr_size;
137
+ struct FullInfo f_access;
138
+ struct FullInfo f_permission;
139
+ struct SSIDInfo f_cfg_conflict;
140
+ /**
141
+ * not supported yet:
142
+ * F_BAD_ATS_TREQ
143
+ * F_BAD_ATS_TREQ
144
+ * F_TLB_CONFLICT
145
+ * E_PAGE_REQUEST
146
+ * IMPDEF_EVENTn
147
+ */
148
+ } u;
149
+} SMMUEventInfo;
150
+
151
+/* EVTQ fields */
152
+
153
+#define EVT_Q_OVERFLOW (1 << 31)
154
+
155
+#define EVT_SET_TYPE(x, v) deposit32((x)->word[0], 0 , 8 , v)
156
+#define EVT_SET_SSV(x, v) deposit32((x)->word[0], 11, 1 , v)
157
+#define EVT_SET_SSID(x, v) deposit32((x)->word[0], 12, 20, v)
158
+#define EVT_SET_SID(x, v) ((x)->word[1] = v)
159
+#define EVT_SET_STAG(x, v) deposit32((x)->word[2], 0 , 16, v)
160
+#define EVT_SET_STALL(x, v) deposit32((x)->word[2], 31, 1 , v)
161
+#define EVT_SET_PNU(x, v) deposit32((x)->word[3], 1 , 1 , v)
162
+#define EVT_SET_IND(x, v) deposit32((x)->word[3], 2 , 1 , v)
163
+#define EVT_SET_RNW(x, v) deposit32((x)->word[3], 3 , 1 , v)
164
+#define EVT_SET_S2(x, v) deposit32((x)->word[3], 7 , 1 , v)
165
+#define EVT_SET_CLASS(x, v) deposit32((x)->word[3], 8 , 2 , v)
166
+#define EVT_SET_ADDR(x, addr) \
167
+ do { \
168
+ (x)->word[5] = (uint32_t)(addr >> 32); \
169
+ (x)->word[4] = (uint32_t)(addr & 0xffffffff); \
170
+ } while (0)
171
+#define EVT_SET_ADDR2(x, addr) \
172
+ do { \
173
+ deposit32((x)->word[7], 3, 29, addr >> 16); \
174
+ deposit32((x)->word[7], 0, 16, addr & 0xffff);\
175
+ } while (0)
176
+
177
+void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
178
+
179
#endif
180
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
181
index XXXXXXX..XXXXXXX 100644
182
--- a/hw/arm/smmuv3.c
183
+++ b/hw/arm/smmuv3.c
184
@@ -XXX,XX +XXX,XX @@ static MemTxResult queue_write(SMMUQueue *q, void *data)
185
return MEMTX_OK;
186
}
104
}
187
105
188
-void smmuv3_write_eventq(SMMUv3State *s, Evt *evt)
106
static void exynos4210_init(Object *obj)
189
+static MemTxResult smmuv3_write_eventq(SMMUv3State *s, Evt *evt)
190
{
191
SMMUQueue *q = &s->eventq;
192
+ MemTxResult r;
193
+
194
+ if (!smmuv3_eventq_enabled(s)) {
195
+ return MEMTX_ERROR;
196
+ }
197
+
198
+ if (smmuv3_q_full(q)) {
199
+ return MEMTX_ERROR;
200
+ }
201
+
202
+ r = queue_write(q, evt);
203
+ if (r != MEMTX_OK) {
204
+ return r;
205
+ }
206
+
207
+ if (smmuv3_q_empty(q)) {
208
+ smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0);
209
+ }
210
+ return MEMTX_OK;
211
+}
212
+
213
+void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info)
214
+{
215
+ Evt evt;
216
+ MemTxResult r;
217
218
if (!smmuv3_eventq_enabled(s)) {
219
return;
220
}
221
222
- if (smmuv3_q_full(q)) {
223
+ EVT_SET_TYPE(&evt, info->type);
224
+ EVT_SET_SID(&evt, info->sid);
225
+
226
+ switch (info->type) {
227
+ case SMMU_EVT_OK:
228
return;
229
+ case SMMU_EVT_F_UUT:
230
+ EVT_SET_SSID(&evt, info->u.f_uut.ssid);
231
+ EVT_SET_SSV(&evt, info->u.f_uut.ssv);
232
+ EVT_SET_ADDR(&evt, info->u.f_uut.addr);
233
+ EVT_SET_RNW(&evt, info->u.f_uut.rnw);
234
+ EVT_SET_PNU(&evt, info->u.f_uut.pnu);
235
+ EVT_SET_IND(&evt, info->u.f_uut.ind);
236
+ break;
237
+ case SMMU_EVT_C_BAD_STREAMID:
238
+ EVT_SET_SSID(&evt, info->u.c_bad_streamid.ssid);
239
+ EVT_SET_SSV(&evt, info->u.c_bad_streamid.ssv);
240
+ break;
241
+ case SMMU_EVT_F_STE_FETCH:
242
+ EVT_SET_SSID(&evt, info->u.f_ste_fetch.ssid);
243
+ EVT_SET_SSV(&evt, info->u.f_ste_fetch.ssv);
244
+ EVT_SET_ADDR(&evt, info->u.f_ste_fetch.addr);
245
+ break;
246
+ case SMMU_EVT_C_BAD_STE:
247
+ EVT_SET_SSID(&evt, info->u.c_bad_ste.ssid);
248
+ EVT_SET_SSV(&evt, info->u.c_bad_ste.ssv);
249
+ break;
250
+ case SMMU_EVT_F_STREAM_DISABLED:
251
+ break;
252
+ case SMMU_EVT_F_TRANS_FORBIDDEN:
253
+ EVT_SET_ADDR(&evt, info->u.f_transl_forbidden.addr);
254
+ EVT_SET_RNW(&evt, info->u.f_transl_forbidden.rnw);
255
+ break;
256
+ case SMMU_EVT_C_BAD_SUBSTREAMID:
257
+ EVT_SET_SSID(&evt, info->u.c_bad_substream.ssid);
258
+ break;
259
+ case SMMU_EVT_F_CD_FETCH:
260
+ EVT_SET_SSID(&evt, info->u.f_cd_fetch.ssid);
261
+ EVT_SET_SSV(&evt, info->u.f_cd_fetch.ssv);
262
+ EVT_SET_ADDR(&evt, info->u.f_cd_fetch.addr);
263
+ break;
264
+ case SMMU_EVT_C_BAD_CD:
265
+ EVT_SET_SSID(&evt, info->u.c_bad_cd.ssid);
266
+ EVT_SET_SSV(&evt, info->u.c_bad_cd.ssv);
267
+ break;
268
+ case SMMU_EVT_F_WALK_EABT:
269
+ case SMMU_EVT_F_TRANSLATION:
270
+ case SMMU_EVT_F_ADDR_SIZE:
271
+ case SMMU_EVT_F_ACCESS:
272
+ case SMMU_EVT_F_PERMISSION:
273
+ EVT_SET_STALL(&evt, info->u.f_walk_eabt.stall);
274
+ EVT_SET_STAG(&evt, info->u.f_walk_eabt.stag);
275
+ EVT_SET_SSID(&evt, info->u.f_walk_eabt.ssid);
276
+ EVT_SET_SSV(&evt, info->u.f_walk_eabt.ssv);
277
+ EVT_SET_S2(&evt, info->u.f_walk_eabt.s2);
278
+ EVT_SET_ADDR(&evt, info->u.f_walk_eabt.addr);
279
+ EVT_SET_RNW(&evt, info->u.f_walk_eabt.rnw);
280
+ EVT_SET_PNU(&evt, info->u.f_walk_eabt.pnu);
281
+ EVT_SET_IND(&evt, info->u.f_walk_eabt.ind);
282
+ EVT_SET_CLASS(&evt, info->u.f_walk_eabt.class);
283
+ EVT_SET_ADDR2(&evt, info->u.f_walk_eabt.addr2);
284
+ break;
285
+ case SMMU_EVT_F_CFG_CONFLICT:
286
+ EVT_SET_SSID(&evt, info->u.f_cfg_conflict.ssid);
287
+ EVT_SET_SSV(&evt, info->u.f_cfg_conflict.ssv);
288
+ break;
289
+ /* rest is not implemented */
290
+ case SMMU_EVT_F_BAD_ATS_TREQ:
291
+ case SMMU_EVT_F_TLB_CONFLICT:
292
+ case SMMU_EVT_E_PAGE_REQ:
293
+ default:
294
+ g_assert_not_reached();
295
}
296
297
- queue_write(q, evt);
298
-
299
- if (smmuv3_q_empty(q)) {
300
- smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0);
301
+ trace_smmuv3_record_event(smmu_event_string(info->type), info->sid);
302
+ r = smmuv3_write_eventq(s, &evt);
303
+ if (r != MEMTX_OK) {
304
+ smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_EVENTQ_ABT_ERR_MASK);
305
}
306
+ info->recorded = true;
307
}
308
309
static void smmuv3_init_regs(SMMUv3State *s)
310
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
311
index XXXXXXX..XXXXXXX 100644
312
--- a/hw/arm/trace-events
313
+++ b/hw/arm/trace-events
314
@@ -XXX,XX +XXX,XX @@ smmuv3_write_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr:
315
smmuv3_write_mmio_idr(uint64_t addr, uint64_t val) "write to RO/Unimpl reg 0x%lx val64:0x%lx"
316
smmuv3_write_mmio_evtq_cons_bef_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "Before clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
317
smmuv3_write_mmio_evtq_cons_after_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "after clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
318
+smmuv3_record_event(const char *type, uint32_t sid) "%s sid=%d"
319
--
107
--
320
2.17.0
108
2.20.1
321
109
322
110
diff view generated by jsdifflib
Deleted patch
1
From: Prem Mallappa <prem.mallappa@broadcom.com>
2
1
3
This patch builds the smmuv3 node in the ACPI IORT table.
4
5
The RID space of the root complex, which spans 0x0-0x10000
6
maps to streamid space 0x0-0x10000 in smmuv3, which in turn
7
maps to deviceid space 0x0-0x10000 in the ITS group.
8
9
The guest must feature the IOMMU probe deferral series
10
(https://lkml.org/lkml/2017/4/10/214) which fixes streamid
11
multiple lookup. This bug is not related to the SMMU emulation.
12
13
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
14
Signed-off-by: Eric Auger <eric.auger@redhat.com>
15
Reviewed-by: Shannon Zhao <zhaoshenglong@huawei.com>
16
Message-id: 1524665762-31355-14-git-send-email-eric.auger@redhat.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
include/hw/acpi/acpi-defs.h | 15 ++++++++++
20
hw/arm/virt-acpi-build.c | 55 ++++++++++++++++++++++++++++++++-----
21
2 files changed, 63 insertions(+), 7 deletions(-)
22
23
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/acpi/acpi-defs.h
26
+++ b/include/hw/acpi/acpi-defs.h
27
@@ -XXX,XX +XXX,XX @@ struct AcpiIortItsGroup {
28
} QEMU_PACKED;
29
typedef struct AcpiIortItsGroup AcpiIortItsGroup;
30
31
+struct AcpiIortSmmu3 {
32
+ ACPI_IORT_NODE_HEADER_DEF
33
+ uint64_t base_address;
34
+ uint32_t flags;
35
+ uint32_t reserved2;
36
+ uint64_t vatos_address;
37
+ uint32_t model;
38
+ uint32_t event_gsiv;
39
+ uint32_t pri_gsiv;
40
+ uint32_t gerr_gsiv;
41
+ uint32_t sync_gsiv;
42
+ AcpiIortIdMapping id_mapping_array[0];
43
+} QEMU_PACKED;
44
+typedef struct AcpiIortSmmu3 AcpiIortSmmu3;
45
+
46
struct AcpiIortRC {
47
ACPI_IORT_NODE_HEADER_DEF
48
AcpiIortMemoryAccess memory_properties;
49
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/virt-acpi-build.c
52
+++ b/hw/arm/virt-acpi-build.c
53
@@ -XXX,XX +XXX,XX @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned xsdt_tbl_offset)
54
}
55
56
static void
57
-build_iort(GArray *table_data, BIOSLinker *linker)
58
+build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
59
{
60
- int iort_start = table_data->len;
61
+ int nb_nodes, iort_start = table_data->len;
62
AcpiIortIdMapping *idmap;
63
AcpiIortItsGroup *its;
64
AcpiIortTable *iort;
65
- size_t node_size, iort_length;
66
+ AcpiIortSmmu3 *smmu;
67
+ size_t node_size, iort_length, smmu_offset = 0;
68
AcpiIortRC *rc;
69
70
iort = acpi_data_push(table_data, sizeof(*iort));
71
72
+ if (vms->iommu == VIRT_IOMMU_SMMUV3) {
73
+ nb_nodes = 3; /* RC, ITS, SMMUv3 */
74
+ } else {
75
+ nb_nodes = 2; /* RC, ITS */
76
+ }
77
+
78
iort_length = sizeof(*iort);
79
- iort->node_count = cpu_to_le32(2); /* RC and ITS nodes */
80
+ iort->node_count = cpu_to_le32(nb_nodes);
81
iort->node_offset = cpu_to_le32(sizeof(*iort));
82
83
/* ITS group node */
84
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker)
85
its->its_count = cpu_to_le32(1);
86
its->identifiers[0] = 0; /* MADT translation_id */
87
88
+ if (vms->iommu == VIRT_IOMMU_SMMUV3) {
89
+ int irq = vms->irqmap[VIRT_SMMU];
90
+
91
+ /* SMMUv3 node */
92
+ smmu_offset = iort->node_offset + node_size;
93
+ node_size = sizeof(*smmu) + sizeof(*idmap);
94
+ iort_length += node_size;
95
+ smmu = acpi_data_push(table_data, node_size);
96
+
97
+ smmu->type = ACPI_IORT_NODE_SMMU_V3;
98
+ smmu->length = cpu_to_le16(node_size);
99
+ smmu->mapping_count = cpu_to_le32(1);
100
+ smmu->mapping_offset = cpu_to_le32(sizeof(*smmu));
101
+ smmu->base_address = cpu_to_le64(vms->memmap[VIRT_SMMU].base);
102
+ smmu->event_gsiv = cpu_to_le32(irq);
103
+ smmu->pri_gsiv = cpu_to_le32(irq + 1);
104
+ smmu->gerr_gsiv = cpu_to_le32(irq + 2);
105
+ smmu->sync_gsiv = cpu_to_le32(irq + 3);
106
+
107
+ /* Identity RID mapping covering the whole input RID range */
108
+ idmap = &smmu->id_mapping_array[0];
109
+ idmap->input_base = 0;
110
+ idmap->id_count = cpu_to_le32(0xFFFF);
111
+ idmap->output_base = 0;
112
+ /* output IORT node is the ITS group node (the first node) */
113
+ idmap->output_reference = cpu_to_le32(iort->node_offset);
114
+ }
115
+
116
/* Root Complex Node */
117
node_size = sizeof(*rc) + sizeof(*idmap);
118
iort_length += node_size;
119
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker)
120
idmap->input_base = 0;
121
idmap->id_count = cpu_to_le32(0xFFFF);
122
idmap->output_base = 0;
123
- /* output IORT node is the ITS group node (the first node) */
124
- idmap->output_reference = cpu_to_le32(iort->node_offset);
125
+
126
+ if (vms->iommu == VIRT_IOMMU_SMMUV3) {
127
+ /* output IORT node is the smmuv3 node */
128
+ idmap->output_reference = cpu_to_le32(smmu_offset);
129
+ } else {
130
+ /* output IORT node is the ITS group node (the first node) */
131
+ idmap->output_reference = cpu_to_le32(iort->node_offset);
132
+ }
133
134
iort->length = cpu_to_le32(iort_length);
135
136
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
137
138
if (its_class_name() && !vmc->no_its) {
139
acpi_add_table(table_offsets, tables_blob);
140
- build_iort(tables_blob, tables->linker);
141
+ build_iort(tables_blob, tables->linker, vms);
142
}
143
144
/* XSDT is pointed to by RSDP */
145
--
146
2.17.0
147
148
diff view generated by jsdifflib