1 | Just small stuff. I expect/hope to get the "report attributes | 1 | A small set of arm bugfixes for rc0. |
---|---|---|---|
2 | in PAR register" fix from Andrew in, but will either send another | ||
3 | pull or just apply it as a single patch once it's been reviewed. | ||
4 | (I think we can call it a bugfix anyway, since it fixes booting | ||
5 | of Windows on ARM.) | ||
6 | |||
7 | thanks | ||
8 | -- PMM | ||
9 | 2 | ||
10 | 3 | ||
11 | The following changes since commit abf6e752e55b2f5afb48303429dea2db7c3a62de: | ||
12 | 4 | ||
13 | Merge remote-tracking branch 'remotes/borntraeger/tags/s390x-20171030' into staging (2017-10-30 13:02:45 +0000) | 5 | The following changes since commit 5853e92207193e967abf5e4c25b4a551c7604725: |
6 | |||
7 | Merge remote-tracking branch 'remotes/pmaydell/tags/pull-cocoa-20171107' into staging (2017-11-07 12:19:48 +0000) | ||
14 | 8 | ||
15 | are available in the git repository at: | 9 | are available in the git repository at: |
16 | 10 | ||
17 | git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20171031 | 11 | git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20171107 |
18 | 12 | ||
19 | for you to fetch changes up to 168df2dea701bbf3118bdfea7794369dfa694d3d: | 13 | for you to fetch changes up to 8a7348b5d62d7ea16807e6bea54b448a0184bb0f: |
20 | 14 | ||
21 | hw/pci-host/gpex: Improve INTX to gsi routing error checking (2017-10-31 11:50:52 +0000) | 15 | hw/intc/arm_gicv3_its: Don't abort on table save failure (2017-11-07 13:03:52 +0000) |
22 | 16 | ||
23 | ---------------------------------------------------------------- | 17 | ---------------------------------------------------------------- |
24 | target-arm queue: | 18 | target-arm queue: |
25 | * fix instruction-length bit in syndrome for WFI/WFE traps | 19 | * arm_gicv3_its: Don't abort on table save failure |
26 | * xlnx-zcu102: Specify the max number of CPUs | 20 | * arm_gicv3_its: Fix the VM termination in vm_change_state_handler() |
27 | * msf2: Remove dead code reported by Coverity | 21 | * translate.c: Fix usermode big-endian AArch32 LDREXD and STREXD |
28 | * msf2: Wire up SYSRESETREQ in SoC for system reset | 22 | * hw/arm: Mark the "fsl,imx31/25/6" devices with user_creatable = false |
29 | * hw/pci-host/gpex: Improve INTX to gsi routing error checking | 23 | * arm: implement cache/shareability attribute bits for PAR registers |
30 | 24 | ||
31 | ---------------------------------------------------------------- | 25 | ---------------------------------------------------------------- |
32 | Alistair Francis (1): | 26 | Andrew Baumann (1): |
33 | xlnx-zcu102: Specify the max number of CPUs | 27 | arm: implement cache/shareability attribute bits for PAR registers |
34 | 28 | ||
35 | Eric Auger (1): | 29 | Eric Auger (1): |
36 | hw/pci-host/gpex: Improve INTX to gsi routing error checking | 30 | hw/intc/arm_gicv3_its: Don't abort on table save failure |
37 | 31 | ||
38 | Stefano Stabellini (1): | 32 | Peter Maydell (1): |
39 | fix WFI/WFE length in syndrome register | 33 | translate.c: Fix usermode big-endian AArch32 LDREXD and STREXD |
40 | 34 | ||
41 | Subbaraya Sundeep (2): | 35 | Shanker Donthineni (1): |
42 | msf2: Remove dead code reported by Coverity | 36 | hw/intc/arm_gicv3_its: Fix the VM termination in vm_change_state_handler() |
43 | msf2: Wire up SYSRESETREQ in SoC for system reset | ||
44 | 37 | ||
45 | target/arm/helper.h | 2 +- | 38 | Thomas Huth (3): |
46 | target/arm/internals.h | 3 ++- | 39 | hw/arm: Mark the "fsl,imx6" device with user_creatable = false |
47 | hw/arm/msf2-soc.c | 11 +++++++++++ | 40 | hw/arm: Mark the "fsl,imx25" device with user_creatable = false |
48 | hw/arm/xlnx-zcu102.c | 1 + | 41 | hw/arm: Mark the "fsl,imx31" device with user_creatable = false |
49 | hw/pci-host/gpex.c | 10 ++++++++-- | ||
50 | hw/ssi/mss-spi.c | 18 ++++++++++++++---- | ||
51 | target/arm/op_helper.c | 7 ++++--- | ||
52 | target/arm/psci.c | 2 +- | ||
53 | target/arm/translate-a64.c | 7 ++++++- | ||
54 | target/arm/translate.c | 10 +++++++++- | ||
55 | 10 files changed, 57 insertions(+), 14 deletions(-) | ||
56 | 42 | ||
43 | hw/arm/fsl-imx25.c | 6 +- | ||
44 | hw/arm/fsl-imx31.c | 6 +- | ||
45 | hw/arm/fsl-imx6.c | 3 +- | ||
46 | hw/intc/arm_gicv3_its_kvm.c | 12 +-- | ||
47 | target/arm/helper.c | 178 ++++++++++++++++++++++++++++++++++++++++---- | ||
48 | target/arm/translate.c | 39 ++++++++-- | ||
49 | 6 files changed, 214 insertions(+), 30 deletions(-) | ||
50 | diff view generated by jsdifflib |
1 | From: Subbaraya Sundeep <sundeep.lkml@gmail.com> | 1 | From: Andrew Baumann <Andrew.Baumann@microsoft.com> |
---|---|---|---|
2 | 2 | ||
3 | Implemented system reset by creating SYSRESETREQ gpio | 3 | On a successful address translation instruction, PAR is supposed to |
4 | out from nvic. | 4 | contain cacheability and shareability attributes determined by the |
5 | 5 | translation. We previously returned 0 for these bits (in line with the | |
6 | Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com> | 6 | general strategy of ignoring caches and memory attributes), but some |
7 | Message-id: 1509253165-7434-1-git-send-email-sundeep.lkml@gmail.com | 7 | guest OSes may depend on them. |
8 | |||
9 | This patch collects the attribute bits in the page-table walk, and | ||
10 | updates PAR with the correct attributes for all LPAE translations. | ||
11 | Short descriptor formats still return 0 for these bits, as in the | ||
12 | prior implementation. | ||
13 | |||
14 | Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com> | ||
15 | Message-id: 20171031223830.4608-1-Andrew.Baumann@microsoft.com | ||
8 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 16 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 17 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
10 | --- | 18 | --- |
11 | hw/arm/msf2-soc.c | 11 +++++++++++ | 19 | target/arm/helper.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++----- |
12 | 1 file changed, 11 insertions(+) | 20 | 1 file changed, 164 insertions(+), 14 deletions(-) |
13 | 21 | ||
14 | diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c | 22 | diff --git a/target/arm/helper.c b/target/arm/helper.c |
15 | index XXXXXXX..XXXXXXX 100644 | 23 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/hw/arm/msf2-soc.c | 24 | --- a/target/arm/helper.c |
17 | +++ b/hw/arm/msf2-soc.c | 25 | +++ b/target/arm/helper.c |
18 | @@ -XXX,XX +XXX,XX @@ static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 }; | 26 | @@ -XXX,XX +XXX,XX @@ |
19 | static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 }; | 27 | #define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */ |
20 | static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 }; | 28 | |
21 | 29 | #ifndef CONFIG_USER_ONLY | |
22 | +static void do_sys_reset(void *opaque, int n, int level) | 30 | +/* Cacheability and shareability attributes for a memory access */ |
31 | +typedef struct ARMCacheAttrs { | ||
32 | + unsigned int attrs:8; /* as in the MAIR register encoding */ | ||
33 | + unsigned int shareability:2; /* as in the SH field of the VMSAv8-64 PTEs */ | ||
34 | +} ARMCacheAttrs; | ||
35 | + | ||
36 | static bool get_phys_addr(CPUARMState *env, target_ulong address, | ||
37 | MMUAccessType access_type, ARMMMUIdx mmu_idx, | ||
38 | hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot, | ||
39 | target_ulong *page_size, uint32_t *fsr, | ||
40 | - ARMMMUFaultInfo *fi); | ||
41 | + ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs); | ||
42 | |||
43 | static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, | ||
44 | MMUAccessType access_type, ARMMMUIdx mmu_idx, | ||
45 | hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot, | ||
46 | target_ulong *page_size_ptr, uint32_t *fsr, | ||
47 | - ARMMMUFaultInfo *fi); | ||
48 | + ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs); | ||
49 | |||
50 | /* Security attributes for an address, as returned by v8m_security_lookup. */ | ||
51 | typedef struct V8M_SAttributes { | ||
52 | @@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value, | ||
53 | uint64_t par64; | ||
54 | MemTxAttrs attrs = {}; | ||
55 | ARMMMUFaultInfo fi = {}; | ||
56 | + ARMCacheAttrs cacheattrs = {}; | ||
57 | |||
58 | - ret = get_phys_addr(env, value, access_type, mmu_idx, | ||
59 | - &phys_addr, &attrs, &prot, &page_size, &fsr, &fi); | ||
60 | + ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs, | ||
61 | + &prot, &page_size, &fsr, &fi, &cacheattrs); | ||
62 | if (extended_addresses_enabled(env)) { | ||
63 | /* fsr is a DFSR/IFSR value for the long descriptor | ||
64 | * translation table format, but with WnR always clear. | ||
65 | @@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value, | ||
66 | if (!attrs.secure) { | ||
67 | par64 |= (1 << 9); /* NS */ | ||
68 | } | ||
69 | - /* We don't set the ATTR or SH fields in the PAR. */ | ||
70 | + par64 |= (uint64_t)cacheattrs.attrs << 56; /* ATTR */ | ||
71 | + par64 |= cacheattrs.shareability << 7; /* SH */ | ||
72 | } else { | ||
73 | par64 |= 1; /* F */ | ||
74 | par64 |= (fsr & 0x3f) << 1; /* FS */ | ||
75 | @@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx, | ||
76 | return false; | ||
77 | } | ||
78 | if (get_phys_addr(env, addr, MMU_INST_FETCH, mmu_idx, | ||
79 | - &physaddr, &attrs, &prot, &page_size, &fsr, &fi)) { | ||
80 | + &physaddr, &attrs, &prot, &page_size, &fsr, &fi, NULL)) { | ||
81 | /* the MPU lookup failed */ | ||
82 | env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_IACCVIOL_MASK; | ||
83 | armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, env->v7m.secure); | ||
84 | @@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, | ||
85 | int ret; | ||
86 | |||
87 | ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa, | ||
88 | - &txattrs, &s2prot, &s2size, fsr, fi); | ||
89 | + &txattrs, &s2prot, &s2size, fsr, fi, NULL); | ||
90 | if (ret) { | ||
91 | fi->s2addr = addr; | ||
92 | fi->stage2 = true; | ||
93 | @@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level, | ||
94 | return true; | ||
95 | } | ||
96 | |||
97 | +/* Translate from the 4-bit stage 2 representation of | ||
98 | + * memory attributes (without cache-allocation hints) to | ||
99 | + * the 8-bit representation of the stage 1 MAIR registers | ||
100 | + * (which includes allocation hints). | ||
101 | + * | ||
102 | + * ref: shared/translation/attrs/S2AttrDecode() | ||
103 | + * .../S2ConvertAttrsHints() | ||
104 | + */ | ||
105 | +static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs) | ||
23 | +{ | 106 | +{ |
24 | + if (level) { | 107 | + uint8_t hiattr = extract32(s2attrs, 2, 2); |
25 | + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); | 108 | + uint8_t loattr = extract32(s2attrs, 0, 2); |
26 | + } | 109 | + uint8_t hihint = 0, lohint = 0; |
110 | + | ||
111 | + if (hiattr != 0) { /* normal memory */ | ||
112 | + if ((env->cp15.hcr_el2 & HCR_CD) != 0) { /* cache disabled */ | ||
113 | + hiattr = loattr = 1; /* non-cacheable */ | ||
114 | + } else { | ||
115 | + if (hiattr != 1) { /* Write-through or write-back */ | ||
116 | + hihint = 3; /* RW allocate */ | ||
117 | + } | ||
118 | + if (loattr != 1) { /* Write-through or write-back */ | ||
119 | + lohint = 3; /* RW allocate */ | ||
120 | + } | ||
121 | + } | ||
122 | + } | ||
123 | + | ||
124 | + return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint; | ||
27 | +} | 125 | +} |
28 | + | 126 | + |
29 | static void m2sxxx_soc_initfn(Object *obj) | 127 | static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, |
128 | MMUAccessType access_type, ARMMMUIdx mmu_idx, | ||
129 | hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot, | ||
130 | target_ulong *page_size_ptr, uint32_t *fsr, | ||
131 | - ARMMMUFaultInfo *fi) | ||
132 | + ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs) | ||
30 | { | 133 | { |
31 | MSF2State *s = MSF2_SOC(obj); | 134 | ARMCPU *cpu = arm_env_get_cpu(env); |
32 | @@ -XXX,XX +XXX,XX @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp) | 135 | CPUState *cs = CPU(cpu); |
33 | error_append_hint(errp, "m3clk can not be zero\n"); | 136 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, |
34 | return; | 137 | */ |
138 | txattrs->secure = false; | ||
35 | } | 139 | } |
36 | + | 140 | + |
37 | + qdev_connect_gpio_out_named(DEVICE(&s->armv7m.nvic), "SYSRESETREQ", 0, | 141 | + if (cacheattrs != NULL) { |
38 | + qemu_allocate_irq(&do_sys_reset, NULL, 0)); | 142 | + if (mmu_idx == ARMMMUIdx_S2NS) { |
39 | + | 143 | + cacheattrs->attrs = convert_stage2_attrs(env, |
40 | system_clock_scale = NANOSECONDS_PER_SECOND / s->m3clk; | 144 | + extract32(attrs, 0, 4)); |
41 | 145 | + } else { | |
42 | for (i = 0; i < MSF2_NUM_UARTS; i++) { | 146 | + /* Index into MAIR registers for cache attributes */ |
147 | + uint8_t attrindx = extract32(attrs, 0, 3); | ||
148 | + uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)]; | ||
149 | + assert(attrindx <= 7); | ||
150 | + cacheattrs->attrs = extract64(mair, attrindx * 8, 8); | ||
151 | + } | ||
152 | + cacheattrs->shareability = extract32(attrs, 6, 2); | ||
153 | + } | ||
154 | + | ||
155 | *phys_ptr = descaddr; | ||
156 | *page_size_ptr = page_size; | ||
157 | return false; | ||
158 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address, | ||
159 | return false; | ||
160 | } | ||
161 | |||
162 | +/* Combine either inner or outer cacheability attributes for normal | ||
163 | + * memory, according to table D4-42 and pseudocode procedure | ||
164 | + * CombineS1S2AttrHints() of ARM DDI 0487B.b (the ARMv8 ARM). | ||
165 | + * | ||
166 | + * NB: only stage 1 includes allocation hints (RW bits), leading to | ||
167 | + * some asymmetry. | ||
168 | + */ | ||
169 | +static uint8_t combine_cacheattr_nibble(uint8_t s1, uint8_t s2) | ||
170 | +{ | ||
171 | + if (s1 == 4 || s2 == 4) { | ||
172 | + /* non-cacheable has precedence */ | ||
173 | + return 4; | ||
174 | + } else if (extract32(s1, 2, 2) == 0 || extract32(s1, 2, 2) == 2) { | ||
175 | + /* stage 1 write-through takes precedence */ | ||
176 | + return s1; | ||
177 | + } else if (extract32(s2, 2, 2) == 2) { | ||
178 | + /* stage 2 write-through takes precedence, but the allocation hint | ||
179 | + * is still taken from stage 1 | ||
180 | + */ | ||
181 | + return (2 << 2) | extract32(s1, 0, 2); | ||
182 | + } else { /* write-back */ | ||
183 | + return s1; | ||
184 | + } | ||
185 | +} | ||
186 | + | ||
187 | +/* Combine S1 and S2 cacheability/shareability attributes, per D4.5.4 | ||
188 | + * and CombineS1S2Desc() | ||
189 | + * | ||
190 | + * @s1: Attributes from stage 1 walk | ||
191 | + * @s2: Attributes from stage 2 walk | ||
192 | + */ | ||
193 | +static ARMCacheAttrs combine_cacheattrs(ARMCacheAttrs s1, ARMCacheAttrs s2) | ||
194 | +{ | ||
195 | + uint8_t s1lo = extract32(s1.attrs, 0, 4), s2lo = extract32(s2.attrs, 0, 4); | ||
196 | + uint8_t s1hi = extract32(s1.attrs, 4, 4), s2hi = extract32(s2.attrs, 4, 4); | ||
197 | + ARMCacheAttrs ret; | ||
198 | + | ||
199 | + /* Combine shareability attributes (table D4-43) */ | ||
200 | + if (s1.shareability == 2 || s2.shareability == 2) { | ||
201 | + /* if either are outer-shareable, the result is outer-shareable */ | ||
202 | + ret.shareability = 2; | ||
203 | + } else if (s1.shareability == 3 || s2.shareability == 3) { | ||
204 | + /* if either are inner-shareable, the result is inner-shareable */ | ||
205 | + ret.shareability = 3; | ||
206 | + } else { | ||
207 | + /* both non-shareable */ | ||
208 | + ret.shareability = 0; | ||
209 | + } | ||
210 | + | ||
211 | + /* Combine memory type and cacheability attributes */ | ||
212 | + if (s1hi == 0 || s2hi == 0) { | ||
213 | + /* Device has precedence over normal */ | ||
214 | + if (s1lo == 0 || s2lo == 0) { | ||
215 | + /* nGnRnE has precedence over anything */ | ||
216 | + ret.attrs = 0; | ||
217 | + } else if (s1lo == 4 || s2lo == 4) { | ||
218 | + /* non-Reordering has precedence over Reordering */ | ||
219 | + ret.attrs = 4; /* nGnRE */ | ||
220 | + } else if (s1lo == 8 || s2lo == 8) { | ||
221 | + /* non-Gathering has precedence over Gathering */ | ||
222 | + ret.attrs = 8; /* nGRE */ | ||
223 | + } else { | ||
224 | + ret.attrs = 0xc; /* GRE */ | ||
225 | + } | ||
226 | + | ||
227 | + /* Any location for which the resultant memory type is any | ||
228 | + * type of Device memory is always treated as Outer Shareable. | ||
229 | + */ | ||
230 | + ret.shareability = 2; | ||
231 | + } else { /* Normal memory */ | ||
232 | + /* Outer/inner cacheability combine independently */ | ||
233 | + ret.attrs = combine_cacheattr_nibble(s1hi, s2hi) << 4 | ||
234 | + | combine_cacheattr_nibble(s1lo, s2lo); | ||
235 | + | ||
236 | + if (ret.attrs == 0x44) { | ||
237 | + /* Any location for which the resultant memory type is Normal | ||
238 | + * Inner Non-cacheable, Outer Non-cacheable is always treated | ||
239 | + * as Outer Shareable. | ||
240 | + */ | ||
241 | + ret.shareability = 2; | ||
242 | + } | ||
243 | + } | ||
244 | + | ||
245 | + return ret; | ||
246 | +} | ||
247 | + | ||
248 | + | ||
249 | /* get_phys_addr - get the physical address for this virtual address | ||
250 | * | ||
251 | * Find the physical address corresponding to the given virtual address, | ||
252 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address, | ||
253 | * @prot: set to the permissions for the page containing phys_ptr | ||
254 | * @page_size: set to the size of the page containing phys_ptr | ||
255 | * @fsr: set to the DFSR/IFSR value on failure | ||
256 | + * @fi: set to fault info if the translation fails | ||
257 | + * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes | ||
258 | */ | ||
259 | static bool get_phys_addr(CPUARMState *env, target_ulong address, | ||
260 | MMUAccessType access_type, ARMMMUIdx mmu_idx, | ||
261 | hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot, | ||
262 | target_ulong *page_size, uint32_t *fsr, | ||
263 | - ARMMMUFaultInfo *fi) | ||
264 | + ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs) | ||
265 | { | ||
266 | if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) { | ||
267 | /* Call ourselves recursively to do the stage 1 and then stage 2 | ||
268 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address, | ||
269 | hwaddr ipa; | ||
270 | int s2_prot; | ||
271 | int ret; | ||
272 | + ARMCacheAttrs cacheattrs2 = {}; | ||
273 | |||
274 | ret = get_phys_addr(env, address, access_type, | ||
275 | stage_1_mmu_idx(mmu_idx), &ipa, attrs, | ||
276 | - prot, page_size, fsr, fi); | ||
277 | + prot, page_size, fsr, fi, cacheattrs); | ||
278 | |||
279 | /* If S1 fails or S2 is disabled, return early. */ | ||
280 | if (ret || regime_translation_disabled(env, ARMMMUIdx_S2NS)) { | ||
281 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address, | ||
282 | /* S1 is done. Now do S2 translation. */ | ||
283 | ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_S2NS, | ||
284 | phys_ptr, attrs, &s2_prot, | ||
285 | - page_size, fsr, fi); | ||
286 | + page_size, fsr, fi, | ||
287 | + cacheattrs != NULL ? &cacheattrs2 : NULL); | ||
288 | fi->s2addr = ipa; | ||
289 | /* Combine the S1 and S2 perms. */ | ||
290 | *prot &= s2_prot; | ||
291 | + | ||
292 | + /* Combine the S1 and S2 cache attributes, if needed */ | ||
293 | + if (!ret && cacheattrs != NULL) { | ||
294 | + *cacheattrs = combine_cacheattrs(*cacheattrs, cacheattrs2); | ||
295 | + } | ||
296 | + | ||
297 | return ret; | ||
298 | } else { | ||
299 | /* | ||
300 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address, | ||
301 | |||
302 | if (regime_using_lpae_format(env, mmu_idx)) { | ||
303 | return get_phys_addr_lpae(env, address, access_type, mmu_idx, phys_ptr, | ||
304 | - attrs, prot, page_size, fsr, fi); | ||
305 | + attrs, prot, page_size, fsr, fi, cacheattrs); | ||
306 | } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) { | ||
307 | return get_phys_addr_v6(env, address, access_type, mmu_idx, phys_ptr, | ||
308 | attrs, prot, page_size, fsr, fi); | ||
309 | @@ -XXX,XX +XXX,XX @@ bool arm_tlb_fill(CPUState *cs, vaddr address, | ||
310 | |||
311 | ret = get_phys_addr(env, address, access_type, | ||
312 | core_to_arm_mmu_idx(env, mmu_idx), &phys_addr, | ||
313 | - &attrs, &prot, &page_size, fsr, fi); | ||
314 | + &attrs, &prot, &page_size, fsr, fi, NULL); | ||
315 | if (!ret) { | ||
316 | /* Map a single [sub]page. */ | ||
317 | phys_addr &= TARGET_PAGE_MASK; | ||
318 | @@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr, | ||
319 | *attrs = (MemTxAttrs) {}; | ||
320 | |||
321 | ret = get_phys_addr(env, addr, 0, mmu_idx, &phys_addr, | ||
322 | - attrs, &prot, &page_size, &fsr, &fi); | ||
323 | + attrs, &prot, &page_size, &fsr, &fi, NULL); | ||
324 | |||
325 | if (ret) { | ||
326 | return -1; | ||
43 | -- | 327 | -- |
44 | 2.7.4 | 328 | 2.7.4 |
45 | 329 | ||
46 | 330 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Thomas Huth <thuth@redhat.com> | ||
1 | 2 | ||
3 | This device causes QEMU to abort if the user tries to instantiate it: | ||
4 | |||
5 | $ qemu-system-aarch64 -M sabrelite -smp 1,maxcpus=2 -device fsl,,imx6 | ||
6 | Unexpected error in qemu_chr_fe_init() at chardev/char-fe.c:222: | ||
7 | qemu-system-aarch64: -device fsl,,imx6: Device 'serial0' is in use | ||
8 | Aborted (core dumped) | ||
9 | |||
10 | The device uses serial_hds[] directly in its realize function, so it | ||
11 | can not be instantiated again by the user. | ||
12 | |||
13 | Signed-off-by: Thomas Huth <thuth@redhat.com> | ||
14 | Message-id: 1509519537-6964-2-git-send-email-thuth@redhat.com | ||
15 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
16 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
17 | --- | ||
18 | hw/arm/fsl-imx6.c | 3 ++- | ||
19 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
20 | |||
21 | diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/hw/arm/fsl-imx6.c | ||
24 | +++ b/hw/arm/fsl-imx6.c | ||
25 | @@ -XXX,XX +XXX,XX @@ static void fsl_imx6_class_init(ObjectClass *oc, void *data) | ||
26 | DeviceClass *dc = DEVICE_CLASS(oc); | ||
27 | |||
28 | dc->realize = fsl_imx6_realize; | ||
29 | - | ||
30 | dc->desc = "i.MX6 SOC"; | ||
31 | + /* Reason: Uses serial_hds[] in the realize() function */ | ||
32 | + dc->user_creatable = false; | ||
33 | } | ||
34 | |||
35 | static const TypeInfo fsl_imx6_type_info = { | ||
36 | -- | ||
37 | 2.7.4 | ||
38 | |||
39 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Thomas Huth <thuth@redhat.com> | ||
1 | 2 | ||
3 | QEMU currently crashes when the user tries to instantiate the fsl,imx25 | ||
4 | device manually: | ||
5 | |||
6 | $ aarch64-softmmu/qemu-system-aarch64 -S -M imx25-pdk -device fsl,,imx25 | ||
7 | ** | ||
8 | ERROR:/home/thuth/devel/qemu/tcg/tcg.c:538:tcg_register_thread: | ||
9 | assertion failed: (n < max_cpus) | ||
10 | |||
11 | The imx25-pdk board (which is the one that uses this CPU type) only | ||
12 | supports one CPU, and the realize function of the "fsl,imx25" device | ||
13 | also uses serial_hds[] directly, so this device clearly can not be | ||
14 | instantiated twice and thus we should mark it with user_creatable = 0. | ||
15 | |||
16 | Signed-off-by: Thomas Huth <thuth@redhat.com> | ||
17 | Message-id: 1509519537-6964-3-git-send-email-thuth@redhat.com | ||
18 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
19 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
20 | --- | ||
21 | hw/arm/fsl-imx25.c | 6 +++++- | ||
22 | 1 file changed, 5 insertions(+), 1 deletion(-) | ||
23 | |||
24 | diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/hw/arm/fsl-imx25.c | ||
27 | +++ b/hw/arm/fsl-imx25.c | ||
28 | @@ -XXX,XX +XXX,XX @@ static void fsl_imx25_class_init(ObjectClass *oc, void *data) | ||
29 | DeviceClass *dc = DEVICE_CLASS(oc); | ||
30 | |||
31 | dc->realize = fsl_imx25_realize; | ||
32 | - | ||
33 | dc->desc = "i.MX25 SOC"; | ||
34 | + /* | ||
35 | + * Reason: uses serial_hds in realize and the imx25 board does not | ||
36 | + * support multiple CPUs | ||
37 | + */ | ||
38 | + dc->user_creatable = false; | ||
39 | } | ||
40 | |||
41 | static const TypeInfo fsl_imx25_type_info = { | ||
42 | -- | ||
43 | 2.7.4 | ||
44 | |||
45 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@xilinx.com> | 1 | From: Thomas Huth <thuth@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Specify the number of CPUs that can run on ZynqMP. | 3 | QEMU currently crashes when the user tries to instantiate the fsl,imx31 |
4 | device manually: | ||
4 | 5 | ||
5 | Signed-off-by: Alistair Francis <alistair.francis@xilinx.com> | 6 | $ aarch64-softmmu/qemu-system-aarch64 -M kzm -device fsl,,imx31 |
6 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 7 | ** |
7 | Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 8 | ERROR:/home/thuth/devel/qemu/tcg/tcg.c:538:tcg_register_thread: |
9 | assertion failed: (n < max_cpus) | ||
10 | Aborted (core dumped) | ||
11 | |||
12 | The kzm board (which is the one that uses this CPU type) only supports | ||
13 | one CPU, and the realize function of the "fsl,imx31" device also uses | ||
14 | serial_hds[] directly, so this device clearly can not be instantiated | ||
15 | twice and thus we should mark it with user_creatable = false. | ||
16 | |||
17 | Signed-off-by: Thomas Huth <thuth@redhat.com> | ||
18 | Message-id: 1509519537-6964-4-git-send-email-thuth@redhat.com | ||
8 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 19 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 20 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
10 | --- | 21 | --- |
11 | hw/arm/xlnx-zcu102.c | 1 + | 22 | hw/arm/fsl-imx31.c | 6 +++++- |
12 | 1 file changed, 1 insertion(+) | 23 | 1 file changed, 5 insertions(+), 1 deletion(-) |
13 | 24 | ||
14 | diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c | 25 | diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c |
15 | index XXXXXXX..XXXXXXX 100644 | 26 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/hw/arm/xlnx-zcu102.c | 27 | --- a/hw/arm/fsl-imx31.c |
17 | +++ b/hw/arm/xlnx-zcu102.c | 28 | +++ b/hw/arm/fsl-imx31.c |
18 | @@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data) | 29 | @@ -XXX,XX +XXX,XX @@ static void fsl_imx31_class_init(ObjectClass *oc, void *data) |
19 | mc->block_default_type = IF_IDE; | 30 | DeviceClass *dc = DEVICE_CLASS(oc); |
20 | mc->units_per_default_bus = 1; | 31 | |
21 | mc->ignore_memory_transaction_failures = true; | 32 | dc->realize = fsl_imx31_realize; |
22 | + mc->max_cpus = XLNX_ZYNQMP_NUM_APU_CPUS + XLNX_ZYNQMP_NUM_RPU_CPUS; | 33 | - |
34 | dc->desc = "i.MX31 SOC"; | ||
35 | + /* | ||
36 | + * Reason: uses serial_hds in realize and the kzm board does not | ||
37 | + * support multiple CPUs | ||
38 | + */ | ||
39 | + dc->user_creatable = false; | ||
23 | } | 40 | } |
24 | 41 | ||
25 | static const TypeInfo xlnx_zcu102_machine_init_typeinfo = { | 42 | static const TypeInfo fsl_imx31_type_info = { |
26 | -- | 43 | -- |
27 | 2.7.4 | 44 | 2.7.4 |
28 | 45 | ||
29 | 46 | diff view generated by jsdifflib |
1 | From: Stefano Stabellini <sstabellini@kernel.org> | 1 | For AArch32 LDREXD and STREXD, architecturally the 32-bit word at the |
---|---|---|---|
2 | lowest address is always Rt and the one at addr+4 is Rt2, even if the | ||
3 | CPU is big-endian. Our implementation does these with a single | ||
4 | 64-bit store, so if we're big-endian then we need to put the two | ||
5 | 32-bit halves together in the opposite order to little-endian, | ||
6 | so that they end up in the right places. We were trying to do | ||
7 | this with the gen_aa32_frob64() function, but that is not correct | ||
8 | for the usermode emulator, because there there is a distinction | ||
9 | between "load a 64 bit value" (which does a BE 64-bit access | ||
10 | and doesn't need swapping) and "load two 32 bit values as one | ||
11 | 64 bit access" (where we still need to do the swapping, like | ||
12 | system mode BE32). | ||
2 | 13 | ||
3 | WFI/E are often, but not always, 4 bytes long. When they are, we need to | 14 | Fixes: https://bugs.launchpad.net/qemu/+bug/1725267 |
4 | set ARM_EL_IL_SHIFT in the syndrome register. | 15 | Cc: qemu-stable@nongnu.org |
16 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
17 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
18 | Message-id: 1509622400-13351-1-git-send-email-peter.maydell@linaro.org | ||
19 | --- | ||
20 | target/arm/translate.c | 39 ++++++++++++++++++++++++++++++++++----- | ||
21 | 1 file changed, 34 insertions(+), 5 deletions(-) | ||
5 | 22 | ||
6 | Pass the instruction length to HELPER(wfi), use it to decrement pc | ||
7 | appropriately and to pass an is_16bit flag to syn_wfx, which sets | ||
8 | ARM_EL_IL_SHIFT if needed. | ||
9 | |||
10 | Set dc->insn in both arm_tr_translate_insn and thumb_tr_translate_insn. | ||
11 | |||
12 | Signed-off-by: Stefano Stabellini <sstabellini@kernel.org> | ||
13 | Message-id: alpine.DEB.2.10.1710241055160.574@sstabellini-ThinkPad-X260 | ||
14 | [PMM: move setting of dc->insn for Thumb so it is correct for 32 bit insns] | ||
15 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
16 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
17 | --- | ||
18 | target/arm/helper.h | 2 +- | ||
19 | target/arm/internals.h | 3 ++- | ||
20 | target/arm/op_helper.c | 7 ++++--- | ||
21 | target/arm/psci.c | 2 +- | ||
22 | target/arm/translate-a64.c | 7 ++++++- | ||
23 | target/arm/translate.c | 10 +++++++++- | ||
24 | 6 files changed, 23 insertions(+), 8 deletions(-) | ||
25 | |||
26 | diff --git a/target/arm/helper.h b/target/arm/helper.h | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/target/arm/helper.h | ||
29 | +++ b/target/arm/helper.h | ||
30 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE, | ||
31 | DEF_HELPER_2(exception_internal, void, env, i32) | ||
32 | DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32) | ||
33 | DEF_HELPER_1(setend, void, env) | ||
34 | -DEF_HELPER_1(wfi, void, env) | ||
35 | +DEF_HELPER_2(wfi, void, env, i32) | ||
36 | DEF_HELPER_1(wfe, void, env) | ||
37 | DEF_HELPER_1(yield, void, env) | ||
38 | DEF_HELPER_1(pre_hvc, void, env) | ||
39 | diff --git a/target/arm/internals.h b/target/arm/internals.h | ||
40 | index XXXXXXX..XXXXXXX 100644 | ||
41 | --- a/target/arm/internals.h | ||
42 | +++ b/target/arm/internals.h | ||
43 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_breakpoint(int same_el) | ||
44 | | ARM_EL_IL | 0x22; | ||
45 | } | ||
46 | |||
47 | -static inline uint32_t syn_wfx(int cv, int cond, int ti) | ||
48 | +static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit) | ||
49 | { | ||
50 | return (EC_WFX_TRAP << ARM_EL_EC_SHIFT) | | ||
51 | + (is_16bit ? 0 : (1 << ARM_EL_IL_SHIFT)) | | ||
52 | (cv << 24) | (cond << 20) | ti; | ||
53 | } | ||
54 | |||
55 | diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c | ||
56 | index XXXXXXX..XXXXXXX 100644 | ||
57 | --- a/target/arm/op_helper.c | ||
58 | +++ b/target/arm/op_helper.c | ||
59 | @@ -XXX,XX +XXX,XX @@ static inline int check_wfx_trap(CPUARMState *env, bool is_wfe) | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | -void HELPER(wfi)(CPUARMState *env) | ||
64 | +void HELPER(wfi)(CPUARMState *env, uint32_t insn_len) | ||
65 | { | ||
66 | CPUState *cs = CPU(arm_env_get_cpu(env)); | ||
67 | int target_el = check_wfx_trap(env, false); | ||
68 | @@ -XXX,XX +XXX,XX @@ void HELPER(wfi)(CPUARMState *env) | ||
69 | } | ||
70 | |||
71 | if (target_el) { | ||
72 | - env->pc -= 4; | ||
73 | - raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0), target_el); | ||
74 | + env->pc -= insn_len; | ||
75 | + raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0, insn_len == 2), | ||
76 | + target_el); | ||
77 | } | ||
78 | |||
79 | cs->exception_index = EXCP_HLT; | ||
80 | diff --git a/target/arm/psci.c b/target/arm/psci.c | ||
81 | index XXXXXXX..XXXXXXX 100644 | ||
82 | --- a/target/arm/psci.c | ||
83 | +++ b/target/arm/psci.c | ||
84 | @@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu) | ||
85 | } else { | ||
86 | env->regs[0] = 0; | ||
87 | } | ||
88 | - helper_wfi(env); | ||
89 | + helper_wfi(env, 4); | ||
90 | break; | ||
91 | case QEMU_PSCI_0_1_FN_MIGRATE: | ||
92 | case QEMU_PSCI_0_2_FN_MIGRATE: | ||
93 | diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c | ||
94 | index XXXXXXX..XXXXXXX 100644 | ||
95 | --- a/target/arm/translate-a64.c | ||
96 | +++ b/target/arm/translate-a64.c | ||
97 | @@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) | ||
98 | gen_helper_yield(cpu_env); | ||
99 | break; | ||
100 | case DISAS_WFI: | ||
101 | + { | ||
102 | /* This is a special case because we don't want to just halt the CPU | ||
103 | * if trying to debug across a WFI. | ||
104 | */ | ||
105 | + TCGv_i32 tmp = tcg_const_i32(4); | ||
106 | + | ||
107 | gen_a64_set_pc_im(dc->pc); | ||
108 | - gen_helper_wfi(cpu_env); | ||
109 | + gen_helper_wfi(cpu_env, tmp); | ||
110 | + tcg_temp_free_i32(tmp); | ||
111 | /* The helper doesn't necessarily throw an exception, but we | ||
112 | * must go back to the main loop to check for interrupts anyway. | ||
113 | */ | ||
114 | tcg_gen_exit_tb(0); | ||
115 | break; | ||
116 | } | ||
117 | + } | ||
118 | } | ||
119 | |||
120 | /* Functions above can change dc->pc, so re-align db->pc_next */ | ||
121 | diff --git a/target/arm/translate.c b/target/arm/translate.c | 23 | diff --git a/target/arm/translate.c b/target/arm/translate.c |
122 | index XXXXXXX..XXXXXXX 100644 | 24 | index XXXXXXX..XXXXXXX 100644 |
123 | --- a/target/arm/translate.c | 25 | --- a/target/arm/translate.c |
124 | +++ b/target/arm/translate.c | 26 | +++ b/target/arm/translate.c |
125 | @@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) | 27 | @@ -XXX,XX +XXX,XX @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2, |
126 | } | 28 | TCGv_i32 tmp2 = tcg_temp_new_i32(); |
127 | 29 | TCGv_i64 t64 = tcg_temp_new_i64(); | |
128 | insn = arm_ldl_code(env, dc->pc, dc->sctlr_b); | 30 | |
129 | + dc->insn = insn; | 31 | - gen_aa32_ld_i64(s, t64, addr, get_mem_index(s), opc); |
130 | dc->pc += 4; | 32 | + /* For AArch32, architecturally the 32-bit word at the lowest |
131 | disas_arm_insn(dc, insn); | 33 | + * address is always Rt and the one at addr+4 is Rt2, even if |
132 | 34 | + * the CPU is big-endian. That means we don't want to do a | |
133 | @@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) | 35 | + * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if |
134 | insn = insn << 16 | insn2; | 36 | + * for an architecturally 64-bit access, but instead do a |
135 | dc->pc += 2; | 37 | + * 64-bit access using MO_BE if appropriate and then split |
136 | } | 38 | + * the two halves. |
137 | + dc->insn = insn; | 39 | + * This only makes a difference for BE32 user-mode, where |
138 | 40 | + * frob64() must not flip the two halves of the 64-bit data | |
139 | if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) { | 41 | + * but this code must treat BE32 user-mode like BE32 system. |
140 | uint32_t cond = dc->condexec_cond; | 42 | + */ |
141 | @@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) | 43 | + TCGv taddr = gen_aa32_addr(s, addr, opc); |
142 | /* nothing more to generate */ | ||
143 | break; | ||
144 | case DISAS_WFI: | ||
145 | - gen_helper_wfi(cpu_env); | ||
146 | + { | ||
147 | + TCGv_i32 tmp = tcg_const_i32((dc->thumb && | ||
148 | + !(dc->insn & (1U << 31))) ? 2 : 4); | ||
149 | + | 44 | + |
150 | + gen_helper_wfi(cpu_env, tmp); | 45 | + tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc); |
151 | + tcg_temp_free_i32(tmp); | 46 | + tcg_temp_free(taddr); |
152 | /* The helper doesn't necessarily throw an exception, but we | 47 | tcg_gen_mov_i64(cpu_exclusive_val, t64); |
153 | * must go back to the main loop to check for interrupts anyway. | 48 | - tcg_gen_extr_i64_i32(tmp, tmp2, t64); |
154 | */ | 49 | + if (s->be_data == MO_BE) { |
155 | tcg_gen_exit_tb(0); | 50 | + tcg_gen_extr_i64_i32(tmp2, tmp, t64); |
156 | break; | 51 | + } else { |
52 | + tcg_gen_extr_i64_i32(tmp, tmp2, t64); | ||
157 | + } | 53 | + } |
158 | case DISAS_WFE: | 54 | tcg_temp_free_i64(t64); |
159 | gen_helper_wfe(cpu_env); | 55 | |
160 | break; | 56 | store_reg(s, rt2, tmp2); |
57 | @@ -XXX,XX +XXX,XX @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, | ||
58 | TCGv_i64 n64 = tcg_temp_new_i64(); | ||
59 | |||
60 | t2 = load_reg(s, rt2); | ||
61 | - tcg_gen_concat_i32_i64(n64, t1, t2); | ||
62 | + /* For AArch32, architecturally the 32-bit word at the lowest | ||
63 | + * address is always Rt and the one at addr+4 is Rt2, even if | ||
64 | + * the CPU is big-endian. Since we're going to treat this as a | ||
65 | + * single 64-bit BE store, we need to put the two halves in the | ||
66 | + * opposite order for BE to LE, so that they end up in the right | ||
67 | + * places. | ||
68 | + * We don't want gen_aa32_frob64() because that does the wrong | ||
69 | + * thing for BE32 usermode. | ||
70 | + */ | ||
71 | + if (s->be_data == MO_BE) { | ||
72 | + tcg_gen_concat_i32_i64(n64, t2, t1); | ||
73 | + } else { | ||
74 | + tcg_gen_concat_i32_i64(n64, t1, t2); | ||
75 | + } | ||
76 | tcg_temp_free_i32(t2); | ||
77 | - gen_aa32_frob64(s, n64); | ||
78 | |||
79 | tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64, | ||
80 | get_mem_index(s), opc); | ||
81 | tcg_temp_free_i64(n64); | ||
82 | |||
83 | - gen_aa32_frob64(s, o64); | ||
84 | tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val); | ||
85 | tcg_gen_extrl_i64_i32(t0, o64); | ||
86 | |||
161 | -- | 87 | -- |
162 | 2.7.4 | 88 | 2.7.4 |
163 | 89 | ||
164 | 90 | diff view generated by jsdifflib |
1 | From: Subbaraya Sundeep <sundeep.lkml@gmail.com> | 1 | From: Shanker Donthineni <shankerd@codeaurora.org> |
---|---|---|---|
2 | 2 | ||
3 | Fixed incorrect frame size mask, validated maximum frame | 3 | The commit cddafd8f353d ("hw/intc/arm_gicv3_its: Implement state save |
4 | size in spi_write and removed dead code. | 4 | /restore") breaks the backward compatibility with the older kernels |
5 | where vITS save/restore support is not available. The vmstate function | ||
6 | vm_change_state_handler() should not be registered if the running kernel | ||
7 | doesn't support ITS save/restore feature. Otherwise VM instance will be | ||
8 | killed whenever vmstate callback function is invoked. | ||
5 | 9 | ||
6 | Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com> | 10 | Observed a virtual machine shutdown with QEMU-2.10+linux-4.11 when testing |
7 | Reviewed-by: Darren Kenny <darren.kenny@oracle.com> | 11 | the reboot command "virsh reboot <domain> --mode acpi" instead of reboot. |
8 | Reviewed-by: Alistair Francis <alistair.francis@xilinx.com> | 12 | |
9 | Message-id: 1508898544-10307-1-git-send-email-sundeep.lkml@gmail.com | 13 | KVM Error: 'KVM_SET_DEVICE_ATTR failed: Group 4 attr 0x00000000000001' |
14 | |||
15 | Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org> | ||
16 | Reviewed-by: Eric Auger <eric.auger@redhat.com> | ||
17 | Message-id: 1509712671-16299-1-git-send-email-shankerd@codeaurora.org | ||
10 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 18 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
11 | --- | 19 | --- |
12 | hw/ssi/mss-spi.c | 18 ++++++++++++++---- | 20 | hw/intc/arm_gicv3_its_kvm.c | 4 ++-- |
13 | 1 file changed, 14 insertions(+), 4 deletions(-) | 21 | 1 file changed, 2 insertions(+), 2 deletions(-) |
14 | 22 | ||
15 | diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c | 23 | diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c |
16 | index XXXXXXX..XXXXXXX 100644 | 24 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/hw/ssi/mss-spi.c | 25 | --- a/hw/intc/arm_gicv3_its_kvm.c |
18 | +++ b/hw/ssi/mss-spi.c | 26 | +++ b/hw/intc/arm_gicv3_its_kvm.c |
19 | @@ -XXX,XX +XXX,XX @@ | 27 | @@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp) |
20 | #define C_BIGFIFO (1 << 29) | 28 | error_free(s->migration_blocker); |
21 | #define C_RESET (1 << 31) | 29 | return; |
22 | 30 | } | |
23 | -#define FRAMESZ_MASK 0x1F | 31 | + } else { |
24 | +#define FRAMESZ_MASK 0x3F | 32 | + qemu_add_vm_change_state_handler(vm_change_state_handler, s); |
25 | #define FMCOUNT_MASK 0x00FFFF00 | ||
26 | #define FMCOUNT_SHIFT 8 | ||
27 | +#define FRAMESZ_MAX 32 | ||
28 | |||
29 | static void txfifo_reset(MSSSpiState *s) | ||
30 | { | ||
31 | @@ -XXX,XX +XXX,XX @@ static void set_fifodepth(MSSSpiState *s) | ||
32 | s->fifo_depth = 32; | ||
33 | } else if (size <= 16) { | ||
34 | s->fifo_depth = 16; | ||
35 | - } else if (size <= 32) { | ||
36 | - s->fifo_depth = 8; | ||
37 | } else { | ||
38 | - s->fifo_depth = 4; | ||
39 | + s->fifo_depth = 8; | ||
40 | } | 33 | } |
34 | |||
35 | kvm_msi_use_devid = true; | ||
36 | kvm_gsi_direct_mapping = false; | ||
37 | kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled(); | ||
38 | - | ||
39 | - qemu_add_vm_change_state_handler(vm_change_state_handler, s); | ||
41 | } | 40 | } |
42 | 41 | ||
43 | @@ -XXX,XX +XXX,XX @@ static void spi_write(void *opaque, hwaddr addr, | 42 | /** |
44 | if (s->enabled) { | ||
45 | break; | ||
46 | } | ||
47 | + /* | ||
48 | + * [31:6] bits are reserved bits and for future use. | ||
49 | + * [5:0] are for frame size. Only [5:0] bits are validated | ||
50 | + * during write, [31:6] bits are untouched. | ||
51 | + */ | ||
52 | + if ((value & FRAMESZ_MASK) > FRAMESZ_MAX) { | ||
53 | + qemu_log_mask(LOG_GUEST_ERROR, "%s: Incorrect size %u provided." | ||
54 | + "Maximum frame size is %u\n", | ||
55 | + __func__, value & FRAMESZ_MASK, FRAMESZ_MAX); | ||
56 | + break; | ||
57 | + } | ||
58 | s->regs[R_SPI_DFSIZE] = value; | ||
59 | break; | ||
60 | |||
61 | -- | 43 | -- |
62 | 2.7.4 | 44 | 2.7.4 |
63 | 45 | ||
64 | 46 | diff view generated by jsdifflib |
1 | From: Eric Auger <eric.auger@redhat.com> | 1 | From: Eric Auger <eric.auger@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | We exposed gpex_set_irq_num() for machines to set the INTx to | 3 | The ITS is not fully properly reset at the moment. Caches are |
4 | GSI routing. However if the machine forgets to call that | 4 | not emptied. |
5 | function we currently do not check the association was properly | ||
6 | done. Let's initialize gsi values to -1 and if this value is | ||
7 | found in gpex_route_intx_pin_to_irq, set the routing mode as | ||
8 | disabled. | ||
9 | 5 | ||
6 | After a reset, in case we attempt to save the state before | ||
7 | the bound devices have registered their MSIs and after the | ||
8 | 1st level table has been allocated by the ITS driver | ||
9 | (device BASER is valid), the first level entries are still | ||
10 | invalid. If the device cache is not empty (devices registered | ||
11 | before the reset), vgic_its_save_device_tables fails with -EINVAL. | ||
12 | This causes a QEMU abort(). | ||
13 | |||
14 | Cc: qemu-stable@nongnu.org | ||
10 | Signed-off-by: Eric Auger <eric.auger@redhat.com> | 15 | Signed-off-by: Eric Auger <eric.auger@redhat.com> |
11 | Message-id: 1508776211-22175-1-git-send-email-eric.auger@redhat.com | 16 | Reported-by: wanghaibin <wanghaibin.wang@huawei.com> |
12 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 17 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
13 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 18 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
14 | --- | 19 | --- |
15 | hw/pci-host/gpex.c | 10 ++++++++-- | 20 | hw/intc/arm_gicv3_its_kvm.c | 8 ++------ |
16 | 1 file changed, 8 insertions(+), 2 deletions(-) | 21 | 1 file changed, 2 insertions(+), 6 deletions(-) |
17 | 22 | ||
18 | diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c | 23 | diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c |
19 | index XXXXXXX..XXXXXXX 100644 | 24 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/hw/pci-host/gpex.c | 25 | --- a/hw/intc/arm_gicv3_its_kvm.c |
21 | +++ b/hw/pci-host/gpex.c | 26 | +++ b/hw/intc/arm_gicv3_its_kvm.c |
22 | @@ -XXX,XX +XXX,XX @@ static PCIINTxRoute gpex_route_intx_pin_to_irq(void *opaque, int pin) | 27 | @@ -XXX,XX +XXX,XX @@ static void vm_change_state_handler(void *opaque, int running, |
23 | { | 28 | { |
24 | PCIINTxRoute route; | 29 | GICv3ITSState *s = (GICv3ITSState *)opaque; |
25 | GPEXHost *s = opaque; | 30 | Error *err = NULL; |
26 | + int gsi = s->irq_num[pin]; | 31 | - int ret; |
27 | 32 | ||
28 | - route.mode = PCI_INTX_ENABLED; | 33 | if (running) { |
29 | - route.irq = s->irq_num[pin]; | 34 | return; |
30 | + route.irq = gsi; | 35 | } |
31 | + if (gsi < 0) { | 36 | |
32 | + route.mode = PCI_INTX_DISABLED; | 37 | - ret = kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL, |
33 | + } else { | 38 | - KVM_DEV_ARM_ITS_SAVE_TABLES, NULL, true, &err); |
34 | + route.mode = PCI_INTX_ENABLED; | 39 | + kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL, |
35 | + } | 40 | + KVM_DEV_ARM_ITS_SAVE_TABLES, NULL, true, &err); |
36 | 41 | if (err) { | |
37 | return route; | 42 | error_report_err(err); |
43 | } | ||
44 | - if (ret < 0 && ret != -EFAULT) { | ||
45 | - abort(); | ||
46 | - } | ||
38 | } | 47 | } |
39 | @@ -XXX,XX +XXX,XX @@ static void gpex_host_realize(DeviceState *dev, Error **errp) | 48 | |
40 | sysbus_init_mmio(sbd, &s->io_ioport); | 49 | static void kvm_arm_its_realize(DeviceState *dev, Error **errp) |
41 | for (i = 0; i < GPEX_NUM_IRQS; i++) { | ||
42 | sysbus_init_irq(sbd, &s->irq[i]); | ||
43 | + s->irq_num[i] = -1; | ||
44 | } | ||
45 | |||
46 | pci->bus = pci_register_bus(dev, "pcie.0", gpex_set_irq, | ||
47 | -- | 50 | -- |
48 | 2.7.4 | 51 | 2.7.4 |
49 | 52 | ||
50 | 53 | diff view generated by jsdifflib |