1
target-arm queue. This has the "plumb txattrs through various
1
target-arm queue for softfreeze:
2
bits of exec.c" patches, and a collection of bug fixes from
2
This has all the big stuff I want to get in for softfreeze;
3
various people.
3
there may be one or two smaller patches I pick up later in
4
the week.
4
5
5
thanks
6
thanks
6
-- PMM
7
-- PMM
7
8
9
The following changes since commit 0984a157c1c053394adbf64ed7de97f1aebe6a2d:
8
10
9
11
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging (2019-03-05 09:33:20 +0000)
10
The following changes since commit a3ac12fba028df90f7b3dbec924995c126c41022:
11
12
Merge remote-tracking branch 'remotes/ehabkost/tags/numa-next-pull-request' into staging (2018-05-31 11:12:36 +0100)
13
12
14
are available in the Git repository at:
13
are available in the Git repository at:
15
14
16
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180531
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190305
17
16
18
for you to fetch changes up to 49d1dca0520ea71bc21867fab6647f474fcf857b:
17
for you to fetch changes up to 566528f823d1a2e9eb2d7b2ed839547cb31bfc34:
19
18
20
KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice (2018-05-31 14:52:53 +0100)
19
hw/arm/stellaris: Implement watchdog timer (2019-03-05 15:55:09 +0000)
21
20
22
----------------------------------------------------------------
21
----------------------------------------------------------------
23
target-arm queue:
22
target-arm queue:
24
* target/arm: Honour FPCR.FZ in FRECPX
23
* Fix PC test for LDM (exception return)
25
* MAINTAINERS: Add entries for newer MPS2 boards and devices
24
* Implement ARMv8.0-SB
26
* hw/intc/arm_gicv3: Fix APxR<n> register dispatching
25
* Implement ARMv8.0-PredInv
27
* arm_gicv3_kvm: fix bug in writing zero bits back to the in-kernel
26
* Implement ARMv8.4-CondM
28
GIC state
27
* Implement ARMv8.5-CondM
29
* tcg: Fix helper function vs host abi for float16
28
* Implement ARMv8.5-FRINT
30
* arm: fix qemu crash on startup with -bios option
29
* hw/arm/stellaris: Implement watchdog timer
31
* arm: fix malloc type mismatch
30
* virt: support more than 255GB of RAM
32
* xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors
33
* Correct CPACR reset value for v7 cores
34
* memory.h: Improve IOMMU related documentation
35
* exec: Plumb transaction attributes through various functions in
36
preparation for allowing IOMMUs to see them
37
* vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY
38
* ARM: ACPI: Fix use-after-free due to memory realloc
39
* KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice
40
31
41
----------------------------------------------------------------
32
----------------------------------------------------------------
42
Francisco Iglesias (1):
33
Eric Auger (9):
43
xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors
34
hw/arm/virt: Rename highmem IO regions
35
hw/arm/virt: Split the memory map description
36
hw/boards: Add a MachineState parameter to kvm_type callback
37
kvm: add kvm_arm_get_max_vm_ipa_size
38
vl: Set machine ram_size, maxram_size and ram_slots earlier
39
hw/arm/virt: Dynamic memory map depending on RAM requirements
40
hw/arm/virt: Implement kvm_type function for 4.0 machine
41
hw/arm/virt: Check the VCPU PA range in TCG mode
42
hw/arm/virt: Bump the 255GB initial RAM limit
44
43
45
Igor Mammedov (1):
44
Michel Heily (1):
46
arm: fix qemu crash on startup with -bios option
45
hw/arm/stellaris: Implement watchdog timer
47
46
48
Jan Kiszka (1):
47
Richard Henderson (11):
49
hw/intc/arm_gicv3: Fix APxR<n> register dispatching
48
target/arm: Fix PC test for LDM (exception return)
49
target/arm: Split out arm_sctlr
50
target/arm: Implement ARMv8.0-SB
51
target/arm: Implement ARMv8.0-PredInv
52
target/arm: Split helper_msr_i_pstate into 3
53
target/arm: Add set/clear_pstate_bits, share gen_ss_advance
54
target/arm: Rearrange disas_data_proc_reg
55
target/arm: Implement ARMv8.4-CondM
56
target/arm: Implement ARMv8.5-CondM
57
target/arm: Restructure handle_fp_1src_{single, double}
58
target/arm: Implement ARMv8.5-FRINT
50
59
51
Paolo Bonzini (1):
60
Shameer Kolothum (1):
52
arm: fix malloc type mismatch
61
hw/arm/boot: introduce fdt_add_memory_node helper
53
62
54
Peter Maydell (17):
63
include/hw/arm/virt.h | 16 +-
55
target/arm: Honour FPCR.FZ in FRECPX
64
include/hw/boards.h | 5 +-
56
MAINTAINERS: Add entries for newer MPS2 boards and devices
65
include/hw/watchdog/cmsdk-apb-watchdog.h | 8 +
57
Correct CPACR reset value for v7 cores
66
target/arm/cpu.h | 64 ++++-
58
memory.h: Improve IOMMU related documentation
67
target/arm/helper-a64.h | 3 +
59
Make tb_invalidate_phys_addr() take a MemTxAttrs argument
68
target/arm/helper.h | 8 +-
60
Make address_space_translate{, _cached}() take a MemTxAttrs argument
69
target/arm/internals.h | 15 +
61
Make address_space_map() take a MemTxAttrs argument
70
target/arm/kvm_arm.h | 13 +
62
Make address_space_access_valid() take a MemTxAttrs argument
71
target/arm/translate.h | 34 +++
63
Make flatview_extend_translation() take a MemTxAttrs argument
72
accel/kvm/kvm-all.c | 2 +-
64
Make memory_region_access_valid() take a MemTxAttrs argument
73
hw/arm/boot.c | 54 ++--
65
Make MemoryRegion valid.accepts callback take a MemTxAttrs argument
74
hw/arm/stellaris.c | 22 +-
66
Make flatview_access_valid() take a MemTxAttrs argument
75
hw/arm/virt-acpi-build.c | 10 +-
67
Make flatview_translate() take a MemTxAttrs argument
76
hw/arm/virt.c | 196 ++++++++++---
68
Make address_space_get_iotlb_entry() take a MemTxAttrs argument
77
hw/ppc/mac_newworld.c | 3 +-
69
Make flatview_do_translate() take a MemTxAttrs argument
78
hw/ppc/mac_oldworld.c | 2 +-
70
Make address_space_translate_iommu take a MemTxAttrs argument
79
hw/ppc/spapr.c | 2 +-
71
vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY
80
hw/watchdog/cmsdk-apb-watchdog.c | 74 ++++-
81
linux-user/elfload.c | 2 +
82
target/arm/cpu.c | 2 +
83
target/arm/cpu64.c | 6 +
84
target/arm/helper-a64.c | 30 ++
85
target/arm/helper.c | 63 +++-
86
target/arm/kvm.c | 10 +
87
target/arm/op_helper.c | 47 ---
88
target/arm/translate-a64.c | 478 +++++++++++++++++++++++--------
89
target/arm/translate.c | 35 ++-
90
target/arm/vfp_helper.c | 96 +++++++
91
vl.c | 6 +-
92
29 files changed, 1032 insertions(+), 274 deletions(-)
72
93
73
Richard Henderson (1):
74
tcg: Fix helper function vs host abi for float16
75
76
Shannon Zhao (3):
77
arm_gicv3_kvm: increase clroffset accordingly
78
ARM: ACPI: Fix use-after-free due to memory realloc
79
KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice
80
81
include/exec/exec-all.h | 5 +-
82
include/exec/helper-head.h | 2 +-
83
include/exec/memory-internal.h | 3 +-
84
include/exec/memory.h | 128 +++++++++++++++++++++++++++++++++++------
85
include/migration/vmstate.h | 3 +
86
include/sysemu/dma.h | 6 +-
87
accel/tcg/translate-all.c | 4 +-
88
exec.c | 95 ++++++++++++++++++------------
89
hw/arm/boot.c | 18 +++---
90
hw/arm/virt-acpi-build.c | 20 +++++--
91
hw/dma/xlnx-zdma.c | 10 +++-
92
hw/hppa/dino.c | 3 +-
93
hw/intc/arm_gic_kvm.c | 1 -
94
hw/intc/arm_gicv3_cpuif.c | 12 ++--
95
hw/intc/arm_gicv3_kvm.c | 2 +-
96
hw/nvram/fw_cfg.c | 12 ++--
97
hw/s390x/s390-pci-inst.c | 3 +-
98
hw/scsi/esp.c | 3 +-
99
hw/vfio/common.c | 3 +-
100
hw/virtio/vhost.c | 3 +-
101
hw/xen/xen_pt_msi.c | 3 +-
102
memory.c | 12 ++--
103
memory_ldst.inc.c | 18 +++---
104
target/arm/gdbstub.c | 3 +-
105
target/arm/helper-a64.c | 41 +++++++------
106
target/arm/helper.c | 90 ++++++++++++++++-------------
107
target/ppc/mmu-hash64.c | 3 +-
108
target/riscv/helper.c | 2 +-
109
target/s390x/diag.c | 6 +-
110
target/s390x/excp_helper.c | 3 +-
111
target/s390x/mmu_helper.c | 3 +-
112
target/s390x/sigp.c | 3 +-
113
target/xtensa/op_helper.c | 3 +-
114
MAINTAINERS | 9 ++-
115
34 files changed, 353 insertions(+), 182 deletions(-)
116
diff view generated by jsdifflib
1
Provide a VMSTATE_BOOL_SUB_ARRAY to go with VMSTATE_UINT8_SUB_ARRAY
1
From: Richard Henderson <richard.henderson@linaro.org>
2
and friends.
3
2
3
Found by inspection: Rn is the base register against which the
4
load began; I is the register within the mask being processed.
5
The exception return should of course be processed from the loaded PC.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190301202921.21209-1-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20180521140402.23318-23-peter.maydell@linaro.org
7
---
11
---
8
include/migration/vmstate.h | 3 +++
12
target/arm/translate.c | 2 +-
9
1 file changed, 3 insertions(+)
13
1 file changed, 1 insertion(+), 1 deletion(-)
10
14
11
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/include/migration/vmstate.h
17
--- a/target/arm/translate.c
14
+++ b/include/migration/vmstate.h
18
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
19
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
16
#define VMSTATE_BOOL_ARRAY(_f, _s, _n) \
20
} else if (i == rn) {
17
VMSTATE_BOOL_ARRAY_V(_f, _s, _n, 0)
21
loaded_var = tmp;
18
22
loaded_base = 1;
19
+#define VMSTATE_BOOL_SUB_ARRAY(_f, _s, _start, _num) \
23
- } else if (rn == 15 && exc_return) {
20
+ VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_bool, bool)
24
+ } else if (i == 15 && exc_return) {
21
+
25
store_pc_exc_ret(s, tmp);
22
#define VMSTATE_UINT16_ARRAY_V(_f, _s, _n, _v) \
26
} else {
23
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint16, uint16_t)
27
store_reg_from_load(s, i, tmp);
24
25
--
28
--
26
2.17.1
29
2.20.1
27
30
28
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Depending on the host abi, float16, aka uint16_t, values are
3
Minimize the number of places that will need updating when
4
passed and returned either zero-extended in the host register
4
the virtual host extensions are added.
5
or with garbage at the top of the host register.
6
5
7
The tcg code generator has so far been assuming garbage, as that
8
matches the x86 abi, but this is incorrect for other host abis.
9
Further, target/arm has so far been assuming zero-extended results,
10
so that it may store the 16-bit value into a 32-bit slot with the
11
high 16-bits already clear.
12
13
Rectify both problems by mapping "f16" in the helper definition
14
to uint32_t instead of (a typedef for) uint16_t. This forces
15
the host compiler to assume garbage in the upper 16 bits on input
16
and to zero-extend the result on output.
17
18
Cc: qemu-stable@nongnu.org
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20190301200501.16533-2-richard.henderson@linaro.org
21
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
22
Message-id: 20180522175629.24932-1-richard.henderson@linaro.org
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
10
---
26
include/exec/helper-head.h | 2 +-
11
target/arm/cpu.h | 26 ++++++++++++++++----------
27
target/arm/helper-a64.c | 35 +++++++++--------
12
target/arm/helper.c | 8 ++------
28
target/arm/helper.c | 80 +++++++++++++++++++-------------------
13
2 files changed, 18 insertions(+), 16 deletions(-)
29
3 files changed, 59 insertions(+), 58 deletions(-)
30
14
31
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
33
--- a/include/exec/helper-head.h
17
--- a/target/arm/cpu.h
34
+++ b/include/exec/helper-head.h
18
+++ b/target/arm/cpu.h
35
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static inline bool arm_sctlr_b(CPUARMState *env)
36
#define dh_ctype_int int
20
(env->cp15.sctlr_el[1] & SCTLR_B) != 0;
37
#define dh_ctype_i64 uint64_t
38
#define dh_ctype_s64 int64_t
39
-#define dh_ctype_f16 float16
40
+#define dh_ctype_f16 uint32_t
41
#define dh_ctype_f32 float32
42
#define dh_ctype_f64 float64
43
#define dh_ctype_ptr void *
44
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/helper-a64.c
47
+++ b/target/arm/helper-a64.c
48
@@ -XXX,XX +XXX,XX @@ static inline uint32_t float_rel_to_flags(int res)
49
return flags;
50
}
21
}
51
22
52
-uint64_t HELPER(vfp_cmph_a64)(float16 x, float16 y, void *fp_status)
23
+static inline uint64_t arm_sctlr(CPUARMState *env, int el)
53
+uint64_t HELPER(vfp_cmph_a64)(uint32_t x, uint32_t y, void *fp_status)
24
+{
25
+ if (el == 0) {
26
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
27
+ return env->cp15.sctlr_el[1];
28
+ } else {
29
+ return env->cp15.sctlr_el[el];
30
+ }
31
+}
32
+
33
+
34
/* Return true if the processor is in big-endian mode. */
35
static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
54
{
36
{
55
return float_rel_to_flags(float16_compare_quiet(x, y, fp_status));
37
- int cur_el;
38
-
39
/* In 32bit endianness is determined by looking at CPSR's E bit */
40
if (!is_a64(env)) {
41
return
42
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
43
arm_sctlr_b(env) ||
44
#endif
45
((env->uncached_cpsr & CPSR_E) ? 1 : 0);
46
+ } else {
47
+ int cur_el = arm_current_el(env);
48
+ uint64_t sctlr = arm_sctlr(env, cur_el);
49
+
50
+ return (sctlr & (cur_el ? SCTLR_EE : SCTLR_E0E)) != 0;
51
}
52
-
53
- cur_el = arm_current_el(env);
54
-
55
- if (cur_el == 0) {
56
- return (env->cp15.sctlr_el[1] & SCTLR_E0E) != 0;
57
- }
58
-
59
- return (env->cp15.sctlr_el[cur_el] & SCTLR_EE) != 0;
56
}
60
}
57
61
58
-uint64_t HELPER(vfp_cmpeh_a64)(float16 x, float16 y, void *fp_status)
62
#include "exec/cpu-all.h"
59
+uint64_t HELPER(vfp_cmpeh_a64)(uint32_t x, uint32_t y, void *fp_status)
60
{
61
return float_rel_to_flags(float16_compare(x, y, fp_status));
62
}
63
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
64
#define float64_three make_float64(0x4008000000000000ULL)
65
#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
66
67
-float16 HELPER(recpsf_f16)(float16 a, float16 b, void *fpstp)
68
+uint32_t HELPER(recpsf_f16)(uint32_t a, uint32_t b, void *fpstp)
69
{
70
float_status *fpst = fpstp;
71
72
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpsf_f64)(float64 a, float64 b, void *fpstp)
73
return float64_muladd(a, b, float64_two, 0, fpst);
74
}
75
76
-float16 HELPER(rsqrtsf_f16)(float16 a, float16 b, void *fpstp)
77
+uint32_t HELPER(rsqrtsf_f16)(uint32_t a, uint32_t b, void *fpstp)
78
{
79
float_status *fpst = fpstp;
80
81
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_addlp_u16)(uint64_t a)
82
}
83
84
/* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */
85
-float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
86
+uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
87
{
88
float_status *fpst = fpstp;
89
uint16_t val16, sbit;
90
@@ -XXX,XX +XXX,XX @@ void HELPER(casp_be_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
91
#define ADVSIMD_HELPER(name, suffix) HELPER(glue(glue(advsimd_, name), suffix))
92
93
#define ADVSIMD_HALFOP(name) \
94
-float16 ADVSIMD_HELPER(name, h)(float16 a, float16 b, void *fpstp) \
95
+uint32_t ADVSIMD_HELPER(name, h)(uint32_t a, uint32_t b, void *fpstp) \
96
{ \
97
float_status *fpst = fpstp; \
98
return float16_ ## name(a, b, fpst); \
99
@@ -XXX,XX +XXX,XX @@ ADVSIMD_HALFOP(mulx)
100
ADVSIMD_TWOHALFOP(mulx)
101
102
/* fused multiply-accumulate */
103
-float16 HELPER(advsimd_muladdh)(float16 a, float16 b, float16 c, void *fpstp)
104
+uint32_t HELPER(advsimd_muladdh)(uint32_t a, uint32_t b, uint32_t c,
105
+ void *fpstp)
106
{
107
float_status *fpst = fpstp;
108
return float16_muladd(a, b, c, 0, fpst);
109
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_muladd2h)(uint32_t two_a, uint32_t two_b,
110
111
#define ADVSIMD_CMPRES(test) (test) ? 0xffff : 0
112
113
-uint32_t HELPER(advsimd_ceq_f16)(float16 a, float16 b, void *fpstp)
114
+uint32_t HELPER(advsimd_ceq_f16)(uint32_t a, uint32_t b, void *fpstp)
115
{
116
float_status *fpst = fpstp;
117
int compare = float16_compare_quiet(a, b, fpst);
118
return ADVSIMD_CMPRES(compare == float_relation_equal);
119
}
120
121
-uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
122
+uint32_t HELPER(advsimd_cge_f16)(uint32_t a, uint32_t b, void *fpstp)
123
{
124
float_status *fpst = fpstp;
125
int compare = float16_compare(a, b, fpst);
126
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
127
compare == float_relation_equal);
128
}
129
130
-uint32_t HELPER(advsimd_cgt_f16)(float16 a, float16 b, void *fpstp)
131
+uint32_t HELPER(advsimd_cgt_f16)(uint32_t a, uint32_t b, void *fpstp)
132
{
133
float_status *fpst = fpstp;
134
int compare = float16_compare(a, b, fpst);
135
return ADVSIMD_CMPRES(compare == float_relation_greater);
136
}
137
138
-uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
139
+uint32_t HELPER(advsimd_acge_f16)(uint32_t a, uint32_t b, void *fpstp)
140
{
141
float_status *fpst = fpstp;
142
float16 f0 = float16_abs(a);
143
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
144
compare == float_relation_equal);
145
}
146
147
-uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
148
+uint32_t HELPER(advsimd_acgt_f16)(uint32_t a, uint32_t b, void *fpstp)
149
{
150
float_status *fpst = fpstp;
151
float16 f0 = float16_abs(a);
152
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
153
}
154
155
/* round to integral */
156
-float16 HELPER(advsimd_rinth_exact)(float16 x, void *fp_status)
157
+uint32_t HELPER(advsimd_rinth_exact)(uint32_t x, void *fp_status)
158
{
159
return float16_round_to_int(x, fp_status);
160
}
161
162
-float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
163
+uint32_t HELPER(advsimd_rinth)(uint32_t x, void *fp_status)
164
{
165
int old_flags = get_float_exception_flags(fp_status), new_flags;
166
float16 ret;
167
@@ -XXX,XX +XXX,XX @@ float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
168
* setting the mode appropriately before calling the helper.
169
*/
170
171
-uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
172
+uint32_t HELPER(advsimd_f16tosinth)(uint32_t a, void *fpstp)
173
{
174
float_status *fpst = fpstp;
175
176
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
177
return float16_to_int16(a, fpst);
178
}
179
180
-uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
181
+uint32_t HELPER(advsimd_f16touinth)(uint32_t a, void *fpstp)
182
{
183
float_status *fpst = fpstp;
184
185
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
186
* Square Root and Reciprocal square root
187
*/
188
189
-float16 HELPER(sqrt_f16)(float16 a, void *fpstp)
190
+uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp)
191
{
192
float_status *s = fpstp;
193
194
diff --git a/target/arm/helper.c b/target/arm/helper.c
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
195
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
196
--- a/target/arm/helper.c
65
--- a/target/arm/helper.c
197
+++ b/target/arm/helper.c
66
+++ b/target/arm/helper.c
198
@@ -XXX,XX +XXX,XX @@ DO_VFP_cmp(d, float64)
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
199
68
flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
200
/* Integer to float and float to integer conversions */
69
}
201
70
202
-#define CONV_ITOF(name, fsz, sign) \
71
- if (current_el == 0) {
203
- float##fsz HELPER(name)(uint32_t x, void *fpstp) \
72
- /* FIXME: ARMv8.1-VHE S2 translation regime. */
204
-{ \
73
- sctlr = env->cp15.sctlr_el[1];
205
- float_status *fpst = fpstp; \
74
- } else {
206
- return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
75
- sctlr = env->cp15.sctlr_el[current_el];
207
+#define CONV_ITOF(name, ftype, fsz, sign) \
76
- }
208
+ftype HELPER(name)(uint32_t x, void *fpstp) \
77
+ sctlr = arm_sctlr(env, current_el);
209
+{ \
78
+
210
+ float_status *fpst = fpstp; \
79
if (cpu_isar_feature(aa64_pauth, cpu)) {
211
+ return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
80
/*
212
}
81
* In order to save space in flags, we record only whether
213
214
-#define CONV_FTOI(name, fsz, sign, round) \
215
-uint32_t HELPER(name)(float##fsz x, void *fpstp) \
216
-{ \
217
- float_status *fpst = fpstp; \
218
- if (float##fsz##_is_any_nan(x)) { \
219
- float_raise(float_flag_invalid, fpst); \
220
- return 0; \
221
- } \
222
- return float##fsz##_to_##sign##int32##round(x, fpst); \
223
+#define CONV_FTOI(name, ftype, fsz, sign, round) \
224
+uint32_t HELPER(name)(ftype x, void *fpstp) \
225
+{ \
226
+ float_status *fpst = fpstp; \
227
+ if (float##fsz##_is_any_nan(x)) { \
228
+ float_raise(float_flag_invalid, fpst); \
229
+ return 0; \
230
+ } \
231
+ return float##fsz##_to_##sign##int32##round(x, fpst); \
232
}
233
234
-#define FLOAT_CONVS(name, p, fsz, sign) \
235
-CONV_ITOF(vfp_##name##to##p, fsz, sign) \
236
-CONV_FTOI(vfp_to##name##p, fsz, sign, ) \
237
-CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero)
238
+#define FLOAT_CONVS(name, p, ftype, fsz, sign) \
239
+ CONV_ITOF(vfp_##name##to##p, ftype, fsz, sign) \
240
+ CONV_FTOI(vfp_to##name##p, ftype, fsz, sign, ) \
241
+ CONV_FTOI(vfp_to##name##z##p, ftype, fsz, sign, _round_to_zero)
242
243
-FLOAT_CONVS(si, h, 16, )
244
-FLOAT_CONVS(si, s, 32, )
245
-FLOAT_CONVS(si, d, 64, )
246
-FLOAT_CONVS(ui, h, 16, u)
247
-FLOAT_CONVS(ui, s, 32, u)
248
-FLOAT_CONVS(ui, d, 64, u)
249
+FLOAT_CONVS(si, h, uint32_t, 16, )
250
+FLOAT_CONVS(si, s, float32, 32, )
251
+FLOAT_CONVS(si, d, float64, 64, )
252
+FLOAT_CONVS(ui, h, uint32_t, 16, u)
253
+FLOAT_CONVS(ui, s, float32, 32, u)
254
+FLOAT_CONVS(ui, d, float64, 64, u)
255
256
#undef CONV_ITOF
257
#undef CONV_FTOI
258
@@ -XXX,XX +XXX,XX @@ static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
259
return float64_to_float16(float64_scalbn(f, -shift, fpst), true, fpst);
260
}
261
262
-float16 HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
263
+uint32_t HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
264
{
265
return do_postscale_fp16(int32_to_float64(x, fpst), shift, fpst);
266
}
267
268
-float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
269
+uint32_t HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
270
{
271
return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
272
}
273
274
-float16 HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
275
+uint32_t HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
276
{
277
return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst);
278
}
279
280
-float16 HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
281
+uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
282
{
283
return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst);
284
}
285
@@ -XXX,XX +XXX,XX @@ static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
286
}
287
}
288
289
-uint32_t HELPER(vfp_toshh)(float16 x, uint32_t shift, void *fpst)
290
+uint32_t HELPER(vfp_toshh)(uint32_t x, uint32_t shift, void *fpst)
291
{
292
return float64_to_int16(do_prescale_fp16(x, shift, fpst), fpst);
293
}
294
295
-uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
296
+uint32_t HELPER(vfp_touhh)(uint32_t x, uint32_t shift, void *fpst)
297
{
298
return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
299
}
300
301
-uint32_t HELPER(vfp_toslh)(float16 x, uint32_t shift, void *fpst)
302
+uint32_t HELPER(vfp_toslh)(uint32_t x, uint32_t shift, void *fpst)
303
{
304
return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst);
305
}
306
307
-uint32_t HELPER(vfp_toulh)(float16 x, uint32_t shift, void *fpst)
308
+uint32_t HELPER(vfp_toulh)(uint32_t x, uint32_t shift, void *fpst)
309
{
310
return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst);
311
}
312
313
-uint64_t HELPER(vfp_tosqh)(float16 x, uint32_t shift, void *fpst)
314
+uint64_t HELPER(vfp_tosqh)(uint32_t x, uint32_t shift, void *fpst)
315
{
316
return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst);
317
}
318
319
-uint64_t HELPER(vfp_touqh)(float16 x, uint32_t shift, void *fpst)
320
+uint64_t HELPER(vfp_touqh)(uint32_t x, uint32_t shift, void *fpst)
321
{
322
return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst);
323
}
324
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(set_neon_rmode)(uint32_t rmode, CPUARMState *env)
325
}
326
327
/* Half precision conversions. */
328
-float32 HELPER(vfp_fcvt_f16_to_f32)(float16 a, void *fpstp, uint32_t ahp_mode)
329
+float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, void *fpstp, uint32_t ahp_mode)
330
{
331
/* Squash FZ16 to 0 for the duration of conversion. In this case,
332
* it would affect flushing input denormals.
333
@@ -XXX,XX +XXX,XX @@ float32 HELPER(vfp_fcvt_f16_to_f32)(float16 a, void *fpstp, uint32_t ahp_mode)
334
return r;
335
}
336
337
-float16 HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
338
+uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
339
{
340
/* Squash FZ16 to 0 for the duration of conversion. In this case,
341
* it would affect flushing output denormals.
342
@@ -XXX,XX +XXX,XX @@ float16 HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
343
return r;
344
}
345
346
-float64 HELPER(vfp_fcvt_f16_to_f64)(float16 a, void *fpstp, uint32_t ahp_mode)
347
+float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, void *fpstp, uint32_t ahp_mode)
348
{
349
/* Squash FZ16 to 0 for the duration of conversion. In this case,
350
* it would affect flushing input denormals.
351
@@ -XXX,XX +XXX,XX @@ float64 HELPER(vfp_fcvt_f16_to_f64)(float16 a, void *fpstp, uint32_t ahp_mode)
352
return r;
353
}
354
355
-float16 HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
356
+uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
357
{
358
/* Squash FZ16 to 0 for the duration of conversion. In this case,
359
* it would affect flushing output denormals.
360
@@ -XXX,XX +XXX,XX @@ static bool round_to_inf(float_status *fpst, bool sign_bit)
361
g_assert_not_reached();
362
}
363
364
-float16 HELPER(recpe_f16)(float16 input, void *fpstp)
365
+uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
366
{
367
float_status *fpst = fpstp;
368
float16 f16 = float16_squash_input_denormal(input, fpst);
369
@@ -XXX,XX +XXX,XX @@ static uint64_t recip_sqrt_estimate(int *exp , int exp_off, uint64_t frac)
370
return extract64(estimate, 0, 8) << 44;
371
}
372
373
-float16 HELPER(rsqrte_f16)(float16 input, void *fpstp)
374
+uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
375
{
376
float_status *s = fpstp;
377
float16 f16 = float16_squash_input_denormal(input, s);
378
--
82
--
379
2.17.1
83
2.20.1
380
84
381
85
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Coverity found that the string return by 'object_get_canonical_path' was not
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
being freed at two locations in the model (CID 1391294 and CID 1391293) and
4
Message-id: 20190301200501.16533-3-richard.henderson@linaro.org
5
also that a memset was being called with a value greater than the max of a byte
6
on the second argument (CID 1391286). This patch corrects this by adding the
7
freeing of the strings and also changing to memset to zero instead on
8
descriptor unaligned errors.
9
10
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180528184859.3530-1-frasse.iglesias@gmail.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
7
---
17
hw/dma/xlnx-zdma.c | 10 +++++++---
8
target/arm/cpu.h | 10 ++++++++++
18
1 file changed, 7 insertions(+), 3 deletions(-)
9
linux-user/elfload.c | 1 +
10
target/arm/cpu.c | 1 +
11
target/arm/cpu64.c | 2 ++
12
target/arm/translate-a64.c | 14 ++++++++++++++
13
target/arm/translate.c | 22 ++++++++++++++++++++++
14
6 files changed, 50 insertions(+)
19
15
20
diff --git a/hw/dma/xlnx-zdma.c b/hw/dma/xlnx-zdma.c
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/dma/xlnx-zdma.c
18
--- a/target/arm/cpu.h
23
+++ b/hw/dma/xlnx-zdma.c
19
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ static bool zdma_load_descriptor(XlnxZDMA *s, uint64_t addr, void *buf)
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id)
25
qemu_log_mask(LOG_GUEST_ERROR,
21
return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0;
26
"zdma: unaligned descriptor at %" PRIx64,
22
}
27
addr);
23
28
- memset(buf, 0xdeadbeef, sizeof(XlnxZDMADescr));
24
+static inline bool isar_feature_aa32_sb(const ARMISARegisters *id)
29
+ memset(buf, 0x0, sizeof(XlnxZDMADescr));
25
+{
30
s->error = true;
26
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0;
31
return false;
27
+}
28
+
29
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
30
{
31
/*
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
33
FIELD_DP64(0, ID_AA64ISAR1, GPI, 0xf))) != 0;
34
}
35
36
+static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
37
+{
38
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
39
+}
40
+
41
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
42
{
43
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
44
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/linux-user/elfload.c
47
+++ b/linux-user/elfload.c
48
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
49
GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
50
GET_FEATURE_ID(aa64_fhm, ARM_HWCAP_A64_ASIMDFHM);
51
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
52
+ GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
53
54
#undef GET_FEATURE_ID
55
56
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/cpu.c
59
+++ b/target/arm/cpu.c
60
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
61
t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
62
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
63
t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
64
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
65
cpu->isar.id_isar6 = t;
66
67
t = cpu->id_mmfr4;
68
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/cpu64.c
71
+++ b/target/arm/cpu64.c
72
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
73
t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
74
t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
75
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
76
+ t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
77
cpu->isar.id_aa64isar1 = t;
78
79
t = cpu->isar.id_aa64pfr0;
80
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
81
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 1);
82
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
83
u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
84
+ u = FIELD_DP32(u, ID_ISAR6, SB, 1);
85
cpu->isar.id_isar6 = u;
86
87
/*
88
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/translate-a64.c
91
+++ b/target/arm/translate-a64.c
92
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
93
reset_btype(s);
94
gen_goto_tb(s, 0, s->pc);
95
return;
96
+
97
+ case 7: /* SB */
98
+ if (crm != 0 || !dc_isar_feature(aa64_sb, s)) {
99
+ goto do_unallocated;
100
+ }
101
+ /*
102
+ * TODO: There is no speculation barrier opcode for TCG;
103
+ * MB and end the TB instead.
104
+ */
105
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
106
+ gen_goto_tb(s, 0, s->pc);
107
+ return;
108
+
109
default:
110
+ do_unallocated:
111
unallocated_encoding(s);
112
return;
32
}
113
}
33
@@ -XXX,XX +XXX,XX @@ static uint64_t zdma_read(void *opaque, hwaddr addr, unsigned size)
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
34
RegisterInfo *r = &s->regs_info[addr / 4];
115
index XXXXXXX..XXXXXXX 100644
35
116
--- a/target/arm/translate.c
36
if (!r->data) {
117
+++ b/target/arm/translate.c
37
+ gchar *path = object_get_canonical_path(OBJECT(s));
118
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
38
qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
119
*/
39
- object_get_canonical_path(OBJECT(s)),
120
gen_goto_tb(s, 0, s->pc & ~1);
40
+ path,
121
return;
41
addr);
122
+ case 7: /* sb */
42
+ g_free(path);
123
+ if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
43
ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
124
+ goto illegal_op;
44
zdma_ch_imr_update_irq(s);
125
+ }
45
return 0;
126
+ /*
46
@@ -XXX,XX +XXX,XX @@ static void zdma_write(void *opaque, hwaddr addr, uint64_t value,
127
+ * TODO: There is no speculation barrier opcode
47
RegisterInfo *r = &s->regs_info[addr / 4];
128
+ * for TCG; MB and end the TB instead.
48
129
+ */
49
if (!r->data) {
130
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
50
+ gchar *path = object_get_canonical_path(OBJECT(s));
131
+ gen_goto_tb(s, 0, s->pc & ~1);
51
qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
132
+ return;
52
- object_get_canonical_path(OBJECT(s)),
133
default:
53
+ path,
134
goto illegal_op;
54
addr, value);
135
}
55
+ g_free(path);
136
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
56
ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
137
*/
57
zdma_ch_imr_update_irq(s);
138
gen_goto_tb(s, 0, s->pc & ~1);
58
return;
139
break;
140
+ case 7: /* sb */
141
+ if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
142
+ goto illegal_op;
143
+ }
144
+ /*
145
+ * TODO: There is no speculation barrier opcode
146
+ * for TCG; MB and end the TB instead.
147
+ */
148
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
149
+ gen_goto_tb(s, 0, s->pc & ~1);
150
+ break;
151
default:
152
goto illegal_op;
153
}
59
--
154
--
60
2.17.1
155
2.20.1
61
156
62
157
diff view generated by jsdifflib
1
In commit f0aff255700 we made cpacr_write() enforce that some CPACR
1
From: Richard Henderson <richard.henderson@linaro.org>
2
bits are RAZ/WI and some are RAO/WI for ARMv7 cores. Unfortunately
3
we forgot to also update the register's reset value. The effect
4
was that (a) a guest that read CPACR on reset would not see ones in
5
the RAO bits, and (b) if you did a migration before the guest did
6
a write to the CPACR then the migration would fail because the
7
destination would enforce the RAO bits and then complain that they
8
didn't match the zero value from the source.
9
2
10
Implement reset for the CPACR using a custom reset function
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
that just calls cpacr_write(), to avoid having to duplicate
4
Message-id: 20190301200501.16533-4-richard.henderson@linaro.org
12
the logic for which bits are RAO.
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/cpu.h | 13 ++++++++++-
9
target/arm/cpu.c | 1 +
10
target/arm/cpu64.c | 2 ++
11
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++++++++
12
4 files changed, 70 insertions(+), 1 deletion(-)
13
13
14
This bug would affect migration for TCG CPUs which are ARMv7
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
with VFP but without one of Neon or VFPv3.
15
index XXXXXXX..XXXXXXX 100644
16
16
--- a/target/arm/cpu.h
17
Reported-by: Cédric Le Goater <clg@kaod.org>
17
+++ b/target/arm/cpu.h
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
19
Tested-by: Cédric Le Goater <clg@kaod.org>
19
#define SCTLR_R (1U << 9) /* up to v6; RAZ in v7 */
20
Message-id: 20180522173713.26282-1-peter.maydell@linaro.org
20
#define SCTLR_UMA (1U << 9) /* v8 onward, AArch64 only */
21
---
21
#define SCTLR_F (1U << 10) /* up to v6 */
22
target/arm/helper.c | 10 +++++++++-
22
-#define SCTLR_SW (1U << 10) /* v7, RES0 in v8 */
23
1 file changed, 9 insertions(+), 1 deletion(-)
23
+#define SCTLR_SW (1U << 10) /* v7 */
24
24
+#define SCTLR_EnRCTX (1U << 10) /* in v8.0-PredInv */
25
#define SCTLR_Z (1U << 11) /* in v7, RES1 in v8 */
26
#define SCTLR_EOS (1U << 11) /* v8.5-ExS */
27
#define SCTLR_I (1U << 12)
28
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_sb(const ARMISARegisters *id)
29
return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0;
30
}
31
32
+static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
33
+{
34
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
35
+}
36
+
37
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
38
{
39
/*
40
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
41
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
42
}
43
44
+static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id)
45
+{
46
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0;
47
+}
48
+
49
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
50
{
51
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
52
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/cpu.c
55
+++ b/target/arm/cpu.c
56
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
57
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
58
t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
59
t = FIELD_DP32(t, ID_ISAR6, SB, 1);
60
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
61
cpu->isar.id_isar6 = t;
62
63
t = cpu->id_mmfr4;
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
67
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
69
t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
70
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
71
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
72
+ t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
73
cpu->isar.id_aa64isar1 = t;
74
75
t = cpu->isar.id_aa64pfr0;
76
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
77
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
78
u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
79
u = FIELD_DP32(u, ID_ISAR6, SB, 1);
80
+ u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
81
cpu->isar.id_isar6 = u;
82
83
/*
25
diff --git a/target/arm/helper.c b/target/arm/helper.c
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
index XXXXXXX..XXXXXXX 100644
85
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/helper.c
86
--- a/target/arm/helper.c
28
+++ b/target/arm/helper.c
87
+++ b/target/arm/helper.c
29
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
88
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pauth_reginfo[] = {
30
env->cp15.cpacr_el1 = value;
89
};
31
}
90
#endif
32
91
33
+static void cpacr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
92
+static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
93
+ bool isread)
34
+{
94
+{
35
+ /* Call cpacr_write() so that we reset with the correct RAO bits set
95
+ int el = arm_current_el(env);
36
+ * for our CPU features.
96
+
37
+ */
97
+ if (el == 0) {
38
+ cpacr_write(env, ri, 0);
98
+ uint64_t sctlr = arm_sctlr(env, el);
99
+ if (!(sctlr & SCTLR_EnRCTX)) {
100
+ return CP_ACCESS_TRAP;
101
+ }
102
+ } else if (el == 1) {
103
+ uint64_t hcr = arm_hcr_el2_eff(env);
104
+ if (hcr & HCR_NV) {
105
+ return CP_ACCESS_TRAP_EL2;
106
+ }
107
+ }
108
+ return CP_ACCESS_OK;
39
+}
109
+}
40
+
110
+
41
static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
111
+static const ARMCPRegInfo predinv_reginfo[] = {
42
bool isread)
112
+ { .name = "CFP_RCTX", .state = ARM_CP_STATE_AA64,
113
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 4,
114
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
115
+ { .name = "DVP_RCTX", .state = ARM_CP_STATE_AA64,
116
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 5,
117
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
118
+ { .name = "CPP_RCTX", .state = ARM_CP_STATE_AA64,
119
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 7,
120
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
121
+ /*
122
+ * Note the AArch32 opcodes have a different OPC1.
123
+ */
124
+ { .name = "CFPRCTX", .state = ARM_CP_STATE_AA32,
125
+ .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 4,
126
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
127
+ { .name = "DVPRCTX", .state = ARM_CP_STATE_AA32,
128
+ .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 5,
129
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
130
+ { .name = "CPPRCTX", .state = ARM_CP_STATE_AA32,
131
+ .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 7,
132
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
133
+ REGINFO_SENTINEL
134
+};
135
+
136
void register_cp_regs_for_features(ARMCPU *cpu)
43
{
137
{
44
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
138
/* Register all the coprocessor registers based on feature bits */
45
{ .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3,
139
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
46
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
140
define_arm_cp_regs(cpu, pauth_reginfo);
47
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
141
}
48
- .resetvalue = 0, .writefn = cpacr_write },
142
#endif
49
+ .resetfn = cpacr_reset, .writefn = cpacr_write },
143
+
50
REGINFO_SENTINEL
144
+ /*
51
};
145
+ * While all v8.0 cpus support aarch64, QEMU does have configurations
52
146
+ * that do not set ID_AA64ISAR1, e.g. user-only qemu-arm -cpu max,
147
+ * which will set ID_ISAR6.
148
+ */
149
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
150
+ ? cpu_isar_feature(aa64_predinv, cpu)
151
+ : cpu_isar_feature(aa32_predinv, cpu)) {
152
+ define_arm_cp_regs(cpu, predinv_reginfo);
153
+ }
154
}
155
156
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
53
--
157
--
54
2.17.1
158
2.20.1
55
159
56
160
diff view generated by jsdifflib
1
The FRECPX instructions should (like most other floating point operations)
1
From: Richard Henderson <richard.henderson@linaro.org>
2
honour the FPCR.FZ bit which specifies whether input denormals should
2
3
be flushed to zero (or FZ16 for the half-precision version).
3
The EL0+UMA check is unique to DAIF. While SPSel had avoided the
4
We forgot to implement this, which doesn't affect the results (since
4
check by nature of already checking EL >= 1, the other post v8.0
5
the calculation doesn't actually care about the mantissa bits) but did
5
extensions to MSR (imm) allow EL0 and do not require UMA. Avoid
6
mean we were failing to set the FPSR.IDC bit.
6
the unconditional write to pc and use raise_exception_ra to unwind.
7
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190301200501.16533-5-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180521172712.19930-1-peter.maydell@linaro.org
11
---
12
---
12
target/arm/helper-a64.c | 6 ++++++
13
target/arm/helper-a64.h | 3 +++
13
1 file changed, 6 insertions(+)
14
target/arm/helper.h | 1 -
14
15
target/arm/internals.h | 15 ++++++++++++++
16
target/arm/helper-a64.c | 30 +++++++++++++++++++++++++++
17
target/arm/op_helper.c | 42 --------------------------------------
18
target/arm/translate-a64.c | 41 ++++++++++++++++++++++---------------
19
6 files changed, 73 insertions(+), 59 deletions(-)
20
21
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper-a64.h
24
+++ b/target/arm/helper-a64.h
25
@@ -XXX,XX +XXX,XX @@
26
DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
27
DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
28
DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
29
+DEF_HELPER_2(msr_i_spsel, void, env, i32)
30
+DEF_HELPER_2(msr_i_daifset, void, env, i32)
31
+DEF_HELPER_2(msr_i_daifclear, void, env, i32)
32
DEF_HELPER_3(vfp_cmph_a64, i64, f16, f16, ptr)
33
DEF_HELPER_3(vfp_cmpeh_a64, i64, f16, f16, ptr)
34
DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
35
diff --git a/target/arm/helper.h b/target/arm/helper.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.h
38
+++ b/target/arm/helper.h
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_cp_reg, i32, env, ptr)
40
DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
41
DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
42
43
-DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
44
DEF_HELPER_1(clear_pstate_ss, void, env)
45
46
DEF_HELPER_2(get_r13_banked, i32, env, i32)
47
diff --git a/target/arm/internals.h b/target/arm/internals.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/internals.h
50
+++ b/target/arm/internals.h
51
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
52
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
53
ARMMMUIdx mmu_idx, bool data);
54
55
+static inline int exception_target_el(CPUARMState *env)
56
+{
57
+ int target_el = MAX(1, arm_current_el(env));
58
+
59
+ /*
60
+ * No such thing as secure EL1 if EL3 is aarch32,
61
+ * so update the target EL to EL3 in this case.
62
+ */
63
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3) && target_el == 1) {
64
+ target_el = 3;
65
+ }
66
+
67
+ return target_el;
68
+}
69
+
70
#endif
15
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
71
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
16
index XXXXXXX..XXXXXXX 100644
72
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-a64.c
73
--- a/target/arm/helper-a64.c
18
+++ b/target/arm/helper-a64.c
74
+++ b/target/arm/helper-a64.c
19
@@ -XXX,XX +XXX,XX @@ float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
75
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(rbit64)(uint64_t x)
20
return nan;
76
return revbit64(x);
77
}
78
79
+void HELPER(msr_i_spsel)(CPUARMState *env, uint32_t imm)
80
+{
81
+ update_spsel(env, imm);
82
+}
83
+
84
+static void daif_check(CPUARMState *env, uint32_t op,
85
+ uint32_t imm, uintptr_t ra)
86
+{
87
+ /* DAIF update to PSTATE. This is OK from EL0 only if UMA is set. */
88
+ if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
89
+ raise_exception_ra(env, EXCP_UDEF,
90
+ syn_aa64_sysregtrap(0, extract32(op, 0, 3),
91
+ extract32(op, 3, 3), 4,
92
+ imm, 0x1f, 0),
93
+ exception_target_el(env), ra);
94
+ }
95
+}
96
+
97
+void HELPER(msr_i_daifset)(CPUARMState *env, uint32_t imm)
98
+{
99
+ daif_check(env, 0x1e, imm, GETPC());
100
+ env->daif |= (imm << 6) & PSTATE_DAIF;
101
+}
102
+
103
+void HELPER(msr_i_daifclear)(CPUARMState *env, uint32_t imm)
104
+{
105
+ daif_check(env, 0x1f, imm, GETPC());
106
+ env->daif &= ~((imm << 6) & PSTATE_DAIF);
107
+}
108
+
109
/* Convert a softfloat float_relation_ (as returned by
110
* the float*_compare functions) to the correct ARM
111
* NZCV flag state.
112
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/op_helper.c
115
+++ b/target/arm/op_helper.c
116
@@ -XXX,XX +XXX,XX @@ void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
117
cpu_loop_exit_restore(cs, ra);
118
}
119
120
-static int exception_target_el(CPUARMState *env)
121
-{
122
- int target_el = MAX(1, arm_current_el(env));
123
-
124
- /* No such thing as secure EL1 if EL3 is aarch32, so update the target EL
125
- * to EL3 in this case.
126
- */
127
- if (arm_is_secure(env) && !arm_el_is_aa64(env, 3) && target_el == 1) {
128
- target_el = 3;
129
- }
130
-
131
- return target_el;
132
-}
133
-
134
uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, void *vn,
135
uint32_t maxindex)
136
{
137
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
138
return res;
139
}
140
141
-void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
142
-{
143
- /* MSR_i to update PSTATE. This is OK from EL0 only if UMA is set.
144
- * Note that SPSel is never OK from EL0; we rely on handle_msr_i()
145
- * to catch that case at translate time.
146
- */
147
- if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
148
- uint32_t syndrome = syn_aa64_sysregtrap(0, extract32(op, 0, 3),
149
- extract32(op, 3, 3), 4,
150
- imm, 0x1f, 0);
151
- raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
152
- }
153
-
154
- switch (op) {
155
- case 0x05: /* SPSel */
156
- update_spsel(env, imm);
157
- break;
158
- case 0x1e: /* DAIFSet */
159
- env->daif |= (imm << 6) & PSTATE_DAIF;
160
- break;
161
- case 0x1f: /* DAIFClear */
162
- env->daif &= ~((imm << 6) & PSTATE_DAIF);
163
- break;
164
- default:
165
- g_assert_not_reached();
166
- }
167
-}
168
-
169
void HELPER(clear_pstate_ss)(CPUARMState *env)
170
{
171
env->pstate &= ~PSTATE_SS;
172
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/target/arm/translate-a64.c
175
+++ b/target/arm/translate-a64.c
176
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
177
static void handle_msr_i(DisasContext *s, uint32_t insn,
178
unsigned int op1, unsigned int op2, unsigned int crm)
179
{
180
+ TCGv_i32 t1;
181
int op = op1 << 3 | op2;
182
+
183
+ /* End the TB by default, chaining is ok. */
184
+ s->base.is_jmp = DISAS_TOO_MANY;
185
+
186
switch (op) {
187
case 0x05: /* SPSel */
188
if (s->current_el == 0) {
189
- unallocated_encoding(s);
190
- return;
191
+ goto do_unallocated;
192
}
193
- /* fall through */
194
- case 0x1e: /* DAIFSet */
195
- case 0x1f: /* DAIFClear */
196
- {
197
- TCGv_i32 tcg_imm = tcg_const_i32(crm);
198
- TCGv_i32 tcg_op = tcg_const_i32(op);
199
- gen_a64_set_pc_im(s->pc - 4);
200
- gen_helper_msr_i_pstate(cpu_env, tcg_op, tcg_imm);
201
- tcg_temp_free_i32(tcg_imm);
202
- tcg_temp_free_i32(tcg_op);
203
- /* For DAIFClear, exit the cpu loop to re-evaluate pending IRQs. */
204
- gen_a64_set_pc_im(s->pc);
205
- s->base.is_jmp = (op == 0x1f ? DISAS_EXIT : DISAS_JUMP);
206
+ t1 = tcg_const_i32(crm & PSTATE_SP);
207
+ gen_helper_msr_i_spsel(cpu_env, t1);
208
+ tcg_temp_free_i32(t1);
209
break;
210
- }
211
+
212
+ case 0x1e: /* DAIFSet */
213
+ t1 = tcg_const_i32(crm);
214
+ gen_helper_msr_i_daifset(cpu_env, t1);
215
+ tcg_temp_free_i32(t1);
216
+ break;
217
+
218
+ case 0x1f: /* DAIFClear */
219
+ t1 = tcg_const_i32(crm);
220
+ gen_helper_msr_i_daifclear(cpu_env, t1);
221
+ tcg_temp_free_i32(t1);
222
+ /* For DAIFClear, exit the cpu loop to re-evaluate pending IRQs. */
223
+ s->base.is_jmp = DISAS_UPDATE;
224
+ break;
225
+
226
default:
227
+ do_unallocated:
228
unallocated_encoding(s);
229
return;
21
}
230
}
22
23
+ a = float16_squash_input_denormal(a, fpst);
24
+
25
val16 = float16_val(a);
26
sbit = 0x8000 & val16;
27
exp = extract32(val16, 10, 5);
28
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
29
return nan;
30
}
31
32
+ a = float32_squash_input_denormal(a, fpst);
33
+
34
val32 = float32_val(a);
35
sbit = 0x80000000ULL & val32;
36
exp = extract32(val32, 23, 8);
37
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
38
return nan;
39
}
40
41
+ a = float64_squash_input_denormal(a, fpst);
42
+
43
val64 = float64_val(a);
44
sbit = 0x8000000000000000ULL & val64;
45
exp = extract64(float64_val(a), 52, 11);
46
--
231
--
47
2.17.1
232
2.20.1
48
233
49
234
diff view generated by jsdifflib
Deleted patch
1
Add entries to MAINTAINERS to cover the newer MPS2 boards and
2
the new devices they use.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180518153157.14899-1-peter.maydell@linaro.org
6
---
7
MAINTAINERS | 9 +++++++--
8
1 file changed, 7 insertions(+), 2 deletions(-)
9
10
diff --git a/MAINTAINERS b/MAINTAINERS
11
index XXXXXXX..XXXXXXX 100644
12
--- a/MAINTAINERS
13
+++ b/MAINTAINERS
14
@@ -XXX,XX +XXX,XX @@ F: hw/timer/cmsdk-apb-timer.c
15
F: include/hw/timer/cmsdk-apb-timer.h
16
F: hw/char/cmsdk-apb-uart.c
17
F: include/hw/char/cmsdk-apb-uart.h
18
+F: hw/misc/tz-ppc.c
19
+F: include/hw/misc/tz-ppc.h
20
21
ARM cores
22
M: Peter Maydell <peter.maydell@linaro.org>
23
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
24
L: qemu-arm@nongnu.org
25
S: Maintained
26
F: hw/arm/mps2.c
27
-F: hw/misc/mps2-scc.c
28
-F: include/hw/misc/mps2-scc.h
29
+F: hw/arm/mps2-tz.c
30
+F: hw/misc/mps2-*.c
31
+F: include/hw/misc/mps2-*.h
32
+F: hw/arm/iotkit.c
33
+F: include/hw/arm/iotkit.h
34
35
Musicpal
36
M: Jan Kiszka <jan.kiszka@web.de>
37
--
38
2.17.1
39
40
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
add MemTxAttrs as an argument to the MemoryRegion valid.accepts
3
callback. We'll need this for subpage_accepts().
4
2
5
We could take the approach we used with the read and write
3
We do not need an out-of-line helper for manipulating bits in pstate.
6
callbacks and add new a new _with_attrs version, but since there
4
While changing things, share the implementation of gen_ss_advance.
7
are so few implementations of the accepts hook we just change
8
them all.
9
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190301200501.16533-6-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20180521140402.23318-9-peter.maydell@linaro.org
14
---
10
---
15
include/exec/memory.h | 3 ++-
11
target/arm/helper.h | 2 --
16
exec.c | 9 ++++++---
12
target/arm/translate.h | 34 ++++++++++++++++++++++++++++++++++
17
hw/hppa/dino.c | 3 ++-
13
target/arm/op_helper.c | 5 -----
18
hw/nvram/fw_cfg.c | 12 ++++++++----
14
target/arm/translate-a64.c | 11 -----------
19
hw/scsi/esp.c | 3 ++-
15
target/arm/translate.c | 11 -----------
20
hw/xen/xen_pt_msi.c | 3 ++-
16
5 files changed, 34 insertions(+), 29 deletions(-)
21
memory.c | 5 +++--
22
7 files changed, 25 insertions(+), 13 deletions(-)
23
17
24
diff --git a/include/exec/memory.h b/include/exec/memory.h
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
25
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
26
--- a/include/exec/memory.h
20
--- a/target/arm/helper.h
27
+++ b/include/exec/memory.h
21
+++ b/target/arm/helper.h
28
@@ -XXX,XX +XXX,XX @@ struct MemoryRegionOps {
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_cp_reg, i32, env, ptr)
29
* as a machine check exception).
23
DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
30
*/
24
DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
31
bool (*accepts)(void *opaque, hwaddr addr,
25
32
- unsigned size, bool is_write);
26
-DEF_HELPER_1(clear_pstate_ss, void, env)
33
+ unsigned size, bool is_write,
27
-
34
+ MemTxAttrs attrs);
28
DEF_HELPER_2(get_r13_banked, i32, env, i32)
35
} valid;
29
DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
36
/* Internal implementation constraints: */
30
37
struct {
31
diff --git a/target/arm/translate.h b/target/arm/translate.h
38
diff --git a/exec.c b/exec.c
39
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
40
--- a/exec.c
33
--- a/target/arm/translate.h
41
+++ b/exec.c
34
+++ b/target/arm/translate.h
42
@@ -XXX,XX +XXX,XX @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
35
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 get_ahp_flag(void)
36
return ret;
43
}
37
}
44
38
45
static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
39
+/* Set bits within PSTATE. */
46
- unsigned size, bool is_write)
40
+static inline void set_pstate_bits(uint32_t bits)
47
+ unsigned size, bool is_write,
41
+{
48
+ MemTxAttrs attrs)
42
+ TCGv_i32 p = tcg_temp_new_i32();
43
+
44
+ tcg_debug_assert(!(bits & CACHED_PSTATE_BITS));
45
+
46
+ tcg_gen_ld_i32(p, cpu_env, offsetof(CPUARMState, pstate));
47
+ tcg_gen_ori_i32(p, p, bits);
48
+ tcg_gen_st_i32(p, cpu_env, offsetof(CPUARMState, pstate));
49
+ tcg_temp_free_i32(p);
50
+}
51
+
52
+/* Clear bits within PSTATE. */
53
+static inline void clear_pstate_bits(uint32_t bits)
54
+{
55
+ TCGv_i32 p = tcg_temp_new_i32();
56
+
57
+ tcg_debug_assert(!(bits & CACHED_PSTATE_BITS));
58
+
59
+ tcg_gen_ld_i32(p, cpu_env, offsetof(CPUARMState, pstate));
60
+ tcg_gen_andi_i32(p, p, ~bits);
61
+ tcg_gen_st_i32(p, cpu_env, offsetof(CPUARMState, pstate));
62
+ tcg_temp_free_i32(p);
63
+}
64
+
65
+/* If the singlestep state is Active-not-pending, advance to Active-pending. */
66
+static inline void gen_ss_advance(DisasContext *s)
67
+{
68
+ if (s->ss_active) {
69
+ s->pstate_ss = 0;
70
+ clear_pstate_bits(PSTATE_SS);
71
+ }
72
+}
73
74
/* Vector operations shared between ARM and AArch64. */
75
extern const GVecGen3 bsl_op;
76
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/op_helper.c
79
+++ b/target/arm/op_helper.c
80
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
81
return res;
82
}
83
84
-void HELPER(clear_pstate_ss)(CPUARMState *env)
85
-{
86
- env->pstate &= ~PSTATE_SS;
87
-}
88
-
89
void HELPER(pre_hvc)(CPUARMState *env)
49
{
90
{
50
return is_write;
91
ARMCPU *cpu = arm_env_get_cpu(env);
92
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/target/arm/translate-a64.c
95
+++ b/target/arm/translate-a64.c
96
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset,
97
s->base.is_jmp = DISAS_NORETURN;
51
}
98
}
52
@@ -XXX,XX +XXX,XX @@ static MemTxResult subpage_write(void *opaque, hwaddr addr,
99
100
-static void gen_ss_advance(DisasContext *s)
101
-{
102
- /* If the singlestep state is Active-not-pending, advance to
103
- * Active-pending.
104
- */
105
- if (s->ss_active) {
106
- s->pstate_ss = 0;
107
- gen_helper_clear_pstate_ss(cpu_env);
108
- }
109
-}
110
-
111
static void gen_step_complete_exception(DisasContext *s)
112
{
113
/* We just completed step of an insn. Move from Active-not-pending
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate.c
117
+++ b/target/arm/translate.c
118
@@ -XXX,XX +XXX,XX @@ static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
119
tcg_temp_free_i32(tcg_excp);
53
}
120
}
54
121
55
static bool subpage_accepts(void *opaque, hwaddr addr,
122
-static void gen_ss_advance(DisasContext *s)
56
- unsigned len, bool is_write)
123
-{
57
+ unsigned len, bool is_write,
124
- /* If the singlestep state is Active-not-pending, advance to
58
+ MemTxAttrs attrs)
125
- * Active-pending.
126
- */
127
- if (s->ss_active) {
128
- s->pstate_ss = 0;
129
- gen_helper_clear_pstate_ss(cpu_env);
130
- }
131
-}
132
-
133
static void gen_step_complete_exception(DisasContext *s)
59
{
134
{
60
subpage_t *subpage = opaque;
135
/* We just completed step of an insn. Move from Active-not-pending
61
#if defined(DEBUG_SUBPAGE)
62
@@ -XXX,XX +XXX,XX @@ static void readonly_mem_write(void *opaque, hwaddr addr,
63
}
64
65
static bool readonly_mem_accepts(void *opaque, hwaddr addr,
66
- unsigned size, bool is_write)
67
+ unsigned size, bool is_write,
68
+ MemTxAttrs attrs)
69
{
70
return is_write;
71
}
72
diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/hppa/dino.c
75
+++ b/hw/hppa/dino.c
76
@@ -XXX,XX +XXX,XX @@ static void gsc_to_pci_forwarding(DinoState *s)
77
}
78
79
static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
80
- unsigned size, bool is_write)
81
+ unsigned size, bool is_write,
82
+ MemTxAttrs attrs)
83
{
84
switch (addr) {
85
case DINO_IAR0:
86
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/nvram/fw_cfg.c
89
+++ b/hw/nvram/fw_cfg.c
90
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_dma_mem_write(void *opaque, hwaddr addr,
91
}
92
93
static bool fw_cfg_dma_mem_valid(void *opaque, hwaddr addr,
94
- unsigned size, bool is_write)
95
+ unsigned size, bool is_write,
96
+ MemTxAttrs attrs)
97
{
98
return !is_write || ((size == 4 && (addr == 0 || addr == 4)) ||
99
(size == 8 && addr == 0));
100
}
101
102
static bool fw_cfg_data_mem_valid(void *opaque, hwaddr addr,
103
- unsigned size, bool is_write)
104
+ unsigned size, bool is_write,
105
+ MemTxAttrs attrs)
106
{
107
return addr == 0;
108
}
109
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_ctl_mem_write(void *opaque, hwaddr addr,
110
}
111
112
static bool fw_cfg_ctl_mem_valid(void *opaque, hwaddr addr,
113
- unsigned size, bool is_write)
114
+ unsigned size, bool is_write,
115
+ MemTxAttrs attrs)
116
{
117
return is_write && size == 2;
118
}
119
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_comb_write(void *opaque, hwaddr addr,
120
}
121
122
static bool fw_cfg_comb_valid(void *opaque, hwaddr addr,
123
- unsigned size, bool is_write)
124
+ unsigned size, bool is_write,
125
+ MemTxAttrs attrs)
126
{
127
return (size == 1) || (is_write && size == 2);
128
}
129
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/scsi/esp.c
132
+++ b/hw/scsi/esp.c
133
@@ -XXX,XX +XXX,XX @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
134
}
135
136
static bool esp_mem_accepts(void *opaque, hwaddr addr,
137
- unsigned size, bool is_write)
138
+ unsigned size, bool is_write,
139
+ MemTxAttrs attrs)
140
{
141
return (size == 1) || (is_write && size == 4);
142
}
143
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/hw/xen/xen_pt_msi.c
146
+++ b/hw/xen/xen_pt_msi.c
147
@@ -XXX,XX +XXX,XX @@ static uint64_t pci_msix_read(void *opaque, hwaddr addr,
148
}
149
150
static bool pci_msix_accepts(void *opaque, hwaddr addr,
151
- unsigned size, bool is_write)
152
+ unsigned size, bool is_write,
153
+ MemTxAttrs attrs)
154
{
155
return !(addr & (size - 1));
156
}
157
diff --git a/memory.c b/memory.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/memory.c
160
+++ b/memory.c
161
@@ -XXX,XX +XXX,XX @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
162
}
163
164
static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
165
- unsigned size, bool is_write)
166
+ unsigned size, bool is_write,
167
+ MemTxAttrs attrs)
168
{
169
return false;
170
}
171
@@ -XXX,XX +XXX,XX @@ bool memory_region_access_valid(MemoryRegion *mr,
172
access_size = MAX(MIN(size, access_size_max), access_size_min);
173
for (i = 0; i < size; i += access_size) {
174
if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size,
175
- is_write)) {
176
+ is_write, attrs)) {
177
return false;
178
}
179
}
180
--
136
--
181
2.17.1
137
2.20.1
182
138
183
139
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
add MemTxAttrs as an argument to memory_region_access_valid().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
2
6
The callsite in flatview_access_valid() is part of a recursive
3
This decoding more closely matches the ARMv8.4 Table C4-6,
7
loop flatview_access_valid() -> memory_region_access_valid() ->
4
Encoding table for Data Processing - Register Group.
8
subpage_accepts() -> flatview_access_valid(); we make it pass
9
MEMTXATTRS_UNSPECIFIED for now, until the next several commits
10
have plumbed an attrs parameter through the rest of the loop
11
and we can add an attrs parameter to flatview_access_valid().
12
5
6
In particular, op2 == 0 is now more than just Add/sub (with carry).
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190301200501.16533-7-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20180521140402.23318-8-peter.maydell@linaro.org
17
---
12
---
18
include/exec/memory-internal.h | 3 ++-
13
target/arm/translate-a64.c | 98 ++++++++++++++++++++++----------------
19
exec.c | 4 +++-
14
1 file changed, 57 insertions(+), 41 deletions(-)
20
hw/s390x/s390-pci-inst.c | 3 ++-
21
memory.c | 7 ++++---
22
4 files changed, 11 insertions(+), 6 deletions(-)
23
15
24
diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/include/exec/memory-internal.h
18
--- a/target/arm/translate-a64.c
27
+++ b/include/exec/memory-internal.h
19
+++ b/target/arm/translate-a64.c
28
@@ -XXX,XX +XXX,XX @@ void flatview_unref(FlatView *view);
20
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
29
extern const MemoryRegionOps unassigned_mem_ops;
21
}
30
22
31
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
23
/* Add/subtract (with carry)
32
- unsigned size, bool is_write);
24
- * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0
33
+ unsigned size, bool is_write,
25
- * +--+--+--+------------------------+------+---------+------+-----+
34
+ MemTxAttrs attrs);
26
- * |sf|op| S| 1 1 0 1 0 0 0 0 | rm | opcode2 | Rn | Rd |
35
27
- * +--+--+--+------------------------+------+---------+------+-----+
36
void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section);
28
- * [000000]
37
AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv);
29
+ * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0
38
diff --git a/exec.c b/exec.c
30
+ * +--+--+--+------------------------+------+-------------+------+-----+
39
index XXXXXXX..XXXXXXX 100644
31
+ * |sf|op| S| 1 1 0 1 0 0 0 0 | rm | 0 0 0 0 0 0 | Rn | Rd |
40
--- a/exec.c
32
+ * +--+--+--+------------------------+------+-------------+------+-----+
41
+++ b/exec.c
33
*/
42
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
34
43
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
35
static void disas_adc_sbc(DisasContext *s, uint32_t insn)
44
if (!memory_access_is_direct(mr, is_write)) {
36
@@ -XXX,XX +XXX,XX @@ static void disas_adc_sbc(DisasContext *s, uint32_t insn)
45
l = memory_access_size(mr, l, addr);
37
unsigned int sf, op, setflags, rm, rn, rd;
46
- if (!memory_region_access_valid(mr, xlat, l, is_write)) {
38
TCGv_i64 tcg_y, tcg_rn, tcg_rd;
47
+ /* When our callers all have attrs we'll pass them through here */
39
48
+ if (!memory_region_access_valid(mr, xlat, l, is_write,
40
- if (extract32(insn, 10, 6) != 0) {
49
+ MEMTXATTRS_UNSPECIFIED)) {
41
- unallocated_encoding(s);
50
return false;
42
- return;
51
}
43
- }
44
-
45
sf = extract32(insn, 31, 1);
46
op = extract32(insn, 30, 1);
47
setflags = extract32(insn, 29, 1);
48
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
49
}
50
}
51
52
-/* Data processing - register */
53
+/*
54
+ * Data processing - register
55
+ * 31 30 29 28 25 21 20 16 10 0
56
+ * +--+---+--+---+-------+-----+-------+-------+---------+
57
+ * | |op0| |op1| 1 0 1 | op2 | | op3 | |
58
+ * +--+---+--+---+-------+-----+-------+-------+---------+
59
+ */
60
static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
61
{
62
- switch (extract32(insn, 24, 5)) {
63
- case 0x0a: /* Logical (shifted register) */
64
- disas_logic_reg(s, insn);
65
- break;
66
- case 0x0b: /* Add/subtract */
67
- if (insn & (1 << 21)) { /* (extended register) */
68
- disas_add_sub_ext_reg(s, insn);
69
+ int op0 = extract32(insn, 30, 1);
70
+ int op1 = extract32(insn, 28, 1);
71
+ int op2 = extract32(insn, 21, 4);
72
+ int op3 = extract32(insn, 10, 6);
73
+
74
+ if (!op1) {
75
+ if (op2 & 8) {
76
+ if (op2 & 1) {
77
+ /* Add/sub (extended register) */
78
+ disas_add_sub_ext_reg(s, insn);
79
+ } else {
80
+ /* Add/sub (shifted register) */
81
+ disas_add_sub_reg(s, insn);
82
+ }
83
} else {
84
- disas_add_sub_reg(s, insn);
85
+ /* Logical (shifted register) */
86
+ disas_logic_reg(s, insn);
52
}
87
}
53
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
88
- break;
54
index XXXXXXX..XXXXXXX 100644
89
- case 0x1b: /* Data-processing (3 source) */
55
--- a/hw/s390x/s390-pci-inst.c
90
- disas_data_proc_3src(s, insn);
56
+++ b/hw/s390x/s390-pci-inst.c
91
- break;
57
@@ -XXX,XX +XXX,XX @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
92
- case 0x1a:
58
mr = s390_get_subregion(mr, offset, len);
93
- switch (extract32(insn, 21, 3)) {
59
offset -= mr->addr;
94
- case 0x0: /* Add/subtract (with carry) */
60
95
+ return;
61
- if (!memory_region_access_valid(mr, offset, len, true)) {
96
+ }
62
+ if (!memory_region_access_valid(mr, offset, len, true,
97
+
63
+ MEMTXATTRS_UNSPECIFIED)) {
98
+ switch (op2) {
64
s390_program_interrupt(env, PGM_OPERAND, 6, ra);
99
+ case 0x0:
65
return 0;
100
+ switch (op3) {
66
}
101
+ case 0x00: /* Add/subtract (with carry) */
67
diff --git a/memory.c b/memory.c
102
disas_adc_sbc(s, insn);
68
index XXXXXXX..XXXXXXX 100644
103
break;
69
--- a/memory.c
104
- case 0x2: /* Conditional compare */
70
+++ b/memory.c
105
- disas_cc(s, insn); /* both imm and reg forms */
71
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps ram_device_mem_ops = {
106
- break;
72
bool memory_region_access_valid(MemoryRegion *mr,
107
- case 0x4: /* Conditional select */
73
hwaddr addr,
108
- disas_cond_select(s, insn);
74
unsigned size,
109
- break;
75
- bool is_write)
110
- case 0x6: /* Data-processing */
76
+ bool is_write,
111
- if (insn & (1 << 30)) { /* (1 source) */
77
+ MemTxAttrs attrs)
112
- disas_data_proc_1src(s, insn);
78
{
113
- } else { /* (2 source) */
79
int access_size_min, access_size_max;
114
- disas_data_proc_2src(s, insn);
80
int access_size, i;
115
- }
81
@@ -XXX,XX +XXX,XX @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
116
- break;
82
{
117
+
83
MemTxResult r;
118
default:
84
119
- unallocated_encoding(s);
85
- if (!memory_region_access_valid(mr, addr, size, false)) {
120
- break;
86
+ if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
121
+ goto do_unallocated;
87
*pval = unassigned_mem_read(mr, addr, size);
122
}
88
return MEMTX_DECODE_ERROR;
123
break;
89
}
124
+
90
@@ -XXX,XX +XXX,XX @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
125
+ case 0x2: /* Conditional compare */
91
unsigned size,
126
+ disas_cc(s, insn); /* both imm and reg forms */
92
MemTxAttrs attrs)
127
+ break;
93
{
128
+
94
- if (!memory_region_access_valid(mr, addr, size, true)) {
129
+ case 0x4: /* Conditional select */
95
+ if (!memory_region_access_valid(mr, addr, size, true, attrs)) {
130
+ disas_cond_select(s, insn);
96
unassigned_mem_write(mr, addr, data, size);
131
+ break;
97
return MEMTX_DECODE_ERROR;
132
+
133
+ case 0x6: /* Data-processing */
134
+ if (op0) { /* (1 source) */
135
+ disas_data_proc_1src(s, insn);
136
+ } else { /* (2 source) */
137
+ disas_data_proc_2src(s, insn);
138
+ }
139
+ break;
140
+ case 0x8 ... 0xf: /* (3 source) */
141
+ disas_data_proc_3src(s, insn);
142
+ break;
143
+
144
default:
145
+ do_unallocated:
146
unallocated_encoding(s);
147
break;
98
}
148
}
99
--
149
--
100
2.17.1
150
2.20.1
101
151
102
152
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
add MemTxAttrs as an argument to address_space_map().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
2
3
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190301200501.16533-8-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
[PMM: fixed up block comment style]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-5-peter.maydell@linaro.org
10
---
9
---
11
include/exec/memory.h | 3 ++-
10
target/arm/cpu.h | 5 ++
12
include/sysemu/dma.h | 3 ++-
11
linux-user/elfload.c | 1 +
13
exec.c | 6 ++++--
12
target/arm/cpu64.c | 1 +
14
target/ppc/mmu-hash64.c | 3 ++-
13
target/arm/translate-a64.c | 99 +++++++++++++++++++++++++++++++++++++-
15
4 files changed, 10 insertions(+), 5 deletions(-)
14
4 files changed, 105 insertions(+), 1 deletion(-)
16
15
17
diff --git a/include/exec/memory.h b/include/exec/memory.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/memory.h
18
--- a/target/arm/cpu.h
20
+++ b/include/exec/memory.h
19
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id)
22
* @addr: address within that address space
21
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0;
23
* @plen: pointer to length of buffer; updated on return
22
}
24
* @is_write: indicates the transfer direction
23
25
+ * @attrs: memory attributes
24
+static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id)
26
*/
25
+{
27
void *address_space_map(AddressSpace *as, hwaddr addr,
26
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0;
28
- hwaddr *plen, bool is_write);
27
+}
29
+ hwaddr *plen, bool is_write, MemTxAttrs attrs);
28
+
30
29
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
31
/* address_space_unmap: Unmaps a memory region previously mapped by address_space_map()
30
{
32
*
31
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
33
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
32
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
34
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
35
--- a/include/sysemu/dma.h
34
--- a/linux-user/elfload.c
36
+++ b/include/sysemu/dma.h
35
+++ b/linux-user/elfload.c
37
@@ -XXX,XX +XXX,XX @@ static inline void *dma_memory_map(AddressSpace *as,
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
38
hwaddr xlen = *len;
37
GET_FEATURE_ID(aa64_fhm, ARM_HWCAP_A64_ASIMDFHM);
39
void *p;
38
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
40
39
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
41
- p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE);
40
+ GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
42
+ p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE,
41
43
+ MEMTXATTRS_UNSPECIFIED);
42
#undef GET_FEATURE_ID
44
*len = xlen;
43
45
return p;
44
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu64.c
47
+++ b/target/arm/cpu64.c
48
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
49
t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
50
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
51
t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
52
+ t = FIELD_DP64(t, ID_AA64ISAR0, TS, 1);
53
cpu->isar.id_aa64isar0 = t;
54
55
t = cpu->isar.id_aa64isar1;
56
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-a64.c
59
+++ b/target/arm/translate-a64.c
60
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
61
s->base.is_jmp = DISAS_TOO_MANY;
62
63
switch (op) {
64
+ case 0x00: /* CFINV */
65
+ if (crm != 0 || !dc_isar_feature(aa64_condm_4, s)) {
66
+ goto do_unallocated;
67
+ }
68
+ tcg_gen_xori_i32(cpu_CF, cpu_CF, 1);
69
+ s->base.is_jmp = DISAS_NEXT;
70
+ break;
71
+
72
case 0x05: /* SPSel */
73
if (s->current_el == 0) {
74
goto do_unallocated;
75
@@ -XXX,XX +XXX,XX @@ static void gen_get_nzcv(TCGv_i64 tcg_rt)
46
}
76
}
47
diff --git a/exec.c b/exec.c
77
48
index XXXXXXX..XXXXXXX 100644
78
static void gen_set_nzcv(TCGv_i64 tcg_rt)
49
--- a/exec.c
79
-
50
+++ b/exec.c
51
@@ -XXX,XX +XXX,XX @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
52
void *address_space_map(AddressSpace *as,
53
hwaddr addr,
54
hwaddr *plen,
55
- bool is_write)
56
+ bool is_write,
57
+ MemTxAttrs attrs)
58
{
80
{
59
hwaddr len = *plen;
81
TCGv_i32 nzcv = tcg_temp_new_i32();
60
hwaddr l, xlat;
82
61
@@ -XXX,XX +XXX,XX @@ void *cpu_physical_memory_map(hwaddr addr,
83
@@ -XXX,XX +XXX,XX @@ static void disas_adc_sbc(DisasContext *s, uint32_t insn)
62
hwaddr *plen,
84
}
63
int is_write)
64
{
65
- return address_space_map(&address_space_memory, addr, plen, is_write);
66
+ return address_space_map(&address_space_memory, addr, plen, is_write,
67
+ MEMTXATTRS_UNSPECIFIED);
68
}
85
}
69
86
70
void cpu_physical_memory_unmap(void *buffer, hwaddr len,
87
+/*
71
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
88
+ * Rotate right into flags
72
index XXXXXXX..XXXXXXX 100644
89
+ * 31 30 29 21 15 10 5 4 0
73
--- a/target/ppc/mmu-hash64.c
90
+ * +--+--+--+-----------------+--------+-----------+------+--+------+
74
+++ b/target/ppc/mmu-hash64.c
91
+ * |sf|op| S| 1 1 0 1 0 0 0 0 | imm6 | 0 0 0 0 1 | Rn |o2| mask |
75
@@ -XXX,XX +XXX,XX @@ const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu,
92
+ * +--+--+--+-----------------+--------+-----------+------+--+------+
76
return NULL;
93
+ */
77
}
94
+static void disas_rotate_right_into_flags(DisasContext *s, uint32_t insn)
78
95
+{
79
- hptes = address_space_map(CPU(cpu)->as, base + pte_offset, &plen, false);
96
+ int mask = extract32(insn, 0, 4);
80
+ hptes = address_space_map(CPU(cpu)->as, base + pte_offset, &plen, false,
97
+ int o2 = extract32(insn, 4, 1);
81
+ MEMTXATTRS_UNSPECIFIED);
98
+ int rn = extract32(insn, 5, 5);
82
if (plen < (n * HASH_PTE_SIZE_64)) {
99
+ int imm6 = extract32(insn, 15, 6);
83
hw_error("%s: Unable to map all requested HPTEs\n", __func__);
100
+ int sf_op_s = extract32(insn, 29, 3);
84
}
101
+ TCGv_i64 tcg_rn;
102
+ TCGv_i32 nzcv;
103
+
104
+ if (sf_op_s != 5 || o2 != 0 || !dc_isar_feature(aa64_condm_4, s)) {
105
+ unallocated_encoding(s);
106
+ return;
107
+ }
108
+
109
+ tcg_rn = read_cpu_reg(s, rn, 1);
110
+ tcg_gen_rotri_i64(tcg_rn, tcg_rn, imm6);
111
+
112
+ nzcv = tcg_temp_new_i32();
113
+ tcg_gen_extrl_i64_i32(nzcv, tcg_rn);
114
+
115
+ if (mask & 8) { /* N */
116
+ tcg_gen_shli_i32(cpu_NF, nzcv, 31 - 3);
117
+ }
118
+ if (mask & 4) { /* Z */
119
+ tcg_gen_not_i32(cpu_ZF, nzcv);
120
+ tcg_gen_andi_i32(cpu_ZF, cpu_ZF, 4);
121
+ }
122
+ if (mask & 2) { /* C */
123
+ tcg_gen_extract_i32(cpu_CF, nzcv, 1, 1);
124
+ }
125
+ if (mask & 1) { /* V */
126
+ tcg_gen_shli_i32(cpu_VF, nzcv, 31 - 0);
127
+ }
128
+
129
+ tcg_temp_free_i32(nzcv);
130
+}
131
+
132
+/*
133
+ * Evaluate into flags
134
+ * 31 30 29 21 15 14 10 5 4 0
135
+ * +--+--+--+-----------------+---------+----+---------+------+--+------+
136
+ * |sf|op| S| 1 1 0 1 0 0 0 0 | opcode2 | sz | 0 0 1 0 | Rn |o3| mask |
137
+ * +--+--+--+-----------------+---------+----+---------+------+--+------+
138
+ */
139
+static void disas_evaluate_into_flags(DisasContext *s, uint32_t insn)
140
+{
141
+ int o3_mask = extract32(insn, 0, 5);
142
+ int rn = extract32(insn, 5, 5);
143
+ int o2 = extract32(insn, 15, 6);
144
+ int sz = extract32(insn, 14, 1);
145
+ int sf_op_s = extract32(insn, 29, 3);
146
+ TCGv_i32 tmp;
147
+ int shift;
148
+
149
+ if (sf_op_s != 1 || o2 != 0 || o3_mask != 0xd ||
150
+ !dc_isar_feature(aa64_condm_4, s)) {
151
+ unallocated_encoding(s);
152
+ return;
153
+ }
154
+ shift = sz ? 16 : 24; /* SETF16 or SETF8 */
155
+
156
+ tmp = tcg_temp_new_i32();
157
+ tcg_gen_extrl_i64_i32(tmp, cpu_reg(s, rn));
158
+ tcg_gen_shli_i32(cpu_NF, tmp, shift);
159
+ tcg_gen_shli_i32(cpu_VF, tmp, shift - 1);
160
+ tcg_gen_mov_i32(cpu_ZF, cpu_NF);
161
+ tcg_gen_xor_i32(cpu_VF, cpu_VF, cpu_NF);
162
+ tcg_temp_free_i32(tmp);
163
+}
164
+
165
/* Conditional compare (immediate / register)
166
* 31 30 29 28 27 26 25 24 23 22 21 20 16 15 12 11 10 9 5 4 3 0
167
* +--+--+--+------------------------+--------+------+----+--+------+--+-----+
168
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
169
disas_adc_sbc(s, insn);
170
break;
171
172
+ case 0x01: /* Rotate right into flags */
173
+ case 0x21:
174
+ disas_rotate_right_into_flags(s, insn);
175
+ break;
176
+
177
+ case 0x02: /* Evaluate into flags */
178
+ case 0x12:
179
+ case 0x22:
180
+ case 0x32:
181
+ disas_evaluate_into_flags(s, insn);
182
+ break;
183
+
184
default:
185
goto do_unallocated;
186
}
85
--
187
--
86
2.17.1
188
2.20.1
87
189
88
190
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
add MemTxAttrs as an argument to tb_invalidate_phys_addr().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
2
3
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190301200501.16533-9-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180521140402.23318-3-peter.maydell@linaro.org
10
---
8
---
11
include/exec/exec-all.h | 5 +++--
9
target/arm/cpu.h | 5 ++++
12
accel/tcg/translate-all.c | 2 +-
10
target/arm/cpu64.c | 2 +-
13
exec.c | 2 +-
11
target/arm/translate-a64.c | 58 ++++++++++++++++++++++++++++++++++++++
14
target/xtensa/op_helper.c | 3 ++-
12
3 files changed, 64 insertions(+), 1 deletion(-)
15
4 files changed, 7 insertions(+), 5 deletions(-)
16
13
17
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/exec-all.h
16
--- a/target/arm/cpu.h
20
+++ b/include/exec/exec-all.h
17
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id)
22
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
19
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0;
23
hwaddr paddr, int prot,
20
}
24
int mmu_idx, target_ulong size);
21
25
-void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr);
22
+static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id)
26
+void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs);
23
+{
27
void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
24
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2;
28
uintptr_t retaddr);
25
+}
29
#else
26
+
30
@@ -XXX,XX +XXX,XX @@ static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
27
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
31
uint16_t idxmap)
32
{
28
{
33
}
29
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
34
-static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
30
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
35
+static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr,
36
+ MemTxAttrs attrs)
37
{
38
}
39
#endif
40
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
41
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
42
--- a/accel/tcg/translate-all.c
32
--- a/target/arm/cpu64.c
43
+++ b/accel/tcg/translate-all.c
33
+++ b/target/arm/cpu64.c
44
@@ -XXX,XX +XXX,XX @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
34
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
45
}
35
t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
46
36
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
47
#if !defined(CONFIG_USER_ONLY)
37
t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
48
-void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
38
- t = FIELD_DP64(t, ID_AA64ISAR0, TS, 1);
49
+void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
39
+ t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
50
{
40
cpu->isar.id_aa64isar0 = t;
51
ram_addr_t ram_addr;
41
52
MemoryRegion *mr;
42
t = cpu->isar.id_aa64isar1;
53
diff --git a/exec.c b/exec.c
43
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
54
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
55
--- a/exec.c
45
--- a/target/arm/translate-a64.c
56
+++ b/exec.c
46
+++ b/target/arm/translate-a64.c
57
@@ -XXX,XX +XXX,XX @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
47
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
58
if (phys != -1) {
59
/* Locks grabbed by tb_invalidate_phys_addr */
60
tb_invalidate_phys_addr(cpu->cpu_ases[asidx].as,
61
- phys | (pc & ~TARGET_PAGE_MASK));
62
+ phys | (pc & ~TARGET_PAGE_MASK), attrs);
63
}
48
}
64
}
49
}
65
#endif
50
66
diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c
51
+static void gen_xaflag(void)
67
index XXXXXXX..XXXXXXX 100644
52
+{
68
--- a/target/xtensa/op_helper.c
53
+ TCGv_i32 z = tcg_temp_new_i32();
69
+++ b/target/xtensa/op_helper.c
54
+
70
@@ -XXX,XX +XXX,XX @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
55
+ tcg_gen_setcondi_i32(TCG_COND_EQ, z, cpu_ZF, 0);
71
int ret = xtensa_get_physical_addr(env, false, vaddr, 2, 0,
56
+
72
&paddr, &page_size, &access);
57
+ /*
73
if (ret == 0) {
58
+ * (!C & !Z) << 31
74
- tb_invalidate_phys_addr(&address_space_memory, paddr);
59
+ * (!(C | Z)) << 31
75
+ tb_invalidate_phys_addr(&address_space_memory, paddr,
60
+ * ~((C | Z) << 31)
76
+ MEMTXATTRS_UNSPECIFIED);
61
+ * ~-(C | Z)
77
}
62
+ * (C | Z) - 1
78
}
63
+ */
79
64
+ tcg_gen_or_i32(cpu_NF, cpu_CF, z);
65
+ tcg_gen_subi_i32(cpu_NF, cpu_NF, 1);
66
+
67
+ /* !(Z & C) */
68
+ tcg_gen_and_i32(cpu_ZF, z, cpu_CF);
69
+ tcg_gen_xori_i32(cpu_ZF, cpu_ZF, 1);
70
+
71
+ /* (!C & Z) << 31 -> -(Z & ~C) */
72
+ tcg_gen_andc_i32(cpu_VF, z, cpu_CF);
73
+ tcg_gen_neg_i32(cpu_VF, cpu_VF);
74
+
75
+ /* C | Z */
76
+ tcg_gen_or_i32(cpu_CF, cpu_CF, z);
77
+
78
+ tcg_temp_free_i32(z);
79
+}
80
+
81
+static void gen_axflag(void)
82
+{
83
+ tcg_gen_sari_i32(cpu_VF, cpu_VF, 31); /* V ? -1 : 0 */
84
+ tcg_gen_andc_i32(cpu_CF, cpu_CF, cpu_VF); /* C & !V */
85
+
86
+ /* !(Z | V) -> !(!ZF | V) -> ZF & !V -> ZF & ~VF */
87
+ tcg_gen_andc_i32(cpu_ZF, cpu_ZF, cpu_VF);
88
+
89
+ tcg_gen_movi_i32(cpu_NF, 0);
90
+ tcg_gen_movi_i32(cpu_VF, 0);
91
+}
92
+
93
/* MSR (immediate) - move immediate to processor state field */
94
static void handle_msr_i(DisasContext *s, uint32_t insn,
95
unsigned int op1, unsigned int op2, unsigned int crm)
96
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
97
s->base.is_jmp = DISAS_NEXT;
98
break;
99
100
+ case 0x01: /* XAFlag */
101
+ if (crm != 0 || !dc_isar_feature(aa64_condm_5, s)) {
102
+ goto do_unallocated;
103
+ }
104
+ gen_xaflag();
105
+ s->base.is_jmp = DISAS_NEXT;
106
+ break;
107
+
108
+ case 0x02: /* AXFlag */
109
+ if (crm != 0 || !dc_isar_feature(aa64_condm_5, s)) {
110
+ goto do_unallocated;
111
+ }
112
+ gen_axflag();
113
+ s->base.is_jmp = DISAS_NEXT;
114
+ break;
115
+
116
case 0x05: /* SPSel */
117
if (s->current_el == 0) {
118
goto do_unallocated;
80
--
119
--
81
2.17.1
120
2.20.1
82
121
83
122
diff view generated by jsdifflib
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
It forgot to increase clroffset during the loop. So it only clear the
3
This will allow sharing code that adjusts rmode beyond
4
first 4 bytes.
4
the existing users.
5
5
6
Fixes: 367b9f527becdd20ddf116e17a3c0c2bbc486920
6
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Cc: qemu-stable@nongnu.org
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
8
Message-id: 20190301200501.16533-10-richard.henderson@linaro.org
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Message-id: 1527047633-12368-1-git-send-email-zhaoshenglong@huawei.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
hw/intc/arm_gicv3_kvm.c | 1 +
12
target/arm/translate-a64.c | 90 +++++++++++++++++++++-----------------
15
1 file changed, 1 insertion(+)
13
1 file changed, 49 insertions(+), 41 deletions(-)
16
14
17
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/arm_gicv3_kvm.c
17
--- a/target/arm/translate-a64.c
20
+++ b/hw/intc/arm_gicv3_kvm.c
18
+++ b/target/arm/translate-a64.c
21
@@ -XXX,XX +XXX,XX @@ static void kvm_dist_putbmp(GICv3State *s, uint32_t offset,
19
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
22
if (clroffset != 0) {
20
/* Floating-point data-processing (1 source) - single precision */
23
reg = 0;
21
static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
24
kvm_gicd_access(s, clroffset, &reg, true);
22
{
25
+ clroffset += 4;
23
+ void (*gen_fpst)(TCGv_i32, TCGv_i32, TCGv_ptr);
26
}
24
+ TCGv_i32 tcg_op, tcg_res;
27
reg = *gic_bmp_ptr32(bmp, irq);
25
TCGv_ptr fpst;
28
kvm_gicd_access(s, offset, &reg, true);
26
- TCGv_i32 tcg_op;
27
- TCGv_i32 tcg_res;
28
+ int rmode = -1;
29
30
- fpst = get_fpstatus_ptr(false);
31
tcg_op = read_fp_sreg(s, rn);
32
tcg_res = tcg_temp_new_i32();
33
34
switch (opcode) {
35
case 0x0: /* FMOV */
36
tcg_gen_mov_i32(tcg_res, tcg_op);
37
- break;
38
+ goto done;
39
case 0x1: /* FABS */
40
gen_helper_vfp_abss(tcg_res, tcg_op);
41
- break;
42
+ goto done;
43
case 0x2: /* FNEG */
44
gen_helper_vfp_negs(tcg_res, tcg_op);
45
- break;
46
+ goto done;
47
case 0x3: /* FSQRT */
48
gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env);
49
- break;
50
+ goto done;
51
case 0x8: /* FRINTN */
52
case 0x9: /* FRINTP */
53
case 0xa: /* FRINTM */
54
case 0xb: /* FRINTZ */
55
case 0xc: /* FRINTA */
56
- {
57
- TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
58
-
59
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
60
- gen_helper_rints(tcg_res, tcg_op, fpst);
61
-
62
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
63
- tcg_temp_free_i32(tcg_rmode);
64
+ rmode = arm_rmode_to_sf(opcode & 7);
65
+ gen_fpst = gen_helper_rints;
66
break;
67
- }
68
case 0xe: /* FRINTX */
69
- gen_helper_rints_exact(tcg_res, tcg_op, fpst);
70
+ gen_fpst = gen_helper_rints_exact;
71
break;
72
case 0xf: /* FRINTI */
73
- gen_helper_rints(tcg_res, tcg_op, fpst);
74
+ gen_fpst = gen_helper_rints;
75
break;
76
default:
77
- abort();
78
+ g_assert_not_reached();
79
}
80
81
- write_fp_sreg(s, rd, tcg_res);
82
-
83
+ fpst = get_fpstatus_ptr(false);
84
+ if (rmode >= 0) {
85
+ TCGv_i32 tcg_rmode = tcg_const_i32(rmode);
86
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
87
+ gen_fpst(tcg_res, tcg_op, fpst);
88
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
89
+ tcg_temp_free_i32(tcg_rmode);
90
+ } else {
91
+ gen_fpst(tcg_res, tcg_op, fpst);
92
+ }
93
tcg_temp_free_ptr(fpst);
94
+
95
+ done:
96
+ write_fp_sreg(s, rd, tcg_res);
97
tcg_temp_free_i32(tcg_op);
98
tcg_temp_free_i32(tcg_res);
99
}
100
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
101
/* Floating-point data-processing (1 source) - double precision */
102
static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
103
{
104
+ void (*gen_fpst)(TCGv_i64, TCGv_i64, TCGv_ptr);
105
+ TCGv_i64 tcg_op, tcg_res;
106
TCGv_ptr fpst;
107
- TCGv_i64 tcg_op;
108
- TCGv_i64 tcg_res;
109
+ int rmode = -1;
110
111
switch (opcode) {
112
case 0x0: /* FMOV */
113
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
114
return;
115
}
116
117
- fpst = get_fpstatus_ptr(false);
118
tcg_op = read_fp_dreg(s, rn);
119
tcg_res = tcg_temp_new_i64();
120
121
switch (opcode) {
122
case 0x1: /* FABS */
123
gen_helper_vfp_absd(tcg_res, tcg_op);
124
- break;
125
+ goto done;
126
case 0x2: /* FNEG */
127
gen_helper_vfp_negd(tcg_res, tcg_op);
128
- break;
129
+ goto done;
130
case 0x3: /* FSQRT */
131
gen_helper_vfp_sqrtd(tcg_res, tcg_op, cpu_env);
132
- break;
133
+ goto done;
134
case 0x8: /* FRINTN */
135
case 0x9: /* FRINTP */
136
case 0xa: /* FRINTM */
137
case 0xb: /* FRINTZ */
138
case 0xc: /* FRINTA */
139
- {
140
- TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
141
-
142
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
143
- gen_helper_rintd(tcg_res, tcg_op, fpst);
144
-
145
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
146
- tcg_temp_free_i32(tcg_rmode);
147
+ rmode = arm_rmode_to_sf(opcode & 7);
148
+ gen_fpst = gen_helper_rintd;
149
break;
150
- }
151
case 0xe: /* FRINTX */
152
- gen_helper_rintd_exact(tcg_res, tcg_op, fpst);
153
+ gen_fpst = gen_helper_rintd_exact;
154
break;
155
case 0xf: /* FRINTI */
156
- gen_helper_rintd(tcg_res, tcg_op, fpst);
157
+ gen_fpst = gen_helper_rintd;
158
break;
159
default:
160
- abort();
161
+ g_assert_not_reached();
162
}
163
164
- write_fp_dreg(s, rd, tcg_res);
165
-
166
+ fpst = get_fpstatus_ptr(false);
167
+ if (rmode >= 0) {
168
+ TCGv_i32 tcg_rmode = tcg_const_i32(rmode);
169
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
170
+ gen_fpst(tcg_res, tcg_op, fpst);
171
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
172
+ tcg_temp_free_i32(tcg_rmode);
173
+ } else {
174
+ gen_fpst(tcg_res, tcg_op, fpst);
175
+ }
176
tcg_temp_free_ptr(fpst);
177
+
178
+ done:
179
+ write_fp_dreg(s, rd, tcg_res);
180
tcg_temp_free_i64(tcg_op);
181
tcg_temp_free_i64(tcg_res);
182
}
29
--
183
--
30
2.17.1
184
2.20.1
31
185
32
186
diff view generated by jsdifflib
1
From: Jan Kiszka <jan.kiszka@siemens.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
There was a nasty flip in identifying which register group an access is
3
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
4
targeting. The issue caused spuriously raised priorities of the guest
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
when handing CPUs over in the Jailhouse hypervisor.
5
Message-id: 20190301200501.16533-11-richard.henderson@linaro.org
6
7
Cc: qemu-stable@nongnu.org
8
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
9
Message-id: 28b927d3-da58-bce4-cc13-bfec7f9b1cb9@siemens.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
8
---
13
hw/intc/arm_gicv3_cpuif.c | 12 ++++++------
9
target/arm/cpu.h | 5 ++
14
1 file changed, 6 insertions(+), 6 deletions(-)
10
target/arm/helper.h | 5 ++
11
target/arm/cpu64.c | 1 +
12
target/arm/translate-a64.c | 71 ++++++++++++++++++++++++++--
13
target/arm/vfp_helper.c | 96 ++++++++++++++++++++++++++++++++++++++
14
5 files changed, 173 insertions(+), 5 deletions(-)
15
15
16
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/arm_gicv3_cpuif.c
18
--- a/target/arm/cpu.h
19
+++ b/hw/intc/arm_gicv3_cpuif.c
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id)
21
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0;
22
}
23
24
+static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
25
+{
26
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
27
+}
28
+
29
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
21
{
30
{
22
GICv3CPUState *cs = icc_cs_from_env(env);
31
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
23
int regno = ri->opc2 & 3;
32
diff --git a/target/arm/helper.h b/target/arm/helper.h
24
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
33
index XXXXXXX..XXXXXXX 100644
25
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
34
--- a/target/arm/helper.h
26
uint64_t value = cs->ich_apr[grp][regno];
35
+++ b/target/arm/helper.h
27
36
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_fmlal_idx_a32, TCG_CALL_NO_RWG,
28
trace_gicv3_icv_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
37
DEF_HELPER_FLAGS_5(gvec_fmlal_idx_a64, TCG_CALL_NO_RWG,
29
@@ -XXX,XX +XXX,XX @@ static void icv_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
38
void, ptr, ptr, ptr, ptr, i32)
30
{
39
31
GICv3CPUState *cs = icc_cs_from_env(env);
40
+DEF_HELPER_FLAGS_2(frint32_s, TCG_CALL_NO_RWG, f32, f32, ptr)
32
int regno = ri->opc2 & 3;
41
+DEF_HELPER_FLAGS_2(frint64_s, TCG_CALL_NO_RWG, f32, f32, ptr)
33
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
42
+DEF_HELPER_FLAGS_2(frint32_d, TCG_CALL_NO_RWG, f64, f64, ptr)
34
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
43
+DEF_HELPER_FLAGS_2(frint64_d, TCG_CALL_NO_RWG, f64, f64, ptr)
35
44
+
36
trace_gicv3_icv_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
45
#ifdef TARGET_AARCH64
37
46
#include "helper-a64.h"
38
@@ -XXX,XX +XXX,XX @@ static uint64_t icc_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
47
#include "helper-sve.h"
39
uint64_t value;
48
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
40
49
index XXXXXXX..XXXXXXX 100644
41
int regno = ri->opc2 & 3;
50
--- a/target/arm/cpu64.c
42
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
51
+++ b/target/arm/cpu64.c
43
+ int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
52
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
44
53
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
45
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
54
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
46
return icv_ap_read(env, ri);
55
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
47
@@ -XXX,XX +XXX,XX @@ static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
56
+ t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
48
GICv3CPUState *cs = icc_cs_from_env(env);
57
cpu->isar.id_aa64isar1 = t;
49
58
50
int regno = ri->opc2 & 3;
59
t = cpu->isar.id_aa64pfr0;
51
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
60
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
52
+ int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
61
index XXXXXXX..XXXXXXX 100644
53
62
--- a/target/arm/translate-a64.c
54
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
63
+++ b/target/arm/translate-a64.c
55
icv_ap_write(env, ri, value);
64
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
56
@@ -XXX,XX +XXX,XX @@ static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
65
case 0xf: /* FRINTI */
57
{
66
gen_fpst = gen_helper_rints;
58
GICv3CPUState *cs = icc_cs_from_env(env);
67
break;
59
int regno = ri->opc2 & 3;
68
+ case 0x10: /* FRINT32Z */
60
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
69
+ rmode = float_round_to_zero;
61
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
70
+ gen_fpst = gen_helper_frint32_s;
62
uint64_t value;
71
+ break;
63
72
+ case 0x11: /* FRINT32X */
64
value = cs->ich_apr[grp][regno];
73
+ gen_fpst = gen_helper_frint32_s;
65
@@ -XXX,XX +XXX,XX @@ static void ich_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
74
+ break;
66
{
75
+ case 0x12: /* FRINT64Z */
67
GICv3CPUState *cs = icc_cs_from_env(env);
76
+ rmode = float_round_to_zero;
68
int regno = ri->opc2 & 3;
77
+ gen_fpst = gen_helper_frint64_s;
69
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
78
+ break;
70
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
79
+ case 0x13: /* FRINT64X */
71
80
+ gen_fpst = gen_helper_frint64_s;
72
trace_gicv3_ich_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
81
+ break;
73
82
default:
83
g_assert_not_reached();
84
}
85
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
86
case 0xf: /* FRINTI */
87
gen_fpst = gen_helper_rintd;
88
break;
89
+ case 0x10: /* FRINT32Z */
90
+ rmode = float_round_to_zero;
91
+ gen_fpst = gen_helper_frint32_d;
92
+ break;
93
+ case 0x11: /* FRINT32X */
94
+ gen_fpst = gen_helper_frint32_d;
95
+ break;
96
+ case 0x12: /* FRINT64Z */
97
+ rmode = float_round_to_zero;
98
+ gen_fpst = gen_helper_frint64_d;
99
+ break;
100
+ case 0x13: /* FRINT64X */
101
+ gen_fpst = gen_helper_frint64_d;
102
+ break;
103
default:
104
g_assert_not_reached();
105
}
106
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
107
handle_fp_fcvt(s, opcode, rd, rn, dtype, type);
108
break;
109
}
110
+
111
+ case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */
112
+ if (type > 1 || !dc_isar_feature(aa64_frint, s)) {
113
+ unallocated_encoding(s);
114
+ return;
115
+ }
116
+ /* fall through */
117
case 0x0 ... 0x3:
118
case 0x8 ... 0xc:
119
case 0xe ... 0xf:
120
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
121
if (!fp_access_check(s)) {
122
return;
123
}
124
-
125
handle_fp_1src_single(s, opcode, rd, rn);
126
break;
127
case 1:
128
if (!fp_access_check(s)) {
129
return;
130
}
131
-
132
handle_fp_1src_double(s, opcode, rd, rn);
133
break;
134
case 3:
135
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
136
if (!fp_access_check(s)) {
137
return;
138
}
139
-
140
handle_fp_1src_half(s, opcode, rd, rn);
141
break;
142
default:
143
unallocated_encoding(s);
144
}
145
break;
146
+
147
default:
148
unallocated_encoding(s);
149
break;
150
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u,
151
case 0x59: /* FRINTX */
152
gen_helper_rintd_exact(tcg_rd, tcg_rn, tcg_fpstatus);
153
break;
154
+ case 0x1e: /* FRINT32Z */
155
+ case 0x5e: /* FRINT32X */
156
+ gen_helper_frint32_d(tcg_rd, tcg_rn, tcg_fpstatus);
157
+ break;
158
+ case 0x1f: /* FRINT64Z */
159
+ case 0x5f: /* FRINT64X */
160
+ gen_helper_frint64_d(tcg_rd, tcg_rn, tcg_fpstatus);
161
+ break;
162
default:
163
g_assert_not_reached();
164
}
165
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
166
}
167
break;
168
case 0xc ... 0xf:
169
- case 0x16 ... 0x1d:
170
- case 0x1f:
171
+ case 0x16 ... 0x1f:
172
{
173
/* Floating point: U, size[1] and opcode indicate operation;
174
* size[0] indicates single or double precision.
175
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
176
}
177
need_fpstatus = true;
178
break;
179
+ case 0x1e: /* FRINT32Z */
180
+ case 0x1f: /* FRINT64Z */
181
+ need_rmode = true;
182
+ rmode = FPROUNDING_ZERO;
183
+ /* fall through */
184
+ case 0x5e: /* FRINT32X */
185
+ case 0x5f: /* FRINT64X */
186
+ need_fpstatus = true;
187
+ if ((size == 3 && !is_q) || !dc_isar_feature(aa64_frint, s)) {
188
+ unallocated_encoding(s);
189
+ return;
190
+ }
191
+ break;
192
default:
193
unallocated_encoding(s);
194
return;
195
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
196
case 0x7c: /* URSQRTE */
197
gen_helper_rsqrte_u32(tcg_res, tcg_op, tcg_fpstatus);
198
break;
199
+ case 0x1e: /* FRINT32Z */
200
+ case 0x5e: /* FRINT32X */
201
+ gen_helper_frint32_s(tcg_res, tcg_op, tcg_fpstatus);
202
+ break;
203
+ case 0x1f: /* FRINT64Z */
204
+ case 0x5f: /* FRINT64X */
205
+ gen_helper_frint64_s(tcg_res, tcg_op, tcg_fpstatus);
206
+ break;
207
default:
208
g_assert_not_reached();
209
}
210
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
211
index XXXXXXX..XXXXXXX 100644
212
--- a/target/arm/vfp_helper.c
213
+++ b/target/arm/vfp_helper.c
214
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vjcvt)(float64 value, CPUARMState *env)
215
216
return result;
217
}
218
+
219
+/* Round a float32 to an integer that fits in int32_t or int64_t. */
220
+static float32 frint_s(float32 f, float_status *fpst, int intsize)
221
+{
222
+ int old_flags = get_float_exception_flags(fpst);
223
+ uint32_t exp = extract32(f, 23, 8);
224
+
225
+ if (unlikely(exp == 0xff)) {
226
+ /* NaN or Inf. */
227
+ goto overflow;
228
+ }
229
+
230
+ /* Round and re-extract the exponent. */
231
+ f = float32_round_to_int(f, fpst);
232
+ exp = extract32(f, 23, 8);
233
+
234
+ /* Validate the range of the result. */
235
+ if (exp < 126 + intsize) {
236
+ /* abs(F) <= INT{N}_MAX */
237
+ return f;
238
+ }
239
+ if (exp == 126 + intsize) {
240
+ uint32_t sign = extract32(f, 31, 1);
241
+ uint32_t frac = extract32(f, 0, 23);
242
+ if (sign && frac == 0) {
243
+ /* F == INT{N}_MIN */
244
+ return f;
245
+ }
246
+ }
247
+
248
+ overflow:
249
+ /*
250
+ * Raise Invalid and return INT{N}_MIN as a float. Revert any
251
+ * inexact exception float32_round_to_int may have raised.
252
+ */
253
+ set_float_exception_flags(old_flags | float_flag_invalid, fpst);
254
+ return (0x100u + 126u + intsize) << 23;
255
+}
256
+
257
+float32 HELPER(frint32_s)(float32 f, void *fpst)
258
+{
259
+ return frint_s(f, fpst, 32);
260
+}
261
+
262
+float32 HELPER(frint64_s)(float32 f, void *fpst)
263
+{
264
+ return frint_s(f, fpst, 64);
265
+}
266
+
267
+/* Round a float64 to an integer that fits in int32_t or int64_t. */
268
+static float64 frint_d(float64 f, float_status *fpst, int intsize)
269
+{
270
+ int old_flags = get_float_exception_flags(fpst);
271
+ uint32_t exp = extract64(f, 52, 11);
272
+
273
+ if (unlikely(exp == 0x7ff)) {
274
+ /* NaN or Inf. */
275
+ goto overflow;
276
+ }
277
+
278
+ /* Round and re-extract the exponent. */
279
+ f = float64_round_to_int(f, fpst);
280
+ exp = extract64(f, 52, 11);
281
+
282
+ /* Validate the range of the result. */
283
+ if (exp < 1022 + intsize) {
284
+ /* abs(F) <= INT{N}_MAX */
285
+ return f;
286
+ }
287
+ if (exp == 1022 + intsize) {
288
+ uint64_t sign = extract64(f, 63, 1);
289
+ uint64_t frac = extract64(f, 0, 52);
290
+ if (sign && frac == 0) {
291
+ /* F == INT{N}_MIN */
292
+ return f;
293
+ }
294
+ }
295
+
296
+ overflow:
297
+ /*
298
+ * Raise Invalid and return INT{N}_MIN as a float. Revert any
299
+ * inexact exception float64_round_to_int may have raised.
300
+ */
301
+ set_float_exception_flags(old_flags | float_flag_invalid, fpst);
302
+ return (uint64_t)(0x800 + 1022 + intsize) << 52;
303
+}
304
+
305
+float64 HELPER(frint32_d)(float64 f, void *fpst)
306
+{
307
+ return frint_d(f, fpst, 32);
308
+}
309
+
310
+float64 HELPER(frint64_d)(float64 f, void *fpst)
311
+{
312
+ return frint_d(f, fpst, 64);
313
+}
74
--
314
--
75
2.17.1
315
2.20.1
76
316
77
317
diff view generated by jsdifflib
1
From: Igor Mammedov <imammedo@redhat.com>
1
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
2
2
3
When QEMU is started with following CLI
3
We introduce an helper to create a memory node.
4
-machine virt,gic-version=3,accel=kvm -cpu host -bios AAVMF_CODE.fd
5
it crashes with abort at
6
accel/kvm/kvm-all.c:2164:
7
KVM_SET_DEVICE_ATTR failed: Group 6 attr 0x000000000000c665: Invalid argument
8
4
9
Which is caused by implicit dependency of kvm_arm_gicv3_reset() on
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
arm_gicv3_icc_reset() where the later is called by CPU reset
6
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
11
reset callback.
7
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
12
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
However commit:
9
Message-id: 20190304101339.25970-2-eric.auger@redhat.com
14
3b77f6c arm/boot: split load_dtb() from arm_load_kernel()
15
broke CPU reset callback registration in case
16
17
arm_load_kernel()
18
...
19
if (!info->kernel_filename || info->firmware_loaded)
20
21
branch is taken, i.e. it's sufficient to provide a firmware
22
or do not provide kernel on CLI to skip cpu reset callback
23
registration, where before offending commit the callback
24
has been registered unconditionally.
25
26
Fix it by registering the callback right at the beginning of
27
arm_load_kernel() unconditionally instead of doing it at the end.
28
29
NOTE:
30
we probably should eliminate that dependency anyways as well as
31
separate arch CPU reset parts from arm_load_kernel() into CPU
32
itself, but that refactoring that I probably would have to do
33
anyways later for CPU hotplug to work.
34
35
Reported-by: Auger Eric <eric.auger@redhat.com>
36
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
37
Reviewed-by: Eric Auger <eric.auger@redhat.com>
38
Tested-by: Eric Auger <eric.auger@redhat.com>
39
Message-id: 1527070950-208350-1-git-send-email-imammedo@redhat.com
40
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
41
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
---
11
---
43
hw/arm/boot.c | 18 +++++++++---------
12
hw/arm/boot.c | 54 ++++++++++++++++++++++++++++++++-------------------
44
1 file changed, 9 insertions(+), 9 deletions(-)
13
1 file changed, 34 insertions(+), 20 deletions(-)
45
14
46
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
15
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
47
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/boot.c
17
--- a/hw/arm/boot.c
49
+++ b/hw/arm/boot.c
18
+++ b/hw/arm/boot.c
50
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
19
@@ -XXX,XX +XXX,XX @@ static void set_kernel_args_old(const struct arm_boot_info *info,
51
static const ARMInsnFixup *primary_loader;
20
}
52
AddressSpace *as = arm_boot_address_space(cpu, info);
21
}
53
22
54
+ /* CPU objects (unlike devices) are not automatically reset on system
23
+static int fdt_add_memory_node(void *fdt, uint32_t acells, hwaddr mem_base,
55
+ * reset, so we must always register a handler to do so. If we're
24
+ uint32_t scells, hwaddr mem_len,
56
+ * actually loading a kernel, the handler is also responsible for
25
+ int numa_node_id)
57
+ * arranging that we start it correctly.
26
+{
58
+ */
27
+ char *nodename;
59
+ for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
28
+ int ret;
60
+ qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
29
+
30
+ nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
31
+ qemu_fdt_add_subnode(fdt, nodename);
32
+ qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
33
+ ret = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", acells, mem_base,
34
+ scells, mem_len);
35
+ if (ret < 0) {
36
+ goto out;
61
+ }
37
+ }
62
+
38
+
63
/* The board code is not supposed to set secure_board_setup unless
39
+ /* only set the NUMA ID if it is specified */
64
* running its code in secure mode is actually possible, and KVM
40
+ if (numa_node_id >= 0) {
65
* doesn't support secure.
41
+ ret = qemu_fdt_setprop_cell(fdt, nodename,
66
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
42
+ "numa-node-id", numa_node_id);
67
ARM_CPU(cs)->env.boot_info = info;
43
+ }
44
+out:
45
+ g_free(nodename);
46
+ return ret;
47
+}
48
+
49
static void fdt_add_psci_node(void *fdt)
50
{
51
uint32_t cpu_suspend_fn;
52
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
53
void *fdt = NULL;
54
int size, rc, n = 0;
55
uint32_t acells, scells;
56
- char *nodename;
57
unsigned int i;
58
hwaddr mem_base, mem_len;
59
char **node_path;
60
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
61
mem_base = binfo->loader_start;
62
for (i = 0; i < nb_numa_nodes; i++) {
63
mem_len = numa_info[i].node_mem;
64
- nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
65
- qemu_fdt_add_subnode(fdt, nodename);
66
- qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
67
- rc = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
68
- acells, mem_base,
69
- scells, mem_len);
70
+ rc = fdt_add_memory_node(fdt, acells, mem_base,
71
+ scells, mem_len, i);
72
if (rc < 0) {
73
- fprintf(stderr, "couldn't set %s/reg for node %d\n", nodename,
74
- i);
75
+ fprintf(stderr, "couldn't add /memory@%"PRIx64" node\n",
76
+ mem_base);
77
goto fail;
78
}
79
80
- qemu_fdt_setprop_cell(fdt, nodename, "numa-node-id", i);
81
mem_base += mem_len;
82
- g_free(nodename);
83
}
84
} else {
85
- nodename = g_strdup_printf("/memory@%" PRIx64, binfo->loader_start);
86
- qemu_fdt_add_subnode(fdt, nodename);
87
- qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
88
-
89
- rc = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
90
- acells, binfo->loader_start,
91
- scells, binfo->ram_size);
92
+ rc = fdt_add_memory_node(fdt, acells, binfo->loader_start,
93
+ scells, binfo->ram_size, -1);
94
if (rc < 0) {
95
- fprintf(stderr, "couldn't set %s reg\n", nodename);
96
+ fprintf(stderr, "couldn't add /memory@%"PRIx64" node\n",
97
+ binfo->loader_start);
98
goto fail;
99
}
100
- g_free(nodename);
68
}
101
}
69
102
70
- /* CPU objects (unlike devices) are not automatically reset on system
103
rc = fdt_path_offset(fdt, "/chosen");
71
- * reset, so we must always register a handler to do so. If we're
72
- * actually loading a kernel, the handler is also responsible for
73
- * arranging that we start it correctly.
74
- */
75
- for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
76
- qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
77
- }
78
-
79
if (!info->skip_dtb_autoload && have_dtb(info)) {
80
if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) {
81
exit(1);
82
--
104
--
83
2.17.1
105
2.20.1
84
106
85
107
diff view generated by jsdifflib
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
acpi_data_push uses g_array_set_size to resize the memory size. If there
3
In preparation for a split of the memory map into a static
4
is no enough contiguous memory, the address will be changed. So previous
4
part and a dynamic part floating after the RAM, let's rename the
5
pointer could not be used any more. It must update the pointer and use
5
regions located after the RAM
6
the new one.
7
6
8
Also, previous codes wrongly use le32 conversion of iort->node_offset
7
Signed-off-by: Eric Auger <eric.auger@redhat.com>
9
for subsequent computations that will result incorrect value if host is
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
not litlle endian. So use the non-converted one instead.
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
11
10
Message-id: 20190304101339.25970-3-eric.auger@redhat.com
12
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
13
Reviewed-by: Eric Auger <eric.auger@redhat.com>
14
Message-id: 1527663951-14552-1-git-send-email-zhaoshenglong@huawei.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
12
---
17
hw/arm/virt-acpi-build.c | 20 +++++++++++++++-----
13
include/hw/arm/virt.h | 8 ++++----
18
1 file changed, 15 insertions(+), 5 deletions(-)
14
hw/arm/virt-acpi-build.c | 10 ++++++----
15
hw/arm/virt.c | 33 ++++++++++++++++++---------------
16
3 files changed, 28 insertions(+), 23 deletions(-)
19
17
18
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/virt.h
21
+++ b/include/hw/arm/virt.h
22
@@ -XXX,XX +XXX,XX @@ enum {
23
VIRT_GIC_VCPU,
24
VIRT_GIC_ITS,
25
VIRT_GIC_REDIST,
26
- VIRT_GIC_REDIST2,
27
+ VIRT_HIGH_GIC_REDIST2,
28
VIRT_SMMU,
29
VIRT_UART,
30
VIRT_MMIO,
31
@@ -XXX,XX +XXX,XX @@ enum {
32
VIRT_PCIE_MMIO,
33
VIRT_PCIE_PIO,
34
VIRT_PCIE_ECAM,
35
- VIRT_PCIE_ECAM_HIGH,
36
+ VIRT_HIGH_PCIE_ECAM,
37
VIRT_PLATFORM_BUS,
38
- VIRT_PCIE_MMIO_HIGH,
39
+ VIRT_HIGH_PCIE_MMIO,
40
VIRT_GPIO,
41
VIRT_SECURE_UART,
42
VIRT_SECURE_MEM,
43
@@ -XXX,XX +XXX,XX @@ typedef struct {
44
int psci_conduit;
45
} VirtMachineState;
46
47
-#define VIRT_ECAM_ID(high) (high ? VIRT_PCIE_ECAM_HIGH : VIRT_PCIE_ECAM)
48
+#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
49
50
#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
51
#define VIRT_MACHINE(obj) \
20
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
52
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
21
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/virt-acpi-build.c
54
--- a/hw/arm/virt-acpi-build.c
23
+++ b/hw/arm/virt-acpi-build.c
55
+++ b/hw/arm/virt-acpi-build.c
24
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
56
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
25
AcpiIortItsGroup *its;
57
size_pio));
26
AcpiIortTable *iort;
58
27
AcpiIortSmmu3 *smmu;
59
if (use_highmem) {
28
- size_t node_size, iort_length, smmu_offset = 0;
60
- hwaddr base_mmio_high = memmap[VIRT_PCIE_MMIO_HIGH].base;
29
+ size_t node_size, iort_node_offset, iort_length, smmu_offset = 0;
61
- hwaddr size_mmio_high = memmap[VIRT_PCIE_MMIO_HIGH].size;
30
AcpiIortRC *rc;
62
+ hwaddr base_mmio_high = memmap[VIRT_HIGH_PCIE_MMIO].base;
31
63
+ hwaddr size_mmio_high = memmap[VIRT_HIGH_PCIE_MMIO].size;
32
iort = acpi_data_push(table_data, sizeof(*iort));
64
33
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
65
aml_append(rbuf,
34
66
aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
35
iort_length = sizeof(*iort);
67
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
36
iort->node_count = cpu_to_le32(nb_nodes);
68
gicr = acpi_data_push(table_data, sizeof(*gicr));
37
- iort->node_offset = cpu_to_le32(sizeof(*iort));
69
gicr->type = ACPI_APIC_GENERIC_REDISTRIBUTOR;
38
+ /*
70
gicr->length = sizeof(*gicr);
39
+ * Use a copy in case table_data->data moves during acpi_data_push
71
- gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST2].base);
40
+ * operations.
72
- gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST2].size);
41
+ */
73
+ gicr->base_address =
42
+ iort_node_offset = sizeof(*iort);
74
+ cpu_to_le64(memmap[VIRT_HIGH_GIC_REDIST2].base);
43
+ iort->node_offset = cpu_to_le32(iort_node_offset);
75
+ gicr->range_length =
44
76
+ cpu_to_le32(memmap[VIRT_HIGH_GIC_REDIST2].size);
45
/* ITS group node */
77
}
46
node_size = sizeof(*its) + sizeof(uint32_t);
78
47
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
79
if (its_class_name() && !vmc->no_its) {
48
int irq = vms->irqmap[VIRT_SMMU];
80
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
49
81
index XXXXXXX..XXXXXXX 100644
50
/* SMMUv3 node */
82
--- a/hw/arm/virt.c
51
- smmu_offset = iort->node_offset + node_size;
83
+++ b/hw/arm/virt.c
52
+ smmu_offset = iort_node_offset + node_size;
84
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry a15memmap[] = {
53
node_size = sizeof(*smmu) + sizeof(*idmap);
85
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
54
iort_length += node_size;
86
[VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
55
smmu = acpi_data_push(table_data, node_size);
87
/* Additional 64 MB redist region (can contain up to 512 redistributors) */
56
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
88
- [VIRT_GIC_REDIST2] = { 0x4000000000ULL, 0x4000000 },
57
idmap->id_count = cpu_to_le32(0xFFFF);
89
- [VIRT_PCIE_ECAM_HIGH] = { 0x4010000000ULL, 0x10000000 },
58
idmap->output_base = 0;
90
+ [VIRT_HIGH_GIC_REDIST2] = { 0x4000000000ULL, 0x4000000 },
59
/* output IORT node is the ITS group node (the first node) */
91
+ [VIRT_HIGH_PCIE_ECAM] = { 0x4010000000ULL, 0x10000000 },
60
- idmap->output_reference = cpu_to_le32(iort->node_offset);
92
/* Second PCIe window, 512GB wide at the 512GB boundary */
61
+ idmap->output_reference = cpu_to_le32(iort_node_offset);
93
- [VIRT_PCIE_MMIO_HIGH] = { 0x8000000000ULL, 0x8000000000ULL },
94
+ [VIRT_HIGH_PCIE_MMIO] = { 0x8000000000ULL, 0x8000000000ULL },
95
};
96
97
static const int a15irqmap[] = {
98
@@ -XXX,XX +XXX,XX @@ static void fdt_add_gic_node(VirtMachineState *vms)
99
2, vms->memmap[VIRT_GIC_REDIST].size);
100
} else {
101
qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
102
- 2, vms->memmap[VIRT_GIC_DIST].base,
103
- 2, vms->memmap[VIRT_GIC_DIST].size,
104
- 2, vms->memmap[VIRT_GIC_REDIST].base,
105
- 2, vms->memmap[VIRT_GIC_REDIST].size,
106
- 2, vms->memmap[VIRT_GIC_REDIST2].base,
107
- 2, vms->memmap[VIRT_GIC_REDIST2].size);
108
+ 2, vms->memmap[VIRT_GIC_DIST].base,
109
+ 2, vms->memmap[VIRT_GIC_DIST].size,
110
+ 2, vms->memmap[VIRT_GIC_REDIST].base,
111
+ 2, vms->memmap[VIRT_GIC_REDIST].size,
112
+ 2, vms->memmap[VIRT_HIGH_GIC_REDIST2].base,
113
+ 2, vms->memmap[VIRT_HIGH_GIC_REDIST2].size);
114
}
115
116
if (vms->virt) {
117
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
118
119
if (nb_redist_regions == 2) {
120
uint32_t redist1_capacity =
121
- vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_SIZE;
122
+ vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
123
124
qdev_prop_set_uint32(gicdev, "redist-region-count[1]",
125
MIN(smp_cpus - redist0_count, redist1_capacity));
126
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
127
if (type == 3) {
128
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base);
129
if (nb_redist_regions == 2) {
130
- sysbus_mmio_map(gicbusdev, 2, vms->memmap[VIRT_GIC_REDIST2].base);
131
+ sysbus_mmio_map(gicbusdev, 2,
132
+ vms->memmap[VIRT_HIGH_GIC_REDIST2].base);
133
}
134
} else {
135
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_CPU].base);
136
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
137
{
138
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
139
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
140
- hwaddr base_mmio_high = vms->memmap[VIRT_PCIE_MMIO_HIGH].base;
141
- hwaddr size_mmio_high = vms->memmap[VIRT_PCIE_MMIO_HIGH].size;
142
+ hwaddr base_mmio_high = vms->memmap[VIRT_HIGH_PCIE_MMIO].base;
143
+ hwaddr size_mmio_high = vms->memmap[VIRT_HIGH_PCIE_MMIO].size;
144
hwaddr base_pio = vms->memmap[VIRT_PCIE_PIO].base;
145
hwaddr size_pio = vms->memmap[VIRT_PCIE_PIO].size;
146
hwaddr base_ecam, size_ecam;
147
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
148
* many redistributors we can fit into the memory map.
149
*/
150
if (vms->gic_version == 3) {
151
- virt_max_cpus = vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
152
- virt_max_cpus += vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_SIZE;
153
+ virt_max_cpus =
154
+ vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
155
+ virt_max_cpus +=
156
+ vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
157
} else {
158
virt_max_cpus = GIC_NCPU;
62
}
159
}
63
64
/* Root Complex Node */
65
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
66
idmap->output_reference = cpu_to_le32(smmu_offset);
67
} else {
68
/* output IORT node is the ITS group node (the first node) */
69
- idmap->output_reference = cpu_to_le32(iort->node_offset);
70
+ idmap->output_reference = cpu_to_le32(iort_node_offset);
71
}
72
73
+ /*
74
+ * Update the pointer address in case table_data->data moves during above
75
+ * acpi_data_push operations.
76
+ */
77
+ iort = (AcpiIortTable *)(table_data->data + iort_start);
78
iort->length = cpu_to_le32(iort_length);
79
80
build_header(linker, table_data, (void *)(table_data->data + iort_start),
81
--
160
--
82
2.17.1
161
2.20.1
83
162
84
163
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Eric Auger <eric.auger@redhat.com>
2
add MemTxAttrs as an argument to address_space_translate_iommu().
3
2
3
In the prospect to introduce an extended memory map supporting more
4
RAM, let's split the memory map array into two parts:
5
6
- the former a15memmap, renamed base_memmap, contains regions below
7
and including the RAM. MemMapEntries initialized in this array
8
have a static size and base address.
9
- extended_memmap, only initialized with entries located after the
10
RAM. MemMapEntries initialized in this array only get their size
11
initialized. Their base address is dynamically computed depending
12
on the the top of the RAM, with same alignment as their size.
13
14
Eventually base_memmap entries are copied into the extended_memmap
15
array. Using two separate arrays however clarifies which entries
16
are statically allocated and those which are dynamically allocated.
17
18
This new split will allow to grow the RAM size without changing the
19
description of the high IO entries.
20
21
We introduce a new virt_set_memmap() helper function which
22
"freezes" the memory map. We call it in machvirt_init as
23
memory attributes of the machine are not yet set when
24
virt_instance_init() gets called.
25
26
The memory map is unchanged (the top of the initial RAM still is
27
256GiB). Then come the high IO regions with same layout as before.
28
29
Signed-off-by: Eric Auger <eric.auger@redhat.com>
30
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
31
Message-id: 20190304101339.25970-4-eric.auger@redhat.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180521140402.23318-14-peter.maydell@linaro.org
8
---
33
---
9
exec.c | 8 +++++---
34
include/hw/arm/virt.h | 13 +++++++----
10
1 file changed, 5 insertions(+), 3 deletions(-)
35
hw/arm/virt.c | 50 +++++++++++++++++++++++++++++++++++++------
36
2 files changed, 53 insertions(+), 10 deletions(-)
11
37
12
diff --git a/exec.c b/exec.c
38
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
13
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
14
--- a/exec.c
40
--- a/include/hw/arm/virt.h
15
+++ b/exec.c
41
+++ b/include/hw/arm/virt.h
16
@@ -XXX,XX +XXX,XX @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
42
@@ -XXX,XX +XXX,XX @@ enum {
17
* @is_write: whether the translation operation is for write
43
VIRT_GIC_VCPU,
18
* @is_mmio: whether this can be MMIO, set true if it can
44
VIRT_GIC_ITS,
19
* @target_as: the address space targeted by the IOMMU
45
VIRT_GIC_REDIST,
20
+ * @attrs: transaction attributes
46
- VIRT_HIGH_GIC_REDIST2,
21
*
47
VIRT_SMMU,
22
* This function is called from RCU critical section. It is the common
48
VIRT_UART,
23
* part of flatview_do_translate and address_space_translate_cached.
49
VIRT_MMIO,
24
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection address_space_translate_iommu(IOMMUMemoryRegion *iomm
50
@@ -XXX,XX +XXX,XX @@ enum {
25
hwaddr *page_mask_out,
51
VIRT_PCIE_MMIO,
26
bool is_write,
52
VIRT_PCIE_PIO,
27
bool is_mmio,
53
VIRT_PCIE_ECAM,
28
- AddressSpace **target_as)
54
- VIRT_HIGH_PCIE_ECAM,
29
+ AddressSpace **target_as,
55
VIRT_PLATFORM_BUS,
30
+ MemTxAttrs attrs)
56
- VIRT_HIGH_PCIE_MMIO,
57
VIRT_GPIO,
58
VIRT_SECURE_UART,
59
VIRT_SECURE_MEM,
60
+ VIRT_LOWMEMMAP_LAST,
61
+};
62
+
63
+/* indices of IO regions located after the RAM */
64
+enum {
65
+ VIRT_HIGH_GIC_REDIST2 = VIRT_LOWMEMMAP_LAST,
66
+ VIRT_HIGH_PCIE_ECAM,
67
+ VIRT_HIGH_PCIE_MMIO,
68
};
69
70
typedef enum VirtIOMMUType {
71
@@ -XXX,XX +XXX,XX @@ typedef struct {
72
int32_t gic_version;
73
VirtIOMMUType iommu;
74
struct arm_boot_info bootinfo;
75
- const MemMapEntry *memmap;
76
+ MemMapEntry *memmap;
77
const int *irqmap;
78
int smp_cpus;
79
void *fdt;
80
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/hw/arm/virt.c
83
+++ b/hw/arm/virt.c
84
@@ -XXX,XX +XXX,XX @@
85
*/
86
87
#include "qemu/osdep.h"
88
+#include "qemu/units.h"
89
#include "qapi/error.h"
90
#include "hw/sysbus.h"
91
#include "hw/arm/arm.h"
92
@@ -XXX,XX +XXX,XX @@
93
* Note that devices should generally be placed at multiples of 0x10000,
94
* to accommodate guests using 64K pages.
95
*/
96
-static const MemMapEntry a15memmap[] = {
97
+static const MemMapEntry base_memmap[] = {
98
/* Space up to 0x8000000 is reserved for a boot ROM */
99
[VIRT_FLASH] = { 0, 0x08000000 },
100
[VIRT_CPUPERIPHS] = { 0x08000000, 0x00020000 },
101
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry a15memmap[] = {
102
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
103
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
104
[VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
105
+};
106
+
107
+/*
108
+ * Highmem IO Regions: This memory map is floating, located after the RAM.
109
+ * Each MemMapEntry base (GPA) will be dynamically computed, depending on the
110
+ * top of the RAM, so that its base get the same alignment as the size,
111
+ * ie. a 512GiB entry will be aligned on a 512GiB boundary. If there is
112
+ * less than 256GiB of RAM, the floating area starts at the 256GiB mark.
113
+ * Note the extended_memmap is sized so that it eventually also includes the
114
+ * base_memmap entries (VIRT_HIGH_GIC_REDIST2 index is greater than the last
115
+ * index of base_memmap).
116
+ */
117
+static MemMapEntry extended_memmap[] = {
118
/* Additional 64 MB redist region (can contain up to 512 redistributors) */
119
- [VIRT_HIGH_GIC_REDIST2] = { 0x4000000000ULL, 0x4000000 },
120
- [VIRT_HIGH_PCIE_ECAM] = { 0x4010000000ULL, 0x10000000 },
121
- /* Second PCIe window, 512GB wide at the 512GB boundary */
122
- [VIRT_HIGH_PCIE_MMIO] = { 0x8000000000ULL, 0x8000000000ULL },
123
+ [VIRT_HIGH_GIC_REDIST2] = { 0x0, 64 * MiB },
124
+ [VIRT_HIGH_PCIE_ECAM] = { 0x0, 256 * MiB },
125
+ /* Second PCIe window */
126
+ [VIRT_HIGH_PCIE_MMIO] = { 0x0, 512 * GiB },
127
};
128
129
static const int a15irqmap[] = {
130
@@ -XXX,XX +XXX,XX @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
131
return arm_cpu_mp_affinity(idx, clustersz);
132
}
133
134
+static void virt_set_memmap(VirtMachineState *vms)
135
+{
136
+ hwaddr base;
137
+ int i;
138
+
139
+ vms->memmap = extended_memmap;
140
+
141
+ for (i = 0; i < ARRAY_SIZE(base_memmap); i++) {
142
+ vms->memmap[i] = base_memmap[i];
143
+ }
144
+
145
+ base = 256 * GiB; /* Top of the legacy initial RAM region */
146
+
147
+ for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) {
148
+ hwaddr size = extended_memmap[i].size;
149
+
150
+ base = ROUND_UP(base, size);
151
+ vms->memmap[i].base = base;
152
+ vms->memmap[i].size = size;
153
+ base += size;
154
+ }
155
+}
156
+
157
static void machvirt_init(MachineState *machine)
31
{
158
{
32
MemoryRegionSection *section;
159
VirtMachineState *vms = VIRT_MACHINE(machine);
33
hwaddr page_mask = (hwaddr)-1;
160
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
161
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
35
return address_space_translate_iommu(iommu_mr, xlat,
162
bool aarch64 = true;
36
plen_out, page_mask_out,
163
37
is_write, is_mmio,
164
+ virt_set_memmap(vms);
38
- target_as);
165
+
39
+ target_as, attrs);
166
/* We can probe only here because during property set
40
}
167
* KVM is not available yet
41
if (page_mask_out) {
168
*/
42
/* Not behind an IOMMU, use default page size. */
169
@@ -XXX,XX +XXX,XX @@ static void virt_instance_init(Object *obj)
43
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate_cached(
170
"Valid values are none and smmuv3",
44
171
NULL);
45
section = address_space_translate_iommu(iommu_mr, xlat, plen,
172
46
NULL, is_write, true,
173
- vms->memmap = a15memmap;
47
- &target_as);
174
vms->irqmap = a15irqmap;
48
+ &target_as, attrs);
49
return section.mr;
50
}
175
}
51
176
52
--
177
--
53
2.17.1
178
2.20.1
54
179
55
180
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Eric Auger <eric.auger@redhat.com>
2
add MemTxAttrs as an argument to address_space_access_valid().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
2
3
On ARM, the kvm_type will be resolved by querying the KVMState.
4
Let's add the MachineState handle to the callback so that we
5
can retrieve the KVMState handle. in kvm_init, when the callback
6
is called, the kvm_state variable is not yet set.
7
8
Signed-off-by: Eric Auger <eric.auger@redhat.com>
9
Acked-by: David Gibson <david@gibson.dropbear.id.au>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
12
Message-id: 20190304101339.25970-5-eric.auger@redhat.com
13
[ppc parts]
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-6-peter.maydell@linaro.org
10
---
17
---
11
include/exec/memory.h | 4 +++-
18
include/hw/boards.h | 5 ++++-
12
include/sysemu/dma.h | 3 ++-
19
accel/kvm/kvm-all.c | 2 +-
13
exec.c | 3 ++-
20
hw/ppc/mac_newworld.c | 3 +--
14
target/s390x/diag.c | 6 ++++--
21
hw/ppc/mac_oldworld.c | 2 +-
15
target/s390x/excp_helper.c | 3 ++-
22
hw/ppc/spapr.c | 2 +-
16
target/s390x/mmu_helper.c | 3 ++-
23
5 files changed, 8 insertions(+), 6 deletions(-)
17
target/s390x/sigp.c | 3 ++-
18
7 files changed, 17 insertions(+), 8 deletions(-)
19
24
20
diff --git a/include/exec/memory.h b/include/exec/memory.h
25
diff --git a/include/hw/boards.h b/include/hw/boards.h
21
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
22
--- a/include/exec/memory.h
27
--- a/include/hw/boards.h
23
+++ b/include/exec/memory.h
28
+++ b/include/hw/boards.h
24
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
29
@@ -XXX,XX +XXX,XX @@ typedef struct {
25
* @addr: address within that address space
30
* should instead use "unimplemented-device" for all memory ranges where
26
* @len: length of the area to be checked
31
* the guest will attempt to probe for a device that QEMU doesn't
27
* @is_write: indicates the transfer direction
32
* implement and a stub device is required.
28
+ * @attrs: memory attributes
33
+ * @kvm_type:
34
+ * Return the type of KVM corresponding to the kvm-type string option or
35
+ * computed based on other criteria such as the host kernel capabilities.
29
*/
36
*/
30
-bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write);
37
struct MachineClass {
31
+bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len,
38
/*< private >*/
32
+ bool is_write, MemTxAttrs attrs);
39
@@ -XXX,XX +XXX,XX @@ struct MachineClass {
33
40
void (*init)(MachineState *state);
34
/* address_space_map: map a physical memory region into a host virtual address
41
void (*reset)(void);
35
*
42
void (*hot_add_cpu)(const int64_t id, Error **errp);
36
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
43
- int (*kvm_type)(const char *arg);
44
+ int (*kvm_type)(MachineState *machine, const char *arg);
45
46
BlockInterfaceType block_default_type;
47
int units_per_default_bus;
48
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
37
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
38
--- a/include/sysemu/dma.h
50
--- a/accel/kvm/kvm-all.c
39
+++ b/include/sysemu/dma.h
51
+++ b/accel/kvm/kvm-all.c
40
@@ -XXX,XX +XXX,XX @@ static inline bool dma_memory_valid(AddressSpace *as,
52
@@ -XXX,XX +XXX,XX @@ static int kvm_init(MachineState *ms)
41
DMADirection dir)
53
54
kvm_type = qemu_opt_get(qemu_get_machine_opts(), "kvm-type");
55
if (mc->kvm_type) {
56
- type = mc->kvm_type(kvm_type);
57
+ type = mc->kvm_type(ms, kvm_type);
58
} else if (kvm_type) {
59
ret = -EINVAL;
60
fprintf(stderr, "Invalid argument kvm-type=%s\n", kvm_type);
61
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/ppc/mac_newworld.c
64
+++ b/hw/ppc/mac_newworld.c
65
@@ -XXX,XX +XXX,XX @@ static char *core99_fw_dev_path(FWPathProvider *p, BusState *bus,
66
67
return NULL;
68
}
69
-
70
-static int core99_kvm_type(const char *arg)
71
+static int core99_kvm_type(MachineState *machine, const char *arg)
42
{
72
{
43
return address_space_access_valid(as, addr, len,
73
/* Always force PR KVM */
44
- dir == DMA_DIRECTION_FROM_DEVICE);
74
return 2;
45
+ dir == DMA_DIRECTION_FROM_DEVICE,
75
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
46
+ MEMTXATTRS_UNSPECIFIED);
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/ppc/mac_oldworld.c
78
+++ b/hw/ppc/mac_oldworld.c
79
@@ -XXX,XX +XXX,XX @@ static char *heathrow_fw_dev_path(FWPathProvider *p, BusState *bus,
80
return NULL;
47
}
81
}
48
82
49
static inline int dma_memory_rw_relaxed(AddressSpace *as, dma_addr_t addr,
83
-static int heathrow_kvm_type(const char *arg)
50
diff --git a/exec.c b/exec.c
84
+static int heathrow_kvm_type(MachineState *machine, const char *arg)
85
{
86
/* Always force PR KVM */
87
return 2;
88
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
51
index XXXXXXX..XXXXXXX 100644
89
index XXXXXXX..XXXXXXX 100644
52
--- a/exec.c
90
--- a/hw/ppc/spapr.c
53
+++ b/exec.c
91
+++ b/hw/ppc/spapr.c
54
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
92
@@ -XXX,XX +XXX,XX @@ static void spapr_machine_init(MachineState *machine)
93
}
55
}
94
}
56
95
57
bool address_space_access_valid(AddressSpace *as, hwaddr addr,
96
-static int spapr_kvm_type(const char *vm_type)
58
- int len, bool is_write)
97
+static int spapr_kvm_type(MachineState *machine, const char *vm_type)
59
+ int len, bool is_write,
60
+ MemTxAttrs attrs)
61
{
98
{
62
FlatView *fv;
99
if (!vm_type) {
63
bool result;
100
return 0;
64
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/s390x/diag.c
67
+++ b/target/s390x/diag.c
68
@@ -XXX,XX +XXX,XX @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
69
return;
70
}
71
if (!address_space_access_valid(&address_space_memory, addr,
72
- sizeof(IplParameterBlock), false)) {
73
+ sizeof(IplParameterBlock), false,
74
+ MEMTXATTRS_UNSPECIFIED)) {
75
s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
76
return;
77
}
78
@@ -XXX,XX +XXX,XX @@ out:
79
return;
80
}
81
if (!address_space_access_valid(&address_space_memory, addr,
82
- sizeof(IplParameterBlock), true)) {
83
+ sizeof(IplParameterBlock), true,
84
+ MEMTXATTRS_UNSPECIFIED)) {
85
s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
86
return;
87
}
88
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/s390x/excp_helper.c
91
+++ b/target/s390x/excp_helper.c
92
@@ -XXX,XX +XXX,XX @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr, int size,
93
94
/* check out of RAM access */
95
if (!address_space_access_valid(&address_space_memory, raddr,
96
- TARGET_PAGE_SIZE, rw)) {
97
+ TARGET_PAGE_SIZE, rw,
98
+ MEMTXATTRS_UNSPECIFIED)) {
99
DPRINTF("%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n", __func__,
100
(uint64_t)raddr, (uint64_t)ram_size);
101
trigger_pgm_exception(env, PGM_ADDRESSING, ILEN_AUTO);
102
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/s390x/mmu_helper.c
105
+++ b/target/s390x/mmu_helper.c
106
@@ -XXX,XX +XXX,XX @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
107
return ret;
108
}
109
if (!address_space_access_valid(&address_space_memory, pages[i],
110
- TARGET_PAGE_SIZE, is_write)) {
111
+ TARGET_PAGE_SIZE, is_write,
112
+ MEMTXATTRS_UNSPECIFIED)) {
113
trigger_access_exception(env, PGM_ADDRESSING, ILEN_AUTO, 0);
114
return -EFAULT;
115
}
116
diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/s390x/sigp.c
119
+++ b/target/s390x/sigp.c
120
@@ -XXX,XX +XXX,XX @@ static void sigp_set_prefix(CPUState *cs, run_on_cpu_data arg)
121
cpu_synchronize_state(cs);
122
123
if (!address_space_access_valid(&address_space_memory, addr,
124
- sizeof(struct LowCore), false)) {
125
+ sizeof(struct LowCore), false,
126
+ MEMTXATTRS_UNSPECIFIED)) {
127
set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
128
return;
129
}
130
--
101
--
131
2.17.1
102
2.20.1
132
103
133
104
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Eric Auger <eric.auger@redhat.com>
2
add MemTxAttrs as an argument to flatview_access_valid().
3
Its callers now all have an attrs value to hand, so we can
4
correct our earlier temporary use of MEMTXATTRS_UNSPECIFIED.
5
2
3
Add the kvm_arm_get_max_vm_ipa_size() helper that returns the
4
number of bits in the IPA address space supported by KVM.
5
6
This capability needs to be known to create the VM with a
7
specific IPA max size (kvm_type passed along KVM_CREATE_VM ioctl.
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
11
Message-id: 20190304101339.25970-6-eric.auger@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-10-peter.maydell@linaro.org
10
---
13
---
11
exec.c | 12 +++++-------
14
target/arm/kvm_arm.h | 13 +++++++++++++
12
1 file changed, 5 insertions(+), 7 deletions(-)
15
target/arm/kvm.c | 10 ++++++++++
16
2 files changed, 23 insertions(+)
13
17
14
diff --git a/exec.c b/exec.c
18
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/exec.c
20
--- a/target/arm/kvm_arm.h
17
+++ b/exec.c
21
+++ b/target/arm/kvm_arm.h
18
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
22
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf);
19
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
23
*/
20
const uint8_t *buf, int len);
24
void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
21
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
25
22
- bool is_write);
26
+/**
23
+ bool is_write, MemTxAttrs attrs);
27
+ * kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the
24
28
+ * IPA address space supported by KVM
25
static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
29
+ *
26
unsigned len, MemTxAttrs attrs)
30
+ * @ms: Machine state handle
27
@@ -XXX,XX +XXX,XX @@ static bool subpage_accepts(void *opaque, hwaddr addr,
31
+ */
28
#endif
32
+int kvm_arm_get_max_vm_ipa_size(MachineState *ms);
29
33
+
30
return flatview_access_valid(subpage->fv, addr + subpage->base,
34
/**
31
- len, is_write);
35
* kvm_arm_sync_mpstate_to_kvm
32
+ len, is_write, attrs);
36
* @cpu: ARMCPU
37
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
38
cpu->host_cpu_probe_failed = true;
33
}
39
}
34
40
35
static const MemoryRegionOps subpage_ops = {
41
+static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
36
@@ -XXX,XX +XXX,XX @@ static void cpu_notify_map_clients(void)
42
+{
43
+ return -ENOENT;
44
+}
45
+
46
static inline int kvm_arm_vgic_probe(void)
47
{
48
return 0;
49
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/kvm.c
52
+++ b/target/arm/kvm.c
53
@@ -XXX,XX +XXX,XX @@
54
#include "qemu/error-report.h"
55
#include "sysemu/sysemu.h"
56
#include "sysemu/kvm.h"
57
+#include "sysemu/kvm_int.h"
58
#include "kvm_arm.h"
59
#include "cpu.h"
60
#include "trace.h"
61
@@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
62
env->features = arm_host_cpu_features.features;
37
}
63
}
38
64
39
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
65
+int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
40
- bool is_write)
66
+{
41
+ bool is_write, MemTxAttrs attrs)
67
+ KVMState *s = KVM_STATE(ms->accelerator);
68
+ int ret;
69
+
70
+ ret = kvm_check_extension(s, KVM_CAP_ARM_VM_IPA_SIZE);
71
+ return ret > 0 ? ret : 40;
72
+}
73
+
74
int kvm_arch_init(MachineState *ms, KVMState *s)
42
{
75
{
43
MemoryRegion *mr;
76
/* For ARM interrupt delivery is always asynchronous,
44
hwaddr l, xlat;
45
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
46
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
47
if (!memory_access_is_direct(mr, is_write)) {
48
l = memory_access_size(mr, l, addr);
49
- /* When our callers all have attrs we'll pass them through here */
50
- if (!memory_region_access_valid(mr, xlat, l, is_write,
51
- MEMTXATTRS_UNSPECIFIED)) {
52
+ if (!memory_region_access_valid(mr, xlat, l, is_write, attrs)) {
53
return false;
54
}
55
}
56
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr,
57
58
rcu_read_lock();
59
fv = address_space_to_flatview(as);
60
- result = flatview_access_valid(fv, addr, len, is_write);
61
+ result = flatview_access_valid(fv, addr, len, is_write, attrs);
62
rcu_read_unlock();
63
return result;
64
}
65
--
77
--
66
2.17.1
78
2.20.1
67
79
68
80
diff view generated by jsdifflib
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
kvm_irqchip_create called by kvm_init will call kvm_init_irq_routing to
3
The machine RAM attributes will need to be analyzed during the
4
initialize global capability variables. If we call kvm_init_irq_routing in
4
configure_accelerator() process. especially kvm_type() arm64
5
GIC realize function, previous allocated memory will leak.
5
machine callback will use them to know how many IPA/GPA bits are
6
needed to model the whole RAM range. So let's assign those machine
7
state fields before calling configure_accelerator.
6
8
7
Fix this by deleting the unnecessary call.
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
8
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
11
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
Message-id: 20190304101339.25970-7-eric.auger@redhat.com
11
Message-id: 1527750994-14360-1-git-send-email-zhaoshenglong@huawei.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
---
14
hw/intc/arm_gic_kvm.c | 1 -
15
vl.c | 6 +++---
15
hw/intc/arm_gicv3_kvm.c | 1 -
16
1 file changed, 3 insertions(+), 3 deletions(-)
16
2 files changed, 2 deletions(-)
17
17
18
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
18
diff --git a/vl.c b/vl.c
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/arm_gic_kvm.c
20
--- a/vl.c
21
+++ b/hw/intc/arm_gic_kvm.c
21
+++ b/vl.c
22
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
22
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
23
23
machine_opts = qemu_get_machine_opts();
24
if (kvm_has_gsi_routing()) {
24
qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
25
/* set up irq routing */
25
&error_fatal);
26
- kvm_init_irq_routing(kvm_state);
26
+ current_machine->ram_size = ram_size;
27
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
27
+ current_machine->maxram_size = maxram_size;
28
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
28
+ current_machine->ram_slots = ram_slots;
29
}
29
30
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
30
configure_accelerator(current_machine, argv[0]);
31
index XXXXXXX..XXXXXXX 100644
31
32
--- a/hw/intc/arm_gicv3_kvm.c
32
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
33
+++ b/hw/intc/arm_gicv3_kvm.c
33
replay_checkpoint(CHECKPOINT_INIT);
34
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
34
qdev_machine_init();
35
35
36
if (kvm_has_gsi_routing()) {
36
- current_machine->ram_size = ram_size;
37
/* set up irq routing */
37
- current_machine->maxram_size = maxram_size;
38
- kvm_init_irq_routing(kvm_state);
38
- current_machine->ram_slots = ram_slots;
39
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
39
current_machine->boot_order = boot_order;
40
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
40
41
}
41
/* parse features once if machine provides default cpu_type */
42
--
42
--
43
2.17.1
43
2.20.1
44
44
45
45
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Eric Auger <eric.auger@redhat.com>
2
add MemTxAttrs as an argument to flatview_translate(); all its
3
callers now have attrs available.
4
2
3
Up to now the memory map has been static and the high IO region
4
base has always been 256GiB.
5
6
This patch modifies the virt_set_memmap() function, which freezes
7
the memory map, so that the high IO range base becomes floating,
8
located after the initial RAM and the device memory.
9
10
The function computes
11
- the base of the device memory,
12
- the size of the device memory,
13
- the high IO region base
14
- the highest GPA used in the memory map.
15
16
Entries of the high IO region are assigned a base address. The
17
device memory is initialized.
18
19
The highest GPA used in the memory map will be used at VM creation
20
to choose the requested IPA size.
21
22
Setting all the existing highmem IO regions beyond the RAM
23
allows to have a single contiguous RAM region (initial RAM and
24
possible hotpluggable device memory). That way we do not need
25
to do invasive changes in the EDK2 FW to support a dynamic
26
RAM base.
27
28
Still the user cannot request an initial RAM size greater than 255GB.
29
30
Signed-off-by: Eric Auger <eric.auger@redhat.com>
31
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
32
Message-id: 20190304101339.25970-8-eric.auger@redhat.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180521140402.23318-11-peter.maydell@linaro.org
9
---
34
---
10
include/exec/memory.h | 7 ++++---
35
include/hw/arm/virt.h | 1 +
11
exec.c | 17 +++++++++--------
36
hw/arm/virt.c | 52 ++++++++++++++++++++++++++++++++++++++-----
12
2 files changed, 13 insertions(+), 11 deletions(-)
37
2 files changed, 47 insertions(+), 6 deletions(-)
13
38
14
diff --git a/include/exec/memory.h b/include/exec/memory.h
39
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
15
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/memory.h
41
--- a/include/hw/arm/virt.h
17
+++ b/include/exec/memory.h
42
+++ b/include/hw/arm/virt.h
18
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
43
@@ -XXX,XX +XXX,XX @@ typedef struct {
44
uint32_t msi_phandle;
45
uint32_t iommu_phandle;
46
int psci_conduit;
47
+ hwaddr highest_gpa;
48
} VirtMachineState;
49
50
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
51
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/arm/virt.c
54
+++ b/hw/arm/virt.c
55
@@ -XXX,XX +XXX,XX @@
56
#include "qapi/visitor.h"
57
#include "standard-headers/linux/input.h"
58
#include "hw/arm/smmuv3.h"
59
+#include "hw/acpi/acpi.h"
60
61
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
62
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
63
@@ -XXX,XX +XXX,XX @@
64
* of a terabyte of RAM will be doing it on a host with more than a
65
* terabyte of physical address space.)
19
*/
66
*/
20
MemoryRegion *flatview_translate(FlatView *fv,
67
-#define RAMLIMIT_GB 255
21
hwaddr addr, hwaddr *xlat,
68
-#define RAMLIMIT_BYTES (RAMLIMIT_GB * 1024ULL * 1024 * 1024)
22
- hwaddr *len, bool is_write);
69
+#define LEGACY_RAMLIMIT_GB 255
23
+ hwaddr *len, bool is_write,
70
+#define LEGACY_RAMLIMIT_BYTES (LEGACY_RAMLIMIT_GB * GiB)
24
+ MemTxAttrs attrs);
71
25
72
/* Addresses and sizes of our components.
26
static inline MemoryRegion *address_space_translate(AddressSpace *as,
73
* 0..128MB is space for a flash device so we can run bootrom code such as UEFI.
27
hwaddr addr, hwaddr *xlat,
74
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry base_memmap[] = {
28
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
75
[VIRT_PCIE_MMIO] = { 0x10000000, 0x2eff0000 },
29
MemTxAttrs attrs)
76
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
77
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
78
- [VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
79
+ /* Actual RAM size depends on initial RAM and device memory settings */
80
+ [VIRT_MEM] = { GiB, LEGACY_RAMLIMIT_BYTES },
81
};
82
83
/*
84
@@ -XXX,XX +XXX,XX @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
85
86
static void virt_set_memmap(VirtMachineState *vms)
30
{
87
{
31
return flatview_translate(address_space_to_flatview(as),
88
- hwaddr base;
32
- addr, xlat, len, is_write);
89
+ MachineState *ms = MACHINE(vms);
33
+ addr, xlat, len, is_write, attrs);
90
+ hwaddr base, device_memory_base, device_memory_size;
91
int i;
92
93
vms->memmap = extended_memmap;
94
@@ -XXX,XX +XXX,XX @@ static void virt_set_memmap(VirtMachineState *vms)
95
vms->memmap[i] = base_memmap[i];
96
}
97
98
- base = 256 * GiB; /* Top of the legacy initial RAM region */
99
+ if (ms->ram_slots > ACPI_MAX_RAM_SLOTS) {
100
+ error_report("unsupported number of memory slots: %"PRIu64,
101
+ ms->ram_slots);
102
+ exit(EXIT_FAILURE);
103
+ }
104
+
105
+ /*
106
+ * We compute the base of the high IO region depending on the
107
+ * amount of initial and device memory. The device memory start/size
108
+ * is aligned on 1GiB. We never put the high IO region below 256GiB
109
+ * so that if maxram_size is < 255GiB we keep the legacy memory map.
110
+ * The device region size assumes 1GiB page max alignment per slot.
111
+ */
112
+ device_memory_base =
113
+ ROUND_UP(vms->memmap[VIRT_MEM].base + ms->ram_size, GiB);
114
+ device_memory_size = ms->maxram_size - ms->ram_size + ms->ram_slots * GiB;
115
+
116
+ /* Base address of the high IO region */
117
+ base = device_memory_base + ROUND_UP(device_memory_size, GiB);
118
+ if (base < device_memory_base) {
119
+ error_report("maxmem/slots too huge");
120
+ exit(EXIT_FAILURE);
121
+ }
122
+ if (base < vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES) {
123
+ base = vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES;
124
+ }
125
126
for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) {
127
hwaddr size = extended_memmap[i].size;
128
@@ -XXX,XX +XXX,XX @@ static void virt_set_memmap(VirtMachineState *vms)
129
vms->memmap[i].size = size;
130
base += size;
131
}
132
+ vms->highest_gpa = base - 1;
133
+ if (device_memory_size > 0) {
134
+ ms->device_memory = g_malloc0(sizeof(*ms->device_memory));
135
+ ms->device_memory->base = device_memory_base;
136
+ memory_region_init(&ms->device_memory->mr, OBJECT(vms),
137
+ "device-memory", device_memory_size);
138
+ }
34
}
139
}
35
140
36
/* address_space_access_valid: check for validity of accessing an address
141
static void machvirt_init(MachineState *machine)
37
@@ -XXX,XX +XXX,XX @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
142
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
38
rcu_read_lock();
143
vms->smp_cpus = smp_cpus;
39
fv = address_space_to_flatview(as);
144
40
l = len;
145
if (machine->ram_size > vms->memmap[VIRT_MEM].size) {
41
- mr = flatview_translate(fv, addr, &addr1, &l, false);
146
- error_report("mach-virt: cannot model more than %dGB RAM", RAMLIMIT_GB);
42
+ mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
147
+ error_report("mach-virt: cannot model more than %dGB RAM",
43
if (len == l && memory_access_is_direct(mr, false)) {
148
+ LEGACY_RAMLIMIT_GB);
44
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
149
exit(1);
45
memcpy(buf, ptr, len);
46
diff --git a/exec.c b/exec.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/exec.c
49
+++ b/exec.c
50
@@ -XXX,XX +XXX,XX @@ iotlb_fail:
51
52
/* Called from RCU critical section */
53
MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
54
- hwaddr *plen, bool is_write)
55
+ hwaddr *plen, bool is_write,
56
+ MemTxAttrs attrs)
57
{
58
MemoryRegion *mr;
59
MemoryRegionSection section;
60
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
61
}
62
63
l = len;
64
- mr = flatview_translate(fv, addr, &addr1, &l, true);
65
+ mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
66
}
150
}
67
151
68
return result;
152
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
69
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
153
memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
70
MemTxResult result = MEMTX_OK;
154
machine->ram_size);
71
155
memory_region_add_subregion(sysmem, vms->memmap[VIRT_MEM].base, ram);
72
l = len;
156
+ if (machine->device_memory) {
73
- mr = flatview_translate(fv, addr, &addr1, &l, true);
157
+ memory_region_add_subregion(sysmem, machine->device_memory->base,
74
+ mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
158
+ &machine->device_memory->mr);
75
result = flatview_write_continue(fv, addr, attrs, buf, len,
159
+ }
76
addr1, l, mr);
160
77
161
create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
78
@@ -XXX,XX +XXX,XX @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
162
79
}
80
81
l = len;
82
- mr = flatview_translate(fv, addr, &addr1, &l, false);
83
+ mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
84
}
85
86
return result;
87
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
88
MemoryRegion *mr;
89
90
l = len;
91
- mr = flatview_translate(fv, addr, &addr1, &l, false);
92
+ mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
93
return flatview_read_continue(fv, addr, attrs, buf, len,
94
addr1, l, mr);
95
}
96
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
97
98
while (len > 0) {
99
l = len;
100
- mr = flatview_translate(fv, addr, &xlat, &l, is_write);
101
+ mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
102
if (!memory_access_is_direct(mr, is_write)) {
103
l = memory_access_size(mr, l, addr);
104
if (!memory_region_access_valid(mr, xlat, l, is_write, attrs)) {
105
@@ -XXX,XX +XXX,XX @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
106
107
len = target_len;
108
this_mr = flatview_translate(fv, addr, &xlat,
109
- &len, is_write);
110
+ &len, is_write, attrs);
111
if (this_mr != mr || xlat != base + done) {
112
return done;
113
}
114
@@ -XXX,XX +XXX,XX @@ void *address_space_map(AddressSpace *as,
115
l = len;
116
rcu_read_lock();
117
fv = address_space_to_flatview(as);
118
- mr = flatview_translate(fv, addr, &xlat, &l, is_write);
119
+ mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
120
121
if (!memory_access_is_direct(mr, is_write)) {
122
if (atomic_xchg(&bounce.in_use, true)) {
123
--
163
--
124
2.17.1
164
2.20.1
125
165
126
166
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Eric Auger <eric.auger@redhat.com>
2
add MemTxAttrs as an argument to flatview_do_translate().
3
2
3
This patch implements the machine class kvm_type() callback.
4
It returns the number of bits requested to implement the whole GPA
5
range including the RAM and IO regions located beyond.
6
The returned value is passed though the KVM_CREATE_VM ioctl and
7
this allows KVM to set the stage2 tables dynamically.
8
9
To compute the highest GPA used in the memory map, kvm_type()
10
must freeze the memory map by calling virt_set_memmap().
11
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
14
Message-id: 20190304101339.25970-9-eric.auger@redhat.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180521140402.23318-13-peter.maydell@linaro.org
8
---
16
---
9
exec.c | 9 ++++++---
17
hw/arm/virt.c | 39 ++++++++++++++++++++++++++++++++++++++-
10
1 file changed, 6 insertions(+), 3 deletions(-)
18
1 file changed, 38 insertions(+), 1 deletion(-)
11
19
12
diff --git a/exec.c b/exec.c
20
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
13
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
14
--- a/exec.c
22
--- a/hw/arm/virt.c
15
+++ b/exec.c
23
+++ b/hw/arm/virt.c
16
@@ -XXX,XX +XXX,XX @@ unassigned:
24
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
17
* @is_write: whether the translation operation is for write
25
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
18
* @is_mmio: whether this can be MMIO, set true if it can
26
bool aarch64 = true;
19
* @target_as: the address space targeted by the IOMMU
27
20
+ * @attrs: memory transaction attributes
28
- virt_set_memmap(vms);
21
*
29
+ /*
22
* This function is called from RCU critical section
30
+ * In accelerated mode, the memory map is computed earlier in kvm_type()
23
*/
31
+ * to create a VM with the right number of IPA bits.
24
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
32
+ */
25
hwaddr *page_mask_out,
33
+ if (!vms->memmap) {
26
bool is_write,
34
+ virt_set_memmap(vms);
27
bool is_mmio,
35
+ }
28
- AddressSpace **target_as)
36
29
+ AddressSpace **target_as,
37
/* We can probe only here because during property set
30
+ MemTxAttrs attrs)
38
* KVM is not available yet
39
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
40
return NULL;
41
}
42
43
+/*
44
+ * for arm64 kvm_type [7-0] encodes the requested number of bits
45
+ * in the IPA address space
46
+ */
47
+static int virt_kvm_type(MachineState *ms, const char *type_str)
48
+{
49
+ VirtMachineState *vms = VIRT_MACHINE(ms);
50
+ int max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms);
51
+ int requested_pa_size;
52
+
53
+ /* we freeze the memory map to compute the highest gpa */
54
+ virt_set_memmap(vms);
55
+
56
+ requested_pa_size = 64 - clz64(vms->highest_gpa);
57
+
58
+ if (requested_pa_size > max_vm_pa_size) {
59
+ error_report("-m and ,maxmem option values "
60
+ "require an IPA range (%d bits) larger than "
61
+ "the one supported by the host (%d bits)",
62
+ requested_pa_size, max_vm_pa_size);
63
+ exit(1);
64
+ }
65
+ /*
66
+ * By default we return 0 which corresponds to an implicit legacy
67
+ * 40b IPA setting. Otherwise we return the actual requested PA
68
+ * logsize
69
+ */
70
+ return requested_pa_size > 40 ? requested_pa_size : 0;
71
+}
72
+
73
static void virt_machine_class_init(ObjectClass *oc, void *data)
31
{
74
{
32
MemoryRegionSection *section;
75
MachineClass *mc = MACHINE_CLASS(oc);
33
IOMMUMemoryRegion *iommu_mr;
76
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
34
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
77
mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
35
* but page mask.
78
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
36
*/
79
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
37
section = flatview_do_translate(address_space_to_flatview(as), addr, &xlat,
80
+ mc->kvm_type = virt_kvm_type;
38
- NULL, &page_mask, is_write, false, &as);
81
assert(!mc->get_hotplug_handler);
39
+ NULL, &page_mask, is_write, false, &as,
82
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
40
+ attrs);
83
hc->plug = virt_machine_device_plug_cb;
41
42
/* Illegal translation */
43
if (section.mr == &io_mem_unassigned) {
44
@@ -XXX,XX +XXX,XX @@ MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
45
46
/* This can be MMIO, so setup MMIO bit. */
47
section = flatview_do_translate(fv, addr, xlat, plen, NULL,
48
- is_write, true, &as);
49
+ is_write, true, &as, attrs);
50
mr = section.mr;
51
52
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
53
--
84
--
54
2.17.1
85
2.20.1
55
86
56
87
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Eric Auger <eric.auger@redhat.com>
2
add MemTxAttrs as an argument to address_space_get_iotlb_entry().
3
2
3
We are about to allow the memory map to grow beyond 1TB and
4
potentially overshoot the VCPU AA64MMFR0.PARANGE.
5
6
In aarch64 mode and when highmem is set, let's check the VCPU
7
PA range is sufficient to address the highest GPA of the memory
8
map.
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
12
Message-id: 20190304101339.25970-10-eric.auger@redhat.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180521140402.23318-12-peter.maydell@linaro.org
8
---
14
---
9
include/exec/memory.h | 2 +-
15
hw/arm/virt.c | 17 +++++++++++++++++
10
exec.c | 2 +-
16
1 file changed, 17 insertions(+)
11
hw/virtio/vhost.c | 3 ++-
12
3 files changed, 4 insertions(+), 3 deletions(-)
13
17
14
diff --git a/include/exec/memory.h b/include/exec/memory.h
18
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/memory.h
20
--- a/hw/arm/virt.c
17
+++ b/include/exec/memory.h
21
+++ b/hw/arm/virt.c
18
@@ -XXX,XX +XXX,XX @@ void address_space_cache_destroy(MemoryRegionCache *cache);
22
@@ -XXX,XX +XXX,XX @@
19
* entry. Should be called from an RCU critical section.
23
#include "standard-headers/linux/input.h"
20
*/
24
#include "hw/arm/smmuv3.h"
21
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
25
#include "hw/acpi/acpi.h"
22
- bool is_write);
26
+#include "target/arm/internals.h"
23
+ bool is_write, MemTxAttrs attrs);
27
24
28
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
25
/* address_space_translate: translate an address range into an address space
29
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
26
* into a MemoryRegion and an address range into that section. Should be
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
27
diff --git a/exec.c b/exec.c
31
fdt_add_timer_nodes(vms);
28
index XXXXXXX..XXXXXXX 100644
32
fdt_add_cpu_nodes(vms);
29
--- a/exec.c
33
30
+++ b/exec.c
34
+ if (!kvm_enabled()) {
31
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
35
+ ARMCPU *cpu = ARM_CPU(first_cpu);
32
36
+ bool aarch64 = object_property_get_bool(OBJECT(cpu), "aarch64", NULL);
33
/* Called from RCU critical section */
37
+
34
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
38
+ if (aarch64 && vms->highmem) {
35
- bool is_write)
39
+ int requested_pa_size, pamax = arm_pamax(cpu);
36
+ bool is_write, MemTxAttrs attrs)
40
+
37
{
41
+ requested_pa_size = 64 - clz64(vms->highest_gpa);
38
MemoryRegionSection section;
42
+ if (pamax < requested_pa_size) {
39
hwaddr xlat, page_mask;
43
+ error_report("VCPU supports less PA bits (%d) than requested "
40
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
44
+ "by the memory map (%d)", pamax, requested_pa_size);
41
index XXXXXXX..XXXXXXX 100644
45
+ exit(1);
42
--- a/hw/virtio/vhost.c
46
+ }
43
+++ b/hw/virtio/vhost.c
47
+ }
44
@@ -XXX,XX +XXX,XX @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
48
+ }
45
trace_vhost_iotlb_miss(dev, 1);
49
+
46
50
memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
47
iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as,
51
machine->ram_size);
48
- iova, write);
52
memory_region_add_subregion(sysmem, vms->memmap[VIRT_MEM].base, ram);
49
+ iova, write,
50
+ MEMTXATTRS_UNSPECIFIED);
51
if (iotlb.target_as != NULL) {
52
ret = vhost_memory_region_lookup(dev, iotlb.translated_addr,
53
&uaddr, &len);
54
--
53
--
55
2.17.1
54
2.20.1
56
55
57
56
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
cpregs_keys is an uint32_t* so the allocation should use uint32_t.
3
Now we have the extended memory map (high IO regions beyond the
4
g_new is even better because it is type-safe.
4
scalable RAM) and dynamic IPA range support at KVM/ARM level
5
we can bump the legacy 255GB initial RAM limit. The actual maximum
6
RAM size now depends on the physical CPU and host kernel, in
7
accelerated mode. In TCG mode, it depends on the VCPU
8
AA64MMFR0.PARANGE.
5
9
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20190304101339.25970-11-eric.auger@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/gdbstub.c | 3 +--
15
hw/arm/virt.c | 21 +--------------------
12
1 file changed, 1 insertion(+), 2 deletions(-)
16
1 file changed, 1 insertion(+), 20 deletions(-)
13
17
14
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
18
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/gdbstub.c
20
--- a/hw/arm/virt.c
17
+++ b/target/arm/gdbstub.c
21
+++ b/hw/arm/virt.c
18
@@ -XXX,XX +XXX,XX @@ int arm_gen_dynamic_xml(CPUState *cs)
22
@@ -XXX,XX +XXX,XX @@
19
RegisterSysregXmlParam param = {cs, s};
23
20
24
#define PLATFORM_BUS_NUM_IRQS 64
21
cpu->dyn_xml.num_cpregs = 0;
25
22
- cpu->dyn_xml.cpregs_keys = g_malloc(sizeof(uint32_t *) *
26
-/* RAM limit in GB. Since VIRT_MEM starts at the 1GB mark, this means
23
- g_hash_table_size(cpu->cp_regs));
27
- * RAM can go up to the 256GB mark, leaving 256GB of the physical
24
+ cpu->dyn_xml.cpregs_keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs));
28
- * address space unallocated and free for future use between 256G and 512G.
25
g_string_printf(s, "<?xml version=\"1.0\"?>");
29
- * If we need to provide more RAM to VMs in the future then we need to:
26
g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
30
- * * allocate a second bank of RAM starting at 2TB and working up
27
g_string_append_printf(s, "<feature name=\"org.qemu.gdb.arm.sys.regs\">");
31
- * * fix the DT and ACPI table generation code in QEMU to correctly
32
- * report two split lumps of RAM to the guest
33
- * * fix KVM in the host kernel to allow guests with >40 bit address spaces
34
- * (We don't want to fill all the way up to 512GB with RAM because
35
- * we might want it for non-RAM purposes later. Conversely it seems
36
- * reasonable to assume that anybody configuring a VM with a quarter
37
- * of a terabyte of RAM will be doing it on a host with more than a
38
- * terabyte of physical address space.)
39
- */
40
+/* Legacy RAM limit in GB (< version 4.0) */
41
#define LEGACY_RAMLIMIT_GB 255
42
#define LEGACY_RAMLIMIT_BYTES (LEGACY_RAMLIMIT_GB * GiB)
43
44
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
45
46
vms->smp_cpus = smp_cpus;
47
48
- if (machine->ram_size > vms->memmap[VIRT_MEM].size) {
49
- error_report("mach-virt: cannot model more than %dGB RAM",
50
- LEGACY_RAMLIMIT_GB);
51
- exit(1);
52
- }
53
-
54
if (vms->virt && kvm_enabled()) {
55
error_report("mach-virt: KVM does not support providing "
56
"Virtualization extensions to the guest CPU");
28
--
57
--
29
2.17.1
58
2.20.1
30
59
31
60
diff view generated by jsdifflib
1
Add more detail to the documentation for memory_region_init_iommu()
1
From: Michel Heily <michelheily@gmail.com>
2
and other IOMMU-related functions and data structures.
2
3
3
Implement the watchdog timer for the stellaris boards.
4
This device is a close variant of the CMSDK APB watchdog
5
device, so we can model it by subclassing that device and
6
tweaking the behaviour of some of its registers.
7
8
Signed-off-by: Michel Heily <michelheily@gmail.com>
9
Reviewed-by: Peter Maydell <petser.maydell@linaro.org>
10
[PMM: rewrote commit message, fixed a few checkpatch nits,
11
added comment giving the URL of the spec for the Stellaris
12
variant of the watchdog device]
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 20180521140402.23318-2-peter.maydell@linaro.org
9
---
14
---
10
include/exec/memory.h | 105 ++++++++++++++++++++++++++++++++++++++----
15
include/hw/watchdog/cmsdk-apb-watchdog.h | 8 +++
11
1 file changed, 95 insertions(+), 10 deletions(-)
16
hw/arm/stellaris.c | 22 ++++++-
12
17
hw/watchdog/cmsdk-apb-watchdog.c | 74 +++++++++++++++++++++++-
13
diff --git a/include/exec/memory.h b/include/exec/memory.h
18
3 files changed, 100 insertions(+), 4 deletions(-)
19
20
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/include/exec/memory.h
22
--- a/include/hw/watchdog/cmsdk-apb-watchdog.h
16
+++ b/include/exec/memory.h
23
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
17
@@ -XXX,XX +XXX,XX @@ enum IOMMUMemoryRegionAttr {
24
@@ -XXX,XX +XXX,XX @@
18
IOMMU_ATTR_SPAPR_TCE_FD
25
#define CMSDK_APB_WATCHDOG(obj) OBJECT_CHECK(CMSDKAPBWatchdog, (obj), \
26
TYPE_CMSDK_APB_WATCHDOG)
27
28
+/*
29
+ * This shares the same struct (and cast macro) as the base
30
+ * cmsdk-apb-watchdog device.
31
+ */
32
+#define TYPE_LUMINARY_WATCHDOG "luminary-watchdog"
33
+
34
typedef struct CMSDKAPBWatchdog {
35
/*< private >*/
36
SysBusDevice parent_obj;
37
@@ -XXX,XX +XXX,XX @@ typedef struct CMSDKAPBWatchdog {
38
MemoryRegion iomem;
39
qemu_irq wdogint;
40
uint32_t wdogclk_frq;
41
+ bool is_luminary;
42
struct ptimer_state *timer;
43
44
uint32_t control;
45
@@ -XXX,XX +XXX,XX @@ typedef struct CMSDKAPBWatchdog {
46
uint32_t itcr;
47
uint32_t itop;
48
uint32_t resetstatus;
49
+ const uint32_t *id;
50
} CMSDKAPBWatchdog;
51
52
#endif
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/stellaris.c
56
+++ b/hw/arm/stellaris.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "sysemu/sysemu.h"
59
#include "hw/arm/armv7m.h"
60
#include "hw/char/pl011.h"
61
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
62
#include "hw/misc/unimp.h"
63
#include "cpu.h"
64
65
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
66
* Stellaris LM3S6965 Microcontroller Data Sheet (rev I)
67
* http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
68
*
69
- * 40000000 wdtimer (unimplemented)
70
+ * 40000000 wdtimer
71
* 40002000 i2c (unimplemented)
72
* 40004000 GPIO
73
* 40005000 GPIO
74
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
75
stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
76
board, nd_table[0].macaddr.a);
77
78
+
79
+ if (board->dc1 & (1 << 3)) { /* watchdog present */
80
+ dev = qdev_create(NULL, TYPE_LUMINARY_WATCHDOG);
81
+
82
+ /* system_clock_scale is valid now */
83
+ uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
84
+ qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
85
+
86
+ qdev_init_nofail(dev);
87
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev),
88
+ 0,
89
+ 0x40000000u);
90
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev),
91
+ 0,
92
+ qdev_get_gpio_in(nvic, 18));
93
+ }
94
+
95
+
96
for (i = 0; i < 7; i++) {
97
if (board->dc4 & (1 << i)) {
98
gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
99
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
100
/* Add dummy regions for the devices we don't implement yet,
101
* so guest accesses don't cause unlogged crashes.
102
*/
103
- create_unimplemented_device("wdtimer", 0x40000000, 0x1000);
104
create_unimplemented_device("i2c-0", 0x40002000, 0x1000);
105
create_unimplemented_device("i2c-2", 0x40021000, 0x1000);
106
create_unimplemented_device("PWM", 0x40028000, 0x1000);
107
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/hw/watchdog/cmsdk-apb-watchdog.c
110
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
111
@@ -XXX,XX +XXX,XX @@
112
* System Design Kit (CMSDK) and documented in the Cortex-M System
113
* Design Kit Technical Reference Manual (ARM DDI0479C):
114
* https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
115
+ *
116
+ * We also support the variant of this device found in the TI
117
+ * Stellaris/Luminary boards and documented in:
118
+ * http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
119
*/
120
121
#include "qemu/osdep.h"
122
@@ -XXX,XX +XXX,XX @@ REG32(WDOGINTCLR, 0xc)
123
REG32(WDOGRIS, 0x10)
124
FIELD(WDOGRIS, INT, 0, 1)
125
REG32(WDOGMIS, 0x14)
126
+REG32(WDOGTEST, 0x418) /* only in Stellaris/Luminary version of the device */
127
REG32(WDOGLOCK, 0xc00)
128
#define WDOG_UNLOCK_VALUE 0x1ACCE551
129
REG32(WDOGITCR, 0xf00)
130
@@ -XXX,XX +XXX,XX @@ REG32(CID2, 0xff8)
131
REG32(CID3, 0xffc)
132
133
/* PID/CID values */
134
-static const int watchdog_id[] = {
135
+static const uint32_t cmsdk_apb_watchdog_id[] = {
136
0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
137
0x24, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
138
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
19
};
139
};
20
140
21
+/**
141
+static const uint32_t luminary_watchdog_id[] = {
22
+ * IOMMUMemoryRegionClass:
142
+ 0x00, 0x00, 0x00, 0x00, /* PID4..PID7 */
23
+ *
143
+ 0x05, 0x18, 0x18, 0x01, /* PID0..PID3 */
24
+ * All IOMMU implementations need to subclass TYPE_IOMMU_MEMORY_REGION
144
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
25
+ * and provide an implementation of at least the @translate method here
145
+};
26
+ * to handle requests to the memory region. Other methods are optional.
146
+
27
+ *
147
static bool cmsdk_apb_watchdog_intstatus(CMSDKAPBWatchdog *s)
28
+ * The IOMMU implementation must use the IOMMU notifier infrastructure
148
{
29
+ * to report whenever mappings are changed, by calling
149
/* Return masked interrupt status */
30
+ * memory_region_notify_iommu() (or, if necessary, by calling
150
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_update(CMSDKAPBWatchdog *s)
31
+ * memory_region_notify_one() for each registered notifier).
151
bool wdogres;
32
+ */
152
33
typedef struct IOMMUMemoryRegionClass {
153
if (s->itcr) {
34
/* private */
154
+ /*
35
struct DeviceClass parent_class;
155
+ * Not checking that !s->is_luminary since s->itcr can't be written
36
156
+ * when s->is_luminary in the first place.
37
/*
157
+ */
38
- * Return a TLB entry that contains a given address. Flag should
158
wdogint = s->itop & R_WDOGITOP_WDOGINT_MASK;
39
- * be the access permission of this translation operation. We can
159
wdogres = s->itop & R_WDOGITOP_WDOGRES_MASK;
40
- * set flag to IOMMU_NONE to mean that we don't need any
160
} else {
41
- * read/write permission checks, like, when for region replay.
161
@@ -XXX,XX +XXX,XX @@ static uint64_t cmsdk_apb_watchdog_read(void *opaque, hwaddr offset,
42
+ * Return a TLB entry that contains a given address.
162
r = s->lock;
43
+ *
163
break;
44
+ * The IOMMUAccessFlags indicated via @flag are optional and may
164
case A_WDOGITCR:
45
+ * be specified as IOMMU_NONE to indicate that the caller needs
165
+ if (s->is_luminary) {
46
+ * the full translation information for both reads and writes. If
166
+ goto bad_offset;
47
+ * the access flags are specified then the IOMMU implementation
167
+ }
48
+ * may use this as an optimization, to stop doing a page table
168
r = s->itcr;
49
+ * walk as soon as it knows that the requested permissions are not
169
break;
50
+ * allowed. If IOMMU_NONE is passed then the IOMMU must do the
170
case A_PID4 ... A_CID3:
51
+ * full page table walk and report the permissions in the returned
171
- r = watchdog_id[(offset - A_PID4) / 4];
52
+ * IOMMUTLBEntry. (Note that this implies that an IOMMU may not
172
+ r = s->id[(offset - A_PID4) / 4];
53
+ * return different mappings for reads and writes.)
173
break;
54
+ *
174
case A_WDOGINTCLR:
55
+ * The returned information remains valid while the caller is
175
case A_WDOGITOP:
56
+ * holding the big QEMU lock or is inside an RCU critical section;
176
+ if (s->is_luminary) {
57
+ * if the caller wishes to cache the mapping beyond that it must
177
+ goto bad_offset;
58
+ * register an IOMMU notifier so it can invalidate its cached
178
+ }
59
+ * information when the IOMMU mapping changes.
179
qemu_log_mask(LOG_GUEST_ERROR,
60
+ *
180
"CMSDK APB watchdog read: read of WO offset %x\n",
61
+ * @iommu: the IOMMUMemoryRegion
181
(int)offset);
62
+ * @hwaddr: address to be translated within the memory region
182
r = 0;
63
+ * @flag: requested access permissions
183
break;
64
*/
184
+ case A_WDOGTEST:
65
IOMMUTLBEntry (*translate)(IOMMUMemoryRegion *iommu, hwaddr addr,
185
+ if (!s->is_luminary) {
66
IOMMUAccessFlags flag);
186
+ goto bad_offset;
67
- /* Returns minimum supported page size */
187
+ }
68
+ /* Returns minimum supported page size in bytes.
188
+ qemu_log_mask(LOG_UNIMP,
69
+ * If this method is not provided then the minimum is assumed to
189
+ "Luminary watchdog read: stall not implemented\n");
70
+ * be TARGET_PAGE_SIZE.
190
+ r = 0;
71
+ *
191
+ break;
72
+ * @iommu: the IOMMUMemoryRegion
192
default:
73
+ */
193
+bad_offset:
74
uint64_t (*get_min_page_size)(IOMMUMemoryRegion *iommu);
194
qemu_log_mask(LOG_GUEST_ERROR,
75
- /* Called when IOMMU Notifier flag changed */
195
"CMSDK APB watchdog read: bad offset %x\n", (int)offset);
76
+ /* Called when IOMMU Notifier flag changes (ie when the set of
196
r = 0;
77
+ * events which IOMMU users are requesting notification for changes).
197
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
78
+ * Optional method -- need not be provided if the IOMMU does not
198
ptimer_run(s->timer, 0);
79
+ * need to know exactly which events must be notified.
199
break;
80
+ *
200
case A_WDOGCONTROL:
81
+ * @iommu: the IOMMUMemoryRegion
201
+ if (s->is_luminary && 0 != (R_WDOGCONTROL_INTEN_MASK & s->control)) {
82
+ * @old_flags: events which previously needed to be notified
202
+ /*
83
+ * @new_flags: events which now need to be notified
203
+ * The Luminary version of this device ignores writes to
84
+ */
204
+ * this register after the guest has enabled interrupts
85
void (*notify_flag_changed)(IOMMUMemoryRegion *iommu,
205
+ * (so they can only be disabled again via reset).
86
IOMMUNotifierFlag old_flags,
206
+ */
87
IOMMUNotifierFlag new_flags);
207
+ break;
88
- /* Set this up to provide customized IOMMU replay function */
208
+ }
89
+ /* Called to handle memory_region_iommu_replay().
209
s->control = value & R_WDOGCONTROL_VALID_MASK;
90
+ *
210
cmsdk_apb_watchdog_update(s);
91
+ * The default implementation of memory_region_iommu_replay() is to
211
break;
92
+ * call the IOMMU translate method for every page in the address space
212
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
93
+ * with flag == IOMMU_NONE and then call the notifier if translate
213
s->lock = (value != WDOG_UNLOCK_VALUE);
94
+ * returns a valid mapping. If this method is implemented then it
214
break;
95
+ * overrides the default behaviour, and must provide the full semantics
215
case A_WDOGITCR:
96
+ * of memory_region_iommu_replay(), by calling @notifier for every
216
+ if (s->is_luminary) {
97
+ * translation present in the IOMMU.
217
+ goto bad_offset;
98
+ *
218
+ }
99
+ * Optional method -- an IOMMU only needs to provide this method
219
s->itcr = value & R_WDOGITCR_VALID_MASK;
100
+ * if the default is inefficient or produces undesirable side effects.
220
cmsdk_apb_watchdog_update(s);
101
+ *
221
break;
102
+ * Note: this is not related to record-and-replay functionality.
222
case A_WDOGITOP:
103
+ */
223
+ if (s->is_luminary) {
104
void (*replay)(IOMMUMemoryRegion *iommu, IOMMUNotifier *notifier);
224
+ goto bad_offset;
105
225
+ }
106
- /* Get IOMMU misc attributes */
226
s->itop = value & R_WDOGITOP_VALID_MASK;
107
- int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr,
227
cmsdk_apb_watchdog_update(s);
108
+ /* Get IOMMU misc attributes. This is an optional method that
228
break;
109
+ * can be used to allow users of the IOMMU to get implementation-specific
229
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
110
+ * information. The IOMMU implements this method to handle calls
230
"CMSDK APB watchdog write: write to RO offset 0x%x\n",
111
+ * by IOMMU users to memory_region_iommu_get_attr() by filling in
231
(int)offset);
112
+ * the arbitrary data pointer for any IOMMUMemoryRegionAttr values that
232
break;
113
+ * the IOMMU supports. If the method is unimplemented then
233
+ case A_WDOGTEST:
114
+ * memory_region_iommu_get_attr() will always return -EINVAL.
234
+ if (!s->is_luminary) {
115
+ *
235
+ goto bad_offset;
116
+ * @iommu: the IOMMUMemoryRegion
236
+ }
117
+ * @attr: attribute being queried
237
+ qemu_log_mask(LOG_UNIMP,
118
+ * @data: memory to fill in with the attribute data
238
+ "Luminary watchdog write: stall not implemented\n");
119
+ *
239
+ break;
120
+ * Returns 0 on success, or a negative errno; in particular
240
default:
121
+ * returns -EINVAL for unrecognized or unimplemented attribute types.
241
+bad_offset:
122
+ */
242
qemu_log_mask(LOG_GUEST_ERROR,
123
+ int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr attr,
243
"CMSDK APB watchdog write: bad offset 0x%x\n",
124
void *data);
244
(int)offset);
125
} IOMMUMemoryRegionClass;
245
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_init(Object *obj)
126
246
s, "cmsdk-apb-watchdog", 0x1000);
127
@@ -XXX,XX +XXX,XX @@ static inline void memory_region_init_reservation(MemoryRegion *mr,
247
sysbus_init_mmio(sbd, &s->iomem);
128
* An IOMMU region translates addresses and forwards accesses to a target
248
sysbus_init_irq(sbd, &s->wdogint);
129
* memory region.
249
+
130
*
250
+ s->is_luminary = false;
131
+ * The IOMMU implementation must define a subclass of TYPE_IOMMU_MEMORY_REGION.
251
+ s->id = cmsdk_apb_watchdog_id;
132
+ * @_iommu_mr should be a pointer to enough memory for an instance of
252
}
133
+ * that subclass, @instance_size is the size of that subclass, and
253
134
+ * @mrtypename is its name. This function will initialize @_iommu_mr as an
254
static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
135
+ * instance of the subclass, and its methods will then be called to handle
255
@@ -XXX,XX +XXX,XX @@ static const TypeInfo cmsdk_apb_watchdog_info = {
136
+ * accesses to the memory region. See the documentation of
256
.class_init = cmsdk_apb_watchdog_class_init,
137
+ * #IOMMUMemoryRegionClass for further details.
257
};
138
+ *
258
139
* @_iommu_mr: the #IOMMUMemoryRegion to be initialized
259
+static void luminary_watchdog_init(Object *obj)
140
* @instance_size: the IOMMUMemoryRegion subclass instance size
260
+{
141
* @mrtypename: the type name of the #IOMMUMemoryRegion
261
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(obj);
142
@@ -XXX,XX +XXX,XX @@ void memory_region_register_iommu_notifier(MemoryRegion *mr,
262
+
143
* a notifier with the minimum page granularity returned by
263
+ s->is_luminary = true;
144
* mr->iommu_ops->get_page_size().
264
+ s->id = luminary_watchdog_id;
145
*
265
+}
146
+ * Note: this is not related to record-and-replay functionality.
266
+
147
+ *
267
+static const TypeInfo luminary_watchdog_info = {
148
* @iommu_mr: the memory region to observe
268
+ .name = TYPE_LUMINARY_WATCHDOG,
149
* @n: the notifier to which to replay iommu mappings
269
+ .parent = TYPE_CMSDK_APB_WATCHDOG,
150
*/
270
+ .instance_init = luminary_watchdog_init
151
@@ -XXX,XX +XXX,XX @@ void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n);
271
+};
152
* memory_region_iommu_replay_all: replay existing IOMMU translations
272
+
153
* to all the notifiers registered.
273
static void cmsdk_apb_watchdog_register_types(void)
154
*
274
{
155
+ * Note: this is not related to record-and-replay functionality.
275
type_register_static(&cmsdk_apb_watchdog_info);
156
+ *
276
+ type_register_static(&luminary_watchdog_info);
157
* @iommu_mr: the memory region to observe
277
}
158
*/
278
159
void memory_region_iommu_replay_all(IOMMUMemoryRegion *iommu_mr);
279
type_init(cmsdk_apb_watchdog_register_types);
160
@@ -XXX,XX +XXX,XX @@ void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
161
* memory_region_iommu_get_attr: return an IOMMU attr if get_attr() is
162
* defined on the IOMMU.
163
*
164
- * Returns 0 if succeded, error code otherwise.
165
+ * Returns 0 on success, or a negative errno otherwise. In particular,
166
+ * -EINVAL indicates that the IOMMU does not support the requested
167
+ * attribute.
168
*
169
* @iommu_mr: the memory region
170
* @attr: the requested attribute
171
--
280
--
172
2.17.1
281
2.20.1
173
282
174
283
diff view generated by jsdifflib
Deleted patch
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
add MemTxAttrs as an argument to address_space_translate()
3
and address_space_translate_cached(). Callers either have an
4
attrs value to hand, or don't care and can use MEMTXATTRS_UNSPECIFIED.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-4-peter.maydell@linaro.org
10
---
11
include/exec/memory.h | 4 +++-
12
accel/tcg/translate-all.c | 2 +-
13
exec.c | 14 +++++++++-----
14
hw/vfio/common.c | 3 ++-
15
memory_ldst.inc.c | 18 +++++++++---------
16
target/riscv/helper.c | 2 +-
17
6 files changed, 25 insertions(+), 18 deletions(-)
18
19
diff --git a/include/exec/memory.h b/include/exec/memory.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/exec/memory.h
22
+++ b/include/exec/memory.h
23
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
24
* #MemoryRegion.
25
* @len: pointer to length
26
* @is_write: indicates the transfer direction
27
+ * @attrs: memory attributes
28
*/
29
MemoryRegion *flatview_translate(FlatView *fv,
30
hwaddr addr, hwaddr *xlat,
31
@@ -XXX,XX +XXX,XX @@ MemoryRegion *flatview_translate(FlatView *fv,
32
33
static inline MemoryRegion *address_space_translate(AddressSpace *as,
34
hwaddr addr, hwaddr *xlat,
35
- hwaddr *len, bool is_write)
36
+ hwaddr *len, bool is_write,
37
+ MemTxAttrs attrs)
38
{
39
return flatview_translate(address_space_to_flatview(as),
40
addr, xlat, len, is_write);
41
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/accel/tcg/translate-all.c
44
+++ b/accel/tcg/translate-all.c
45
@@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
46
hwaddr l = 1;
47
48
rcu_read_lock();
49
- mr = address_space_translate(as, addr, &addr, &l, false);
50
+ mr = address_space_translate(as, addr, &addr, &l, false, attrs);
51
if (!(memory_region_is_ram(mr)
52
|| memory_region_is_romd(mr))) {
53
rcu_read_unlock();
54
diff --git a/exec.c b/exec.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/exec.c
57
+++ b/exec.c
58
@@ -XXX,XX +XXX,XX @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
59
rcu_read_lock();
60
while (len > 0) {
61
l = len;
62
- mr = address_space_translate(as, addr, &addr1, &l, true);
63
+ mr = address_space_translate(as, addr, &addr1, &l, true,
64
+ MEMTXATTRS_UNSPECIFIED);
65
66
if (!(memory_region_is_ram(mr) ||
67
memory_region_is_romd(mr))) {
68
@@ -XXX,XX +XXX,XX @@ void address_space_cache_destroy(MemoryRegionCache *cache)
69
*/
70
static inline MemoryRegion *address_space_translate_cached(
71
MemoryRegionCache *cache, hwaddr addr, hwaddr *xlat,
72
- hwaddr *plen, bool is_write)
73
+ hwaddr *plen, bool is_write, MemTxAttrs attrs)
74
{
75
MemoryRegionSection section;
76
MemoryRegion *mr;
77
@@ -XXX,XX +XXX,XX @@ address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr,
78
MemoryRegion *mr;
79
80
l = len;
81
- mr = address_space_translate_cached(cache, addr, &addr1, &l, false);
82
+ mr = address_space_translate_cached(cache, addr, &addr1, &l, false,
83
+ MEMTXATTRS_UNSPECIFIED);
84
flatview_read_continue(cache->fv,
85
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
86
addr1, l, mr);
87
@@ -XXX,XX +XXX,XX @@ address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
88
MemoryRegion *mr;
89
90
l = len;
91
- mr = address_space_translate_cached(cache, addr, &addr1, &l, true);
92
+ mr = address_space_translate_cached(cache, addr, &addr1, &l, true,
93
+ MEMTXATTRS_UNSPECIFIED);
94
flatview_write_continue(cache->fv,
95
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
96
addr1, l, mr);
97
@@ -XXX,XX +XXX,XX @@ bool cpu_physical_memory_is_io(hwaddr phys_addr)
98
99
rcu_read_lock();
100
mr = address_space_translate(&address_space_memory,
101
- phys_addr, &phys_addr, &l, false);
102
+ phys_addr, &phys_addr, &l, false,
103
+ MEMTXATTRS_UNSPECIFIED);
104
105
res = !(memory_region_is_ram(mr) || memory_region_is_romd(mr));
106
rcu_read_unlock();
107
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/hw/vfio/common.c
110
+++ b/hw/vfio/common.c
111
@@ -XXX,XX +XXX,XX @@ static bool vfio_get_vaddr(IOMMUTLBEntry *iotlb, void **vaddr,
112
*/
113
mr = address_space_translate(&address_space_memory,
114
iotlb->translated_addr,
115
- &xlat, &len, writable);
116
+ &xlat, &len, writable,
117
+ MEMTXATTRS_UNSPECIFIED);
118
if (!memory_region_is_ram(mr)) {
119
error_report("iommu map to non memory area %"HWADDR_PRIx"",
120
xlat);
121
diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/memory_ldst.inc.c
124
+++ b/memory_ldst.inc.c
125
@@ -XXX,XX +XXX,XX @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
126
bool release_lock = false;
127
128
RCU_READ_LOCK();
129
- mr = TRANSLATE(addr, &addr1, &l, false);
130
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
131
if (l < 4 || !IS_DIRECT(mr, false)) {
132
release_lock |= prepare_mmio_access(mr);
133
134
@@ -XXX,XX +XXX,XX @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
135
bool release_lock = false;
136
137
RCU_READ_LOCK();
138
- mr = TRANSLATE(addr, &addr1, &l, false);
139
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
140
if (l < 8 || !IS_DIRECT(mr, false)) {
141
release_lock |= prepare_mmio_access(mr);
142
143
@@ -XXX,XX +XXX,XX @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
144
bool release_lock = false;
145
146
RCU_READ_LOCK();
147
- mr = TRANSLATE(addr, &addr1, &l, false);
148
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
149
if (!IS_DIRECT(mr, false)) {
150
release_lock |= prepare_mmio_access(mr);
151
152
@@ -XXX,XX +XXX,XX @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
153
bool release_lock = false;
154
155
RCU_READ_LOCK();
156
- mr = TRANSLATE(addr, &addr1, &l, false);
157
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
158
if (l < 2 || !IS_DIRECT(mr, false)) {
159
release_lock |= prepare_mmio_access(mr);
160
161
@@ -XXX,XX +XXX,XX @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
162
bool release_lock = false;
163
164
RCU_READ_LOCK();
165
- mr = TRANSLATE(addr, &addr1, &l, true);
166
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
167
if (l < 4 || !IS_DIRECT(mr, true)) {
168
release_lock |= prepare_mmio_access(mr);
169
170
@@ -XXX,XX +XXX,XX @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
171
bool release_lock = false;
172
173
RCU_READ_LOCK();
174
- mr = TRANSLATE(addr, &addr1, &l, true);
175
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
176
if (l < 4 || !IS_DIRECT(mr, true)) {
177
release_lock |= prepare_mmio_access(mr);
178
179
@@ -XXX,XX +XXX,XX @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
180
bool release_lock = false;
181
182
RCU_READ_LOCK();
183
- mr = TRANSLATE(addr, &addr1, &l, true);
184
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
185
if (!IS_DIRECT(mr, true)) {
186
release_lock |= prepare_mmio_access(mr);
187
r = memory_region_dispatch_write(mr, addr1, val, 1, attrs);
188
@@ -XXX,XX +XXX,XX @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
189
bool release_lock = false;
190
191
RCU_READ_LOCK();
192
- mr = TRANSLATE(addr, &addr1, &l, true);
193
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
194
if (l < 2 || !IS_DIRECT(mr, true)) {
195
release_lock |= prepare_mmio_access(mr);
196
197
@@ -XXX,XX +XXX,XX @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
198
bool release_lock = false;
199
200
RCU_READ_LOCK();
201
- mr = TRANSLATE(addr, &addr1, &l, true);
202
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
203
if (l < 8 || !IS_DIRECT(mr, true)) {
204
release_lock |= prepare_mmio_access(mr);
205
206
diff --git a/target/riscv/helper.c b/target/riscv/helper.c
207
index XXXXXXX..XXXXXXX 100644
208
--- a/target/riscv/helper.c
209
+++ b/target/riscv/helper.c
210
@@ -XXX,XX +XXX,XX @@ restart:
211
MemoryRegion *mr;
212
hwaddr l = sizeof(target_ulong), addr1;
213
mr = address_space_translate(cs->as, pte_addr,
214
- &addr1, &l, false);
215
+ &addr1, &l, false, MEMTXATTRS_UNSPECIFIED);
216
if (memory_access_is_direct(mr, true)) {
217
target_ulong *pte_pa =
218
qemu_map_ram_ptr(mr->ram_block, addr1);
219
--
220
2.17.1
221
222
diff view generated by jsdifflib
Deleted patch
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
add MemTxAttrs as an argument to flatview_extend_translation().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-7-peter.maydell@linaro.org
10
---
11
exec.c | 15 ++++++++++-----
12
1 file changed, 10 insertions(+), 5 deletions(-)
13
14
diff --git a/exec.c b/exec.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/exec.c
17
+++ b/exec.c
18
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr,
19
20
static hwaddr
21
flatview_extend_translation(FlatView *fv, hwaddr addr,
22
- hwaddr target_len,
23
- MemoryRegion *mr, hwaddr base, hwaddr len,
24
- bool is_write)
25
+ hwaddr target_len,
26
+ MemoryRegion *mr, hwaddr base, hwaddr len,
27
+ bool is_write, MemTxAttrs attrs)
28
{
29
hwaddr done = 0;
30
hwaddr xlat;
31
@@ -XXX,XX +XXX,XX @@ void *address_space_map(AddressSpace *as,
32
33
memory_region_ref(mr);
34
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
35
- l, is_write);
36
+ l, is_write, attrs);
37
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
38
rcu_read_unlock();
39
40
@@ -XXX,XX +XXX,XX @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
41
mr = cache->mrs.mr;
42
memory_region_ref(mr);
43
if (memory_access_is_direct(mr, is_write)) {
44
+ /* We don't care about the memory attributes here as we're only
45
+ * doing this if we found actual RAM, which behaves the same
46
+ * regardless of attributes; so UNSPECIFIED is fine.
47
+ */
48
l = flatview_extend_translation(cache->fv, addr, len, mr,
49
- cache->xlat, l, is_write);
50
+ cache->xlat, l, is_write,
51
+ MEMTXATTRS_UNSPECIFIED);
52
cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
53
} else {
54
cache->ptr = NULL;
55
--
56
2.17.1
57
58
diff view generated by jsdifflib