1 | Hi; this is a collection of mostly GIC related patches for rc3. | 1 | v2: drop pvpanic-pci patches. |
---|---|---|---|
2 | The "Update cached state after LPI state changes" fix is important | ||
3 | and fixes what would otherwise be a regression since we enable the | ||
4 | ITS by default in the virt board now. The others are not regressions | ||
5 | but I think are OK for rc3 as they're fairly self contained (and two | ||
6 | of them are fixes to new-in-6.2 functionality). | ||
7 | 2 | ||
8 | thanks | 3 | The following changes since commit f1fcb6851aba6dd9838886dc179717a11e344a1c: |
9 | -- PMM | ||
10 | 4 | ||
11 | The following changes since commit dd4b0de45965538f19bb40c7ddaaba384a8c613a: | 5 | Merge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2021-01-19' into staging (2021-01-19 11:57:07 +0000) |
12 | |||
13 | Fix version for v6.2.0-rc2 release (2021-11-26 11:58:54 +0100) | ||
14 | 6 | ||
15 | are available in the Git repository at: | 7 | are available in the Git repository at: |
16 | 8 | ||
17 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20211129 | 9 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210119-1 |
18 | 10 | ||
19 | for you to fetch changes up to 90feffad2aafe856ed2af75313b2c1669ba671e9: | 11 | for you to fetch changes up to b93f4fbdc48283a39089469c44a5529d79dc40a8: |
20 | 12 | ||
21 | hw/intc/arm_gicv3: fix handling of LPIs in list registers (2021-11-29 10:10:21 +0000) | 13 | docs: Build and install all the docs in a single manual (2021-01-19 15:45:14 +0000) |
22 | 14 | ||
23 | ---------------------------------------------------------------- | 15 | ---------------------------------------------------------------- |
24 | target-arm queue: | 16 | target-arm queue: |
25 | * virt: Diagnose attempts to enable MTE or virt when using HVF accelerator | 17 | * Implement IMPDEF pauth algorithm |
26 | * GICv3 ITS: Allow clearing of ITS CTLR Enabled bit | 18 | * Support ARMv8.4-SEL2 |
27 | * GICv3: Update cached state after LPI state changes | 19 | * Fix bug where we were truncating predicate vector lengths in SVE insns |
28 | * GICv3: Fix handling of LPIs in list registers | 20 | * npcm7xx_adc-test: Fix memleak in adc_qom_set |
21 | * target/arm/m_helper: Silence GCC 10 maybe-uninitialized error | ||
22 | * docs: Build and install all the docs in a single manual | ||
29 | 23 | ||
30 | ---------------------------------------------------------------- | 24 | ---------------------------------------------------------------- |
31 | Alexander Graf (1): | 25 | Gan Qixin (1): |
32 | hw/arm/virt: Extend nested and mte checks to hvf | 26 | npcm7xx_adc-test: Fix memleak in adc_qom_set |
33 | 27 | ||
34 | Peter Maydell (3): | 28 | Peter Maydell (1): |
35 | hw/intc/arm_gicv3: Update cached state after LPI state changes | 29 | docs: Build and install all the docs in a single manual |
36 | hw/intc/arm_gicv3: Add new gicv3_intid_is_special() function | ||
37 | hw/intc/arm_gicv3: fix handling of LPIs in list registers | ||
38 | 30 | ||
39 | Shashi Mallela (1): | 31 | Philippe Mathieu-Daudé (1): |
40 | hw/intc: cannot clear GICv3 ITS CTLR[Enabled] bit | 32 | target/arm/m_helper: Silence GCC 10 maybe-uninitialized error |
41 | 33 | ||
42 | hw/intc/gicv3_internal.h | 30 ++++++++++++++++++++++++++++++ | 34 | Richard Henderson (7): |
43 | hw/arm/virt.c | 15 +++++++++------ | 35 | target/arm: Implement an IMPDEF pauth algorithm |
44 | hw/intc/arm_gicv3.c | 6 ++++-- | 36 | target/arm: Add cpu properties to control pauth |
45 | hw/intc/arm_gicv3_cpuif.c | 9 ++++----- | 37 | target/arm: Use object_property_add_bool for "sve" property |
46 | hw/intc/arm_gicv3_its.c | 7 ++++--- | 38 | target/arm: Introduce PREDDESC field definitions |
47 | hw/intc/arm_gicv3_redist.c | 14 ++++++++++---- | 39 | target/arm: Update PFIRST, PNEXT for pred_desc |
48 | 6 files changed, 61 insertions(+), 20 deletions(-) | 40 | target/arm: Update ZIP, UZP, TRN for pred_desc |
41 | target/arm: Update REV, PUNPK for pred_desc | ||
49 | 42 | ||
43 | Rémi Denis-Courmont (19): | ||
44 | target/arm: remove redundant tests | ||
45 | target/arm: add arm_is_el2_enabled() helper | ||
46 | target/arm: use arm_is_el2_enabled() where applicable | ||
47 | target/arm: use arm_hcr_el2_eff() where applicable | ||
48 | target/arm: factor MDCR_EL2 common handling | ||
49 | target/arm: Define isar_feature function to test for presence of SEL2 | ||
50 | target/arm: add 64-bit S-EL2 to EL exception table | ||
51 | target/arm: add MMU stage 1 for Secure EL2 | ||
52 | target/arm: add ARMv8.4-SEL2 system registers | ||
53 | target/arm: handle VMID change in secure state | ||
54 | target/arm: do S1_ptw_translate() before address space lookup | ||
55 | target/arm: translate NS bit in page-walks | ||
56 | target/arm: generalize 2-stage page-walk condition | ||
57 | target/arm: secure stage 2 translation regime | ||
58 | target/arm: set HPFAR_EL2.NS on secure stage 2 faults | ||
59 | target/arm: revector to run-time pick target EL | ||
60 | target/arm: Implement SCR_EL2.EEL2 | ||
61 | target/arm: enable Secure EL2 in max CPU | ||
62 | target/arm: refactor vae1_tlbmask() | ||
63 | |||
64 | docs/conf.py | 46 ++++- | ||
65 | docs/devel/conf.py | 15 -- | ||
66 | docs/index.html.in | 17 -- | ||
67 | docs/interop/conf.py | 28 --- | ||
68 | docs/meson.build | 64 +++--- | ||
69 | docs/specs/conf.py | 16 -- | ||
70 | docs/system/arm/cpu-features.rst | 21 ++ | ||
71 | docs/system/conf.py | 28 --- | ||
72 | docs/tools/conf.py | 37 ---- | ||
73 | docs/user/conf.py | 15 -- | ||
74 | include/qemu/xxhash.h | 98 +++++++++ | ||
75 | target/arm/cpu-param.h | 2 +- | ||
76 | target/arm/cpu.h | 107 ++++++++-- | ||
77 | target/arm/internals.h | 45 +++++ | ||
78 | target/arm/cpu.c | 23 ++- | ||
79 | target/arm/cpu64.c | 65 ++++-- | ||
80 | target/arm/helper-a64.c | 8 +- | ||
81 | target/arm/helper.c | 414 ++++++++++++++++++++++++++------------- | ||
82 | target/arm/m_helper.c | 2 +- | ||
83 | target/arm/monitor.c | 1 + | ||
84 | target/arm/op_helper.c | 4 +- | ||
85 | target/arm/pauth_helper.c | 27 ++- | ||
86 | target/arm/sve_helper.c | 33 ++-- | ||
87 | target/arm/tlb_helper.c | 3 + | ||
88 | target/arm/translate-a64.c | 4 + | ||
89 | target/arm/translate-sve.c | 31 ++- | ||
90 | target/arm/translate.c | 36 +++- | ||
91 | tests/qtest/arm-cpu-features.c | 13 ++ | ||
92 | tests/qtest/npcm7xx_adc-test.c | 1 + | ||
93 | .gitlab-ci.yml | 4 +- | ||
94 | 30 files changed, 770 insertions(+), 438 deletions(-) | ||
95 | delete mode 100644 docs/devel/conf.py | ||
96 | delete mode 100644 docs/index.html.in | ||
97 | delete mode 100644 docs/interop/conf.py | ||
98 | delete mode 100644 docs/specs/conf.py | ||
99 | delete mode 100644 docs/system/conf.py | ||
100 | delete mode 100644 docs/tools/conf.py | ||
101 | delete mode 100644 docs/user/conf.py | ||
102 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alexander Graf <agraf@csgraf.de> | ||
2 | 1 | ||
3 | The virt machine has properties to enable MTE and Nested Virtualization | ||
4 | support. However, its check to ensure the backing accel implementation | ||
5 | supports it today only looks for KVM and bails out if it finds it. | ||
6 | |||
7 | Extend the checks to HVF as well as it does not support either today. | ||
8 | This will cause QEMU to print a useful error message rather than | ||
9 | silently ignoring the attempt by the user to enable either MTE or | ||
10 | the Virtualization extensions. | ||
11 | |||
12 | Reported-by: saar amar <saaramar5@gmail.com> | ||
13 | Signed-off-by: Alexander Graf <agraf@csgraf.de> | ||
14 | Message-id: 20211123122859.22452-1-agraf@csgraf.de | ||
15 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
16 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
17 | --- | ||
18 | hw/arm/virt.c | 15 +++++++++------ | ||
19 | 1 file changed, 9 insertions(+), 6 deletions(-) | ||
20 | |||
21 | diff --git a/hw/arm/virt.c b/hw/arm/virt.c | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/hw/arm/virt.c | ||
24 | +++ b/hw/arm/virt.c | ||
25 | @@ -XXX,XX +XXX,XX @@ | ||
26 | #include "sysemu/runstate.h" | ||
27 | #include "sysemu/tpm.h" | ||
28 | #include "sysemu/kvm.h" | ||
29 | +#include "sysemu/hvf.h" | ||
30 | #include "hw/loader.h" | ||
31 | #include "qapi/error.h" | ||
32 | #include "qemu/bitops.h" | ||
33 | @@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine) | ||
34 | exit(1); | ||
35 | } | ||
36 | |||
37 | - if (vms->virt && kvm_enabled()) { | ||
38 | - error_report("mach-virt: KVM does not support providing " | ||
39 | - "Virtualization extensions to the guest CPU"); | ||
40 | + if (vms->virt && (kvm_enabled() || hvf_enabled())) { | ||
41 | + error_report("mach-virt: %s does not support providing " | ||
42 | + "Virtualization extensions to the guest CPU", | ||
43 | + kvm_enabled() ? "KVM" : "HVF"); | ||
44 | exit(1); | ||
45 | } | ||
46 | |||
47 | - if (vms->mte && kvm_enabled()) { | ||
48 | - error_report("mach-virt: KVM does not support providing " | ||
49 | - "MTE to the guest CPU"); | ||
50 | + if (vms->mte && (kvm_enabled() || hvf_enabled())) { | ||
51 | + error_report("mach-virt: %s does not support providing " | ||
52 | + "MTE to the guest CPU", | ||
53 | + kvm_enabled() ? "KVM" : "HVF"); | ||
54 | exit(1); | ||
55 | } | ||
56 | |||
57 | -- | ||
58 | 2.25.1 | ||
59 | |||
60 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Shashi Mallela <shashi.mallela@linaro.org> | ||
2 | 1 | ||
3 | When Enabled bit is cleared in GITS_CTLR,ITS feature continues | ||
4 | to be enabled.This patch fixes the issue. | ||
5 | |||
6 | Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org> | ||
7 | Tested-by: Alex Bennée <alex.bennee@linaro.org> | ||
8 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
9 | Message-id: 20211124182246.67691-1-shashi.mallela@linaro.org | ||
10 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
11 | --- | ||
12 | hw/intc/arm_gicv3_its.c | 7 ++++--- | ||
13 | 1 file changed, 4 insertions(+), 3 deletions(-) | ||
14 | |||
15 | diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/hw/intc/arm_gicv3_its.c | ||
18 | +++ b/hw/intc/arm_gicv3_its.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset, | ||
20 | |||
21 | switch (offset) { | ||
22 | case GITS_CTLR: | ||
23 | - s->ctlr |= (value & ~(s->ctlr)); | ||
24 | - | ||
25 | - if (s->ctlr & ITS_CTLR_ENABLED) { | ||
26 | + if (value & R_GITS_CTLR_ENABLED_MASK) { | ||
27 | + s->ctlr |= ITS_CTLR_ENABLED; | ||
28 | extract_table_params(s); | ||
29 | extract_cmdq_params(s); | ||
30 | s->creadr = 0; | ||
31 | process_cmdq(s); | ||
32 | + } else { | ||
33 | + s->ctlr &= ~ITS_CTLR_ENABLED; | ||
34 | } | ||
35 | break; | ||
36 | case GITS_CBASER: | ||
37 | -- | ||
38 | 2.25.1 | ||
39 | |||
40 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | The logic of gicv3_redist_update() is as follows: | ||
2 | * it must be called in any code path that changes the state of | ||
3 | (only) redistributor interrupts | ||
4 | * if it finds a redistributor interrupt that is (now) higher | ||
5 | priority than the previous highest-priority pending interrupt, | ||
6 | then this must be the new highest-priority pending interrupt | ||
7 | * if it does *not* find a better redistributor interrupt, then: | ||
8 | - if the previous state was "no interrupts pending" then | ||
9 | the new state is still "no interrupts pending" | ||
10 | - if the previous best interrupt was not a redistributor | ||
11 | interrupt then that remains the best interrupt | ||
12 | - if the previous best interrupt *was* a redistributor interrupt, | ||
13 | then the new best interrupt must be some non-redistributor | ||
14 | interrupt, but we don't know which so must do a full scan | ||
15 | 1 | ||
16 | In commit 17fb5e36aabd4b2c125 we effectively added the LPI interrupts | ||
17 | as a kind of "redistributor interrupt" for this purpose, by adding | ||
18 | cs->hpplpi to the set of things that gicv3_redist_update() considers | ||
19 | before it gives up and decides to do a full scan of distributor | ||
20 | interrupts. However we didn't quite get this right: | ||
21 | * the condition check for "was the previous best interrupt a | ||
22 | redistributor interrupt" must be updated to include LPIs | ||
23 | in what it considers to be redistributor interrupts | ||
24 | * every code path which updates the LPI state which | ||
25 | gicv3_redist_update() checks must also call gicv3_redist_update(): | ||
26 | this is cs->hpplpi and the GICR_CTLR ENABLE_LPIS bit | ||
27 | |||
28 | This commit fixes this by: | ||
29 | * correcting the test on cs->hppi.irq in gicv3_redist_update() | ||
30 | * making gicv3_redist_update_lpi() always call gicv3_redist_update() | ||
31 | * introducing a new gicv3_redist_update_lpi_only() for the one | ||
32 | callsite (the post-load hook) which must not call | ||
33 | gicv3_redist_update() | ||
34 | * making gicv3_redist_lpi_pending() always call gicv3_redist_update(), | ||
35 | either directly or via gicv3_redist_update_lpi() | ||
36 | * removing a couple of now-unnecessary calls to gicv3_redist_update() | ||
37 | from some callers of those two functions | ||
38 | * calling gicv3_redist_update() when the GICR_CTLR ENABLE_LPIS | ||
39 | bit is cleared | ||
40 | |||
41 | (This means that the not-file-local gicv3_redist_* LPI related | ||
42 | functions now all take care of the updates of internally cached | ||
43 | GICv3 information, in the same way the older functions | ||
44 | gicv3_redist_set_irq() and gicv3_redist_send_sgi() do.) | ||
45 | |||
46 | The visible effect of this bug was that when the guest acknowledged | ||
47 | an LPI by reading ICC_IAR1_EL1, we marked it as not pending in the | ||
48 | LPI data structure but still left it in cs->hppi so we would offer it | ||
49 | to the guest again. In particular for setups using an emulated GICv3 | ||
50 | and ITS and using devices which use LPIs (ie PCI devices) a Linux | ||
51 | guest would complain "irq 54: nobody cared" and then hang. (The hang | ||
52 | was intermittent, presumably depending on the timing between | ||
53 | different interrupts arriving and being completed.) | ||
54 | |||
55 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
56 | Tested-by: Alex Bennée <alex.bennee@linaro.org> | ||
57 | Reviewed-by: Alex Bennée <alex.bennee@linaro.org> | ||
58 | Message-id: 20211124202005.989935-1-peter.maydell@linaro.org | ||
59 | --- | ||
60 | hw/intc/gicv3_internal.h | 17 +++++++++++++++++ | ||
61 | hw/intc/arm_gicv3.c | 6 ++++-- | ||
62 | hw/intc/arm_gicv3_redist.c | 14 ++++++++++---- | ||
63 | 3 files changed, 31 insertions(+), 6 deletions(-) | ||
64 | |||
65 | diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h | ||
66 | index XXXXXXX..XXXXXXX 100644 | ||
67 | --- a/hw/intc/gicv3_internal.h | ||
68 | +++ b/hw/intc/gicv3_internal.h | ||
69 | @@ -XXX,XX +XXX,XX @@ void gicv3_dist_set_irq(GICv3State *s, int irq, int level); | ||
70 | void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level); | ||
71 | void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level); | ||
72 | void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level); | ||
73 | +/** | ||
74 | + * gicv3_redist_update_lpi: | ||
75 | + * @cs: GICv3CPUState | ||
76 | + * | ||
77 | + * Scan the LPI pending table and recalculate the highest priority | ||
78 | + * pending LPI and also the overall highest priority pending interrupt. | ||
79 | + */ | ||
80 | void gicv3_redist_update_lpi(GICv3CPUState *cs); | ||
81 | +/** | ||
82 | + * gicv3_redist_update_lpi_only: | ||
83 | + * @cs: GICv3CPUState | ||
84 | + * | ||
85 | + * Scan the LPI pending table and recalculate cs->hpplpi only, | ||
86 | + * without calling gicv3_redist_update() to recalculate the overall | ||
87 | + * highest priority pending interrupt. This should be called after | ||
88 | + * an incoming migration has loaded new state. | ||
89 | + */ | ||
90 | +void gicv3_redist_update_lpi_only(GICv3CPUState *cs); | ||
91 | void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns); | ||
92 | void gicv3_init_cpuif(GICv3State *s); | ||
93 | |||
94 | diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c | ||
95 | index XXXXXXX..XXXXXXX 100644 | ||
96 | --- a/hw/intc/arm_gicv3.c | ||
97 | +++ b/hw/intc/arm_gicv3.c | ||
98 | @@ -XXX,XX +XXX,XX @@ static void gicv3_redist_update_noirqset(GICv3CPUState *cs) | ||
99 | * interrupt has reduced in priority and any other interrupt could | ||
100 | * now be the new best one). | ||
101 | */ | ||
102 | - if (!seenbetter && cs->hppi.prio != 0xff && cs->hppi.irq < GIC_INTERNAL) { | ||
103 | + if (!seenbetter && cs->hppi.prio != 0xff && | ||
104 | + (cs->hppi.irq < GIC_INTERNAL || | ||
105 | + cs->hppi.irq >= GICV3_LPI_INTID_START)) { | ||
106 | gicv3_full_update_noirqset(cs->gic); | ||
107 | } | ||
108 | } | ||
109 | @@ -XXX,XX +XXX,XX @@ static void arm_gicv3_post_load(GICv3State *s) | ||
110 | * pending interrupt, but don't set IRQ or FIQ lines. | ||
111 | */ | ||
112 | for (i = 0; i < s->num_cpu; i++) { | ||
113 | - gicv3_redist_update_lpi(&s->cpu[i]); | ||
114 | + gicv3_redist_update_lpi_only(&s->cpu[i]); | ||
115 | } | ||
116 | gicv3_full_update_noirqset(s); | ||
117 | /* Repopulate the cache of GICv3CPUState pointers for target CPUs */ | ||
118 | diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c | ||
119 | index XXXXXXX..XXXXXXX 100644 | ||
120 | --- a/hw/intc/arm_gicv3_redist.c | ||
121 | +++ b/hw/intc/arm_gicv3_redist.c | ||
122 | @@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset, | ||
123 | cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS; | ||
124 | /* Check for any pending interr in pending table */ | ||
125 | gicv3_redist_update_lpi(cs); | ||
126 | - gicv3_redist_update(cs); | ||
127 | } else { | ||
128 | cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS; | ||
129 | + /* cs->hppi might have been an LPI; recalculate */ | ||
130 | + gicv3_redist_update(cs); | ||
131 | } | ||
132 | } | ||
133 | return MEMTX_OK; | ||
134 | @@ -XXX,XX +XXX,XX @@ static void gicv3_redist_check_lpi_priority(GICv3CPUState *cs, int irq) | ||
135 | } | ||
136 | } | ||
137 | |||
138 | -void gicv3_redist_update_lpi(GICv3CPUState *cs) | ||
139 | +void gicv3_redist_update_lpi_only(GICv3CPUState *cs) | ||
140 | { | ||
141 | /* | ||
142 | * This function scans the LPI pending table and for each pending | ||
143 | @@ -XXX,XX +XXX,XX @@ void gicv3_redist_update_lpi(GICv3CPUState *cs) | ||
144 | } | ||
145 | } | ||
146 | |||
147 | +void gicv3_redist_update_lpi(GICv3CPUState *cs) | ||
148 | +{ | ||
149 | + gicv3_redist_update_lpi_only(cs); | ||
150 | + gicv3_redist_update(cs); | ||
151 | +} | ||
152 | + | ||
153 | void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level) | ||
154 | { | ||
155 | /* | ||
156 | @@ -XXX,XX +XXX,XX @@ void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level) | ||
157 | */ | ||
158 | if (level) { | ||
159 | gicv3_redist_check_lpi_priority(cs, irq); | ||
160 | + gicv3_redist_update(cs); | ||
161 | } else { | ||
162 | if (irq == cs->hpplpi.irq) { | ||
163 | gicv3_redist_update_lpi(cs); | ||
164 | @@ -XXX,XX +XXX,XX @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level) | ||
165 | |||
166 | /* set/clear the pending bit for this irq */ | ||
167 | gicv3_redist_lpi_pending(cs, irq, level); | ||
168 | - | ||
169 | - gicv3_redist_update(cs); | ||
170 | } | ||
171 | |||
172 | void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level) | ||
173 | -- | ||
174 | 2.25.1 | ||
175 | |||
176 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | The GICv3/v4 pseudocode has a function IsSpecial() which returns true | ||
2 | if passed a "special" interrupt ID number (anything between 1020 and | ||
3 | 1023 inclusive). We open-code this condition in a couple of places, | ||
4 | so abstract it out into a new function gicv3_intid_is_special(). | ||
5 | 1 | ||
6 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
7 | Reviewed-by: Marc Zyngier <maz@kernel.org> | ||
8 | Reviewed-by: Alex Bennée <alex.bennee@linaro.org> | ||
9 | --- | ||
10 | hw/intc/gicv3_internal.h | 13 +++++++++++++ | ||
11 | hw/intc/arm_gicv3_cpuif.c | 4 ++-- | ||
12 | 2 files changed, 15 insertions(+), 2 deletions(-) | ||
13 | |||
14 | diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/hw/intc/gicv3_internal.h | ||
17 | +++ b/hw/intc/gicv3_internal.h | ||
18 | @@ -XXX,XX +XXX,XX @@ FIELD(MAPC, RDBASE, 16, 32) | ||
19 | |||
20 | /* Functions internal to the emulated GICv3 */ | ||
21 | |||
22 | +/** | ||
23 | + * gicv3_intid_is_special: | ||
24 | + * @intid: interrupt ID | ||
25 | + * | ||
26 | + * Return true if @intid is a special interrupt ID (1020 to | ||
27 | + * 1023 inclusive). This corresponds to the GIC spec pseudocode | ||
28 | + * IsSpecial() function. | ||
29 | + */ | ||
30 | +static inline bool gicv3_intid_is_special(int intid) | ||
31 | +{ | ||
32 | + return intid >= INTID_SECURE && intid <= INTID_SPURIOUS; | ||
33 | +} | ||
34 | + | ||
35 | /** | ||
36 | * gicv3_redist_update: | ||
37 | * @cs: GICv3CPUState for this redistributor | ||
38 | diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/hw/intc/arm_gicv3_cpuif.c | ||
41 | +++ b/hw/intc/arm_gicv3_cpuif.c | ||
42 | @@ -XXX,XX +XXX,XX @@ static uint64_t icc_iar0_read(CPUARMState *env, const ARMCPRegInfo *ri) | ||
43 | intid = icc_hppir0_value(cs, env); | ||
44 | } | ||
45 | |||
46 | - if (!(intid >= INTID_SECURE && intid <= INTID_SPURIOUS)) { | ||
47 | + if (!gicv3_intid_is_special(intid)) { | ||
48 | icc_activate_irq(cs, intid); | ||
49 | } | ||
50 | |||
51 | @@ -XXX,XX +XXX,XX @@ static uint64_t icc_iar1_read(CPUARMState *env, const ARMCPRegInfo *ri) | ||
52 | intid = icc_hppir1_value(cs, env); | ||
53 | } | ||
54 | |||
55 | - if (!(intid >= INTID_SECURE && intid <= INTID_SPURIOUS)) { | ||
56 | + if (!gicv3_intid_is_special(intid)) { | ||
57 | icc_activate_irq(cs, intid); | ||
58 | } | ||
59 | |||
60 | -- | ||
61 | 2.25.1 | ||
62 | |||
63 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | It is valid for an OS to put virtual interrupt ID values into the | ||
2 | list registers ICH_LR<n> which are greater than 1023. This | ||
3 | corresponds to (for example) KVM using the in-kernel emulated ITS to | ||
4 | give a (nested) guest an ITS. LPIs are delivered by the L1 kernel to | ||
5 | the L2 guest via the list registers in the same way as non-LPI | ||
6 | interrupts. | ||
7 | 1 | ||
8 | QEMU's code for handling writes to ICV_IARn (which happen when the L2 | ||
9 | guest acknowledges an interrupt) and to ICV_EOIRn (which happen at | ||
10 | the end of the interrupt) did not consider LPIs, so it would | ||
11 | incorrectly treat interrupt IDs above 1023 as invalid. Fix this by | ||
12 | using the correct condition, which is gicv3_intid_is_special(). | ||
13 | |||
14 | Note that the condition in icv_dir_write() is correct -- LPIs | ||
15 | are not valid there and so we want to ignore both "special" ID | ||
16 | values and LPIs. | ||
17 | |||
18 | (In the pseudocode this logic is in: | ||
19 | - VirtualReadIAR0(), VirtualReadIAR1(), which call IsSpecial() | ||
20 | - VirtualWriteEOIR0(), VirtualWriteEOIR1(), which call | ||
21 | VirtualIdentifierValid(data, TRUE) meaning "LPIs OK" | ||
22 | - VirtualWriteDIR(), which calls VirtualIdentifierValid(data, FALSE) | ||
23 | meaning "LPIs not OK") | ||
24 | |||
25 | This bug doesn't seem to have any visible effect on Linux L2 guests | ||
26 | most of the time, because the two bugs cancel each other out: we | ||
27 | neither mark the interrupt active nor deactivate it. However it does | ||
28 | mean that the L2 vCPU priority while the LPI handler is running will | ||
29 | not be correct, so the interrupt handler could be unexpectedly | ||
30 | interrupted by a different interrupt. | ||
31 | |||
32 | (NB: this has nothing to do with using QEMU's emulated ITS.) | ||
33 | |||
34 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
35 | Reviewed-by: Marc Zyngier <maz@kernel.org> | ||
36 | --- | ||
37 | hw/intc/arm_gicv3_cpuif.c | 5 ++--- | ||
38 | 1 file changed, 2 insertions(+), 3 deletions(-) | ||
39 | |||
40 | diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/hw/intc/arm_gicv3_cpuif.c | ||
43 | +++ b/hw/intc/arm_gicv3_cpuif.c | ||
44 | @@ -XXX,XX +XXX,XX @@ static uint64_t icv_iar_read(CPUARMState *env, const ARMCPRegInfo *ri) | ||
45 | |||
46 | if (thisgrp == grp && icv_hppi_can_preempt(cs, lr)) { | ||
47 | intid = ich_lr_vintid(lr); | ||
48 | - if (intid < INTID_SECURE) { | ||
49 | + if (!gicv3_intid_is_special(intid)) { | ||
50 | icv_activate_irq(cs, idx, grp); | ||
51 | } else { | ||
52 | /* Interrupt goes from Pending to Invalid */ | ||
53 | @@ -XXX,XX +XXX,XX @@ static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||
54 | trace_gicv3_icv_eoir_write(ri->crm == 8 ? 0 : 1, | ||
55 | gicv3_redist_affid(cs), value); | ||
56 | |||
57 | - if (irq >= GICV3_MAXIRQ) { | ||
58 | - /* Also catches special interrupt numbers and LPIs */ | ||
59 | + if (gicv3_intid_is_special(irq)) { | ||
60 | return; | ||
61 | } | ||
62 | |||
63 | -- | ||
64 | 2.25.1 | ||
65 | |||
66 | diff view generated by jsdifflib |