* [PATCH v2 01/11] xen/arm: vgic-v2: Implement correctly ICFGR{0, 1} read-only
2015-11-18 17:27 [PATCH v2 00/11] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
@ 2015-11-18 17:27 ` Julien Grall
2015-11-24 17:14 ` Ian Campbell
2015-11-18 17:27 ` [PATCH v2 02/11] xen/arm: vgic-v3: Don't try to emulate IROUTER which doesn't exist in the spec Julien Grall
` (9 subsequent siblings)
10 siblings, 1 reply; 24+ messages in thread
From: Julien Grall @ 2015-11-18 17:27 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
Each ITARGETSR register are 4-byte wide and the offset is in byte.
The current implementation is computing the offset of ICFGR1 and ICFG2
wonrgly result to emulate only the first 2 byte of the ICFGR<n> range
read-only. The rest will be treated as read-write.
For convenience introduce ITARGETSR1 and ITARGETSR2.
Signed-off-by: Julien Grall <julien.grall@citrix.com>
---
We only store the value of ICFGR<n> registers for the guest own purpose
today. Xen is not using it at all. So I don't think it's worth to backport
it.
Changes in v2:
- This patch was supposed to be in v1, but messed up the
git format-patch command
---
xen/arch/arm/vgic-v2.c | 6 ++++--
xen/include/asm-arm/gic.h | 2 ++
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index c94f0f3..4fb954b 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -507,10 +507,12 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
case GICD_ICFGR: /* SGIs */
goto write_ignore_32;
- case GICD_ICFGR + 1: /* PPIs */
+
+ case GICD_ICFGR1:
/* It is implementation defined if these are writeable. We chose not */
goto write_ignore_32;
- case GICD_ICFGR + 2 ... GICD_ICFGRN: /* SPIs */
+
+ case GICD_ICFGR2 ... GICD_ICFGRN: /* SPIs */
if ( dabt.size != DABT_WORD ) goto bad_width;
rank = vgic_rank_offset(v, 2, gicd_reg - GICD_ICFGR, DABT_WORD);
if ( rank == NULL) goto write_ignore;
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index 3064d1c..42a2eec 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -46,6 +46,8 @@
#define GICD_ITARGETSR8 (0x820)
#define GICD_ITARGETSRN (0xBF8)
#define GICD_ICFGR (0xC00)
+#define GICD_ICFGR1 (0xC04)
+#define GICD_ICFGR2 (0xC08)
#define GICD_ICFGRN (0xCFC)
#define GICD_NSACR (0xE00)
#define GICD_NSACRN (0xEFC)
--
2.1.4
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v2 01/11] xen/arm: vgic-v2: Implement correctly ICFGR{0, 1} read-only
2015-11-18 17:27 ` [PATCH v2 01/11] xen/arm: vgic-v2: Implement correctly ICFGR{0, 1} read-only Julien Grall
@ 2015-11-24 17:14 ` Ian Campbell
2015-11-25 12:29 ` Ian Campbell
0 siblings, 1 reply; 24+ messages in thread
From: Ian Campbell @ 2015-11-24 17:14 UTC (permalink / raw)
To: Julien Grall, xen-devel; +Cc: stefano.stabellini
On Wed, 2015-11-18 at 17:27 +0000, Julien Grall wrote:
> Each ITARGETSR register are 4-byte wide and the offset is in byte.
"is 4-bytes" ... "is in bytes".
>
> The current implementation is computing the offset of ICFGR1 and ICFG2
> wonrgly result to emulate only the first 2 byte of the ICFGR<n> range
wrongly
> read-only. The rest will be treated as read-write.
>
> For convenience introduce ITARGETSR1 and ITARGETSR2.
>
> Signed-off-by: Julien Grall <julien.grall@citrix.com>
> ---
>
> We only store the value of ICFGR<n> registers for the guest own
> purpose
> today. Xen is not using it at all. So I don't think it's worth to
> backport
> it.
>
> Changes in v2:
> - This patch was supposed to be in v1, but messed up the
> git format-patch command
> ---
> xen/arch/arm/vgic-v2.c | 6 ++++--
> xen/include/asm-arm/gic.h | 2 ++
> 2 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
> index c94f0f3..4fb954b 100644
> --- a/xen/arch/arm/vgic-v2.c
> +++ b/xen/arch/arm/vgic-v2.c
> @@ -507,10 +507,12 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v,
> mmio_info_t *info,
>
> case GICD_ICFGR: /* SGIs */
> goto write_ignore_32;
> - case GICD_ICFGR + 1: /* PPIs */
> +
> + case GICD_ICFGR1:
This should have a /* PPIs */ comment I think?
I think I could add that on commit if you agree.
Ian.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v2 01/11] xen/arm: vgic-v2: Implement correctly ICFGR{0, 1} read-only
2015-11-24 17:14 ` Ian Campbell
@ 2015-11-25 12:29 ` Ian Campbell
2015-11-30 12:11 ` Julien Grall
0 siblings, 1 reply; 24+ messages in thread
From: Ian Campbell @ 2015-11-25 12:29 UTC (permalink / raw)
To: Julien Grall, xen-devel; +Cc: stefano.stabellini
On Tue, 2015-11-24 at 17:14 +0000, Ian Campbell wrote:
> @@ -507,10 +507,12 @@ static int vgic_v2_distr_mmio_write(struct vcpu
> > *v,
> > mmio_info_t *info,
> >
> > case GICD_ICFGR: /* SGIs */
> > goto write_ignore_32;
> > - case GICD_ICFGR + 1: /* PPIs */
> > +
> > + case GICD_ICFGR1:
>
> This should have a /* PPIs */ comment I think?
>
> I think I could add that on commit if you agree.
With you being away this week I decided this wasn't worth holding up 11
patches over and committed without. Instead:
----8<---------
From ae3bbd51d27ac413fc948cfd3b2d5604323c7d4c Mon Sep 17 00:00:00 2001
From: Ian Campbell <ian.campbell@citrix.com>
Date: Wed, 25 Nov 2015 12:02:18 +0000
Subject: [PATCH] xen/arm: vgic-v2: Add "PPIs" comment to GICD_ICFGR1 handler
To match the surrounding SPIs and SGIs comments.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
xen/arch/arm/vgic-v2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index 2c73133..c3c6b66 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -545,7 +545,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
case VREG32(GICD_ICFGR): /* SGIs */
goto write_ignore_32;
- case VREG32(GICD_ICFGR1):
+ case VREG32(GICD_ICFGR1): /* PPIs */
/* It is implementation defined if these are writeable. We chose not */
goto write_ignore_32;
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v2 01/11] xen/arm: vgic-v2: Implement correctly ICFGR{0, 1} read-only
2015-11-25 12:29 ` Ian Campbell
@ 2015-11-30 12:11 ` Julien Grall
0 siblings, 0 replies; 24+ messages in thread
From: Julien Grall @ 2015-11-30 12:11 UTC (permalink / raw)
To: Ian Campbell, xen-devel; +Cc: stefano.stabellini
Hi Ian,
On 25/11/15 12:29, Ian Campbell wrote:
> On Tue, 2015-11-24 at 17:14 +0000, Ian Campbell wrote:
>> @@ -507,10 +507,12 @@ static int vgic_v2_distr_mmio_write(struct vcpu
>>> *v,
>>> mmio_info_t *info,
>>>
>>> case GICD_ICFGR: /* SGIs */
>>> goto write_ignore_32;
>>> - case GICD_ICFGR + 1: /* PPIs */
>>> +
>>> + case GICD_ICFGR1:
>>
>> This should have a /* PPIs */ comment I think?
>>
>> I think I could add that on commit if you agree.
>
> With you being away this week I decided this wasn't worth holding up 11
> patches over and committed without. Instead:
FWIW, I'm fine with that as it was a mistake while I wrote the patch.
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 02/11] xen/arm: vgic-v3: Don't try to emulate IROUTER which doesn't exist in the spec
2015-11-18 17:27 [PATCH v2 00/11] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
2015-11-18 17:27 ` [PATCH v2 01/11] xen/arm: vgic-v2: Implement correctly ICFGR{0, 1} read-only Julien Grall
@ 2015-11-18 17:27 ` Julien Grall
2015-11-24 17:17 ` Ian Campbell
2015-11-18 17:27 ` [PATCH v2 03/11] xen/arm: vgic-v3: Use the correct offset GICR_IGRPMODR0 Julien Grall
` (8 subsequent siblings)
10 siblings, 1 reply; 24+ messages in thread
From: Julien Grall @ 2015-11-18 17:27 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
The range of valid IROUTER<n> are n = 32 - 1019 (see 8.9.13 in IHI 0069A)
which correspond to the offset 0x6100-0x7FD8.
Other offset are invalid and therefore should not be emulated.
Also remove the now unused label read_as_zero_64 and write_ignore_64.
Note that GICD_IROUTER is kept to accomadate the GICv3 drivers which has
been in part taken from Linux.
Signed-off-by: Julien Grall <julien.grall@citrix.com>
---
Changes in v2:
- This patch was supposed to be in v1, but messed up
the git format-patch command
---
xen/arch/arm/vgic-v3.c | 19 ++-----------------
xen/include/asm-arm/gic_v3_defs.h | 3 +--
2 files changed, 3 insertions(+), 19 deletions(-)
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 3a7b86f..902f64a 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -806,10 +806,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
* Manage in common
*/
return __vgic_v3_distr_common_mmio_read("vGICD", v, info, gicd_reg, r);
- case GICD_IROUTER ... GICD_IROUTER31:
- /* SGI/PPI is RES0 */
- goto read_as_zero_64;
- case GICD_IROUTER32 ... GICD_IROUTERN:
+ case GICD_IROUTER32 ... GICD_IROUTER1019:
{
uint64_t irouter;
@@ -887,11 +884,6 @@ bad_width:
domain_crash_synchronous();
return 0;
-read_as_zero_64:
- if ( vgic_reg64_check_access(dabt) ) goto bad_width;
- *r = 0;
- return 1;
-
read_as_zero_32:
if ( dabt.size != DABT_WORD ) goto bad_width;
*r = 0;
@@ -974,10 +966,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
* Manage in common */
return __vgic_v3_distr_common_mmio_write("vGICD", v, info,
gicd_reg, r);
- case GICD_IROUTER ... GICD_IROUTER31:
- /* SGI/PPI is RES0 */
- goto write_ignore_64;
- case GICD_IROUTER32 ... GICD_IROUTERN:
+ case GICD_IROUTER32 ... GICD_IROUTER1019:
{
uint64_t irouter;
@@ -1039,10 +1028,6 @@ write_ignore_32:
if ( dabt.size != DABT_WORD ) goto bad_width;
return 1;
-write_ignore_64:
- if ( vgic_reg64_check_access(dabt) ) goto bad_width;
- return 1;
-
write_ignore:
return 1;
}
diff --git a/xen/include/asm-arm/gic_v3_defs.h b/xen/include/asm-arm/gic_v3_defs.h
index c6d73df..89a3548 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -29,9 +29,8 @@
#define GICD_SETSPI_SR (0x050)
#define GICD_CLRSPI_SR (0x058)
#define GICD_IROUTER (0x6000)
-#define GICD_IROUTER31 (0x60F8)
#define GICD_IROUTER32 (0x6100)
-#define GICD_IROUTERN (0x7FF8)
+#define GICD_IROUTER1019 (0x7FD8)
#define GICD_PIDR0 (0xFFE0)
#define GICD_PIDR1 (0xFFE4)
#define GICD_PIDR2 (0xFFE8)
--
2.1.4
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v2 02/11] xen/arm: vgic-v3: Don't try to emulate IROUTER which doesn't exist in the spec
2015-11-18 17:27 ` [PATCH v2 02/11] xen/arm: vgic-v3: Don't try to emulate IROUTER which doesn't exist in the spec Julien Grall
@ 2015-11-24 17:17 ` Ian Campbell
2015-11-30 12:13 ` Julien Grall
0 siblings, 1 reply; 24+ messages in thread
From: Ian Campbell @ 2015-11-24 17:17 UTC (permalink / raw)
To: Julien Grall, xen-devel; +Cc: stefano.stabellini
On Wed, 2015-11-18 at 17:27 +0000, Julien Grall wrote:
Subject: ... which do not exist in the ...
> The range of valid IROUTER<n> are n = 32 - 1019 (see 8.9.13 in IHI 0069A)
> which correspond to the offset 0x6100-0x7FD8.
>
> Other offset are invalid and therefore should not be emulated.
"offsets"
>
> Also remove the now unused label read_as_zero_64 and write_ignore_64.
>
> Note that GICD_IROUTER is kept to accomadate the GICv3 drivers which has
"accommodate"
> been in part taken from Linux.
>
> Signed-off-by: Julien Grall <julien.grall@citrix.com>
Accesses to 0x6000-0x60FF are going to be noisy now, I suppose that is OK.
Acked-by: Ian Campbell <ian.campbell@citrix.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 02/11] xen/arm: vgic-v3: Don't try to emulate IROUTER which doesn't exist in the spec
2015-11-24 17:17 ` Ian Campbell
@ 2015-11-30 12:13 ` Julien Grall
0 siblings, 0 replies; 24+ messages in thread
From: Julien Grall @ 2015-11-30 12:13 UTC (permalink / raw)
To: Ian Campbell, xen-devel; +Cc: stefano.stabellini
Hi Ian,
On 24/11/15 17:17, Ian Campbell wrote:
> On Wed, 2015-11-18 at 17:27 +0000, Julien Grall wrote:
>
> Subject: ... which do not exist in the ...
>
>> The range of valid IROUTER<n> are n = 32 - 1019 (see 8.9.13 in IHI 0069A)
>> which correspond to the offset 0x6100-0x7FD8.
>>
>> Other offset are invalid and therefore should not be emulated.
>
> "offsets"
>
>>
>> Also remove the now unused label read_as_zero_64 and write_ignore_64.
>>
>> Note that GICD_IROUTER is kept to accomadate the GICv3 drivers which has
>
> "accommodate"
>
>> been in part taken from Linux.
>>
>> Signed-off-by: Julien Grall <julien.grall@citrix.com>
>
> Accesses to 0x6000-0x60FF are going to be noisy now, I suppose that is OK.
Well, those registers are reserved so the guests are not supposed to
access them.
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
Thank you!
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 03/11] xen/arm: vgic-v3: Use the correct offset GICR_IGRPMODR0
2015-11-18 17:27 [PATCH v2 00/11] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
2015-11-18 17:27 ` [PATCH v2 01/11] xen/arm: vgic-v2: Implement correctly ICFGR{0, 1} read-only Julien Grall
2015-11-18 17:27 ` [PATCH v2 02/11] xen/arm: vgic-v3: Don't try to emulate IROUTER which doesn't exist in the spec Julien Grall
@ 2015-11-18 17:27 ` Julien Grall
2015-11-18 17:27 ` [PATCH v2 04/11] xen/arm: vgic-v3: Only emulate identification registers required by the spec Julien Grall
` (7 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Julien Grall @ 2015-11-18 17:27 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
The offset is 0x0D00 and not 0x0F80.
Also re-order the definition to keep all the definitions ordered.
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
Changes in v2:
- Add Ian's acked-by
---
xen/include/asm-arm/gic_v3_defs.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/xen/include/asm-arm/gic_v3_defs.h b/xen/include/asm-arm/gic_v3_defs.h
index 89a3548..34e8b0a 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -96,7 +96,6 @@
/* GICR for SGI's & PPI's */
#define GICR_IGROUPR0 (0x0080)
-#define GICR_IGRPMODR0 (0x0F80)
#define GICR_ISENABLER0 (0x0100)
#define GICR_ICENABLER0 (0x0180)
#define GICR_ISPENDR0 (0x0200)
@@ -107,6 +106,7 @@
#define GICR_IPRIORITYR7 (0x041C)
#define GICR_ICFGR0 (0x0C00)
#define GICR_ICFGR1 (0x0C04)
+#define GICR_IGRPMODR0 (0x0D00)
#define GICR_NSACR (0x0E00)
#define GICR_TYPER_PLPIS (1U << 0)
--
2.1.4
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v2 04/11] xen/arm: vgic-v3: Only emulate identification registers required by the spec
2015-11-18 17:27 [PATCH v2 00/11] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
` (2 preceding siblings ...)
2015-11-18 17:27 ` [PATCH v2 03/11] xen/arm: vgic-v3: Use the correct offset GICR_IGRPMODR0 Julien Grall
@ 2015-11-18 17:27 ` Julien Grall
2015-11-18 17:28 ` [PATCH v2 05/11] xen/arm: vgic: Properly emulate the full register Julien Grall
` (6 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Julien Grall @ 2015-11-18 17:27 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
Most of the identification registers space contains implementation
defined registers (see 8.1.13 in ARM IHI 0069A) and only GIC{D,R}_PIDR2
is required to be implemented.
Currently the emulation of those registers mimic the ARM implementation,
but it's untrue to say that we properly emulate a such implementation.
Keep only GIC{D,R}_PIDR2 implemented with the "implementation defined
bits" to zero and the ArchRev field (bits[7:4]) to 0x3 as we emulate a
GICv3.
Note that the emulation of the range wasn't valid anyway because the
registers are split in 2 sets (PIDR4-PIDR7 and PIDR0-PIDR2).
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
Changes in v2:
- Add Ian's acked-by
- Fix typoes
---
xen/arch/arm/vgic-v3.c | 127 +++++++++++++++++++++++---------------
xen/include/asm-arm/gic_v3_defs.h | 12 ----
2 files changed, 76 insertions(+), 63 deletions(-)
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 902f64a..0f6cb95 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -31,17 +31,15 @@
#include <asm/gic_v3_defs.h>
#include <asm/vgic.h>
-/* GICD_PIDRn register values for ARM implementations */
-#define GICV3_GICD_PIDR0 0x92
-#define GICV3_GICD_PIDR1 0xb4
-#define GICV3_GICD_PIDR2 0x3b
-#define GICV3_GICD_PIDR4 0x04
-
-/* GICR_PIDRn register values for ARM implementations */
-#define GICV3_GICR_PIDR0 0x93
-#define GICV3_GICR_PIDR1 GICV3_GICD_PIDR1
+/*
+ * PIDR2: Only bits[7:4] are not implementation defined. We are
+ * emulating a GICv3 ([7:4] = 0x3).
+ *
+ * We don't emulate a specific registers scheme so implement the others
+ * bits as RES0 as recommended by the spec (see 8.1.13 in ARM IHI 0069A).
+ */
+#define GICV3_GICD_PIDR2 0x30
#define GICV3_GICR_PIDR2 GICV3_GICD_PIDR2
-#define GICV3_GICR_PIDR4 GICV3_GICD_PIDR4
/*
* GICD_CTLR default value:
@@ -237,28 +235,20 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
case GICR_MOVALLR:
/* WO Read as zero */
goto read_as_zero_64;
- case GICR_PIDR0:
- if ( dabt.size != DABT_WORD ) goto bad_width;
- *r = vgic_reg32_extract(GICV3_GICR_PIDR0, info);
- return 1;
- case GICR_PIDR1:
- if ( dabt.size != DABT_WORD ) goto bad_width;
- *r = vgic_reg32_extract(GICV3_GICR_PIDR1, info);
- return 1;
+
+ case 0xFFD0 ... 0xFFE4:
+ /* Implementation defined identification registers */
+ goto read_impl_defined;
+
case GICR_PIDR2:
if ( dabt.size != DABT_WORD ) goto bad_width;
*r = vgic_reg32_extract(GICV3_GICR_PIDR2, info);
return 1;
- case GICR_PIDR3:
- /* Manufacture/customer defined */
- goto read_as_zero_32;
- case GICR_PIDR4:
- if ( dabt.size != DABT_WORD ) goto bad_width;
- *r = vgic_reg32_extract(GICV3_GICR_PIDR4, info);
- return 1;
- case GICR_PIDR5 ... GICR_PIDR7:
- /* Reserved0 */
- goto read_as_zero_32;
+
+ case 0xFFEC ... 0xFFFC:
+ /* Implementation defined identification registers */
+ goto read_impl_defined;
+
default:
printk(XENLOG_G_ERR
"%pv: vGICR: unhandled read r%d offset %#08x\n",
@@ -280,6 +270,13 @@ read_as_zero_32:
if ( dabt.size != DABT_WORD ) goto bad_width;
*r = 0;
return 1;
+
+read_impl_defined:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICR: RAZ on implemention defined register offset %#08x\n",
+ v, gicr_reg);
+ *r = 0;
+ return 1;
}
static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
@@ -332,9 +329,19 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
case GICR_MOVALLR:
/* LPI is not implemented */
goto write_ignore_64;
- case GICR_PIDR7... GICR_PIDR0:
+
+ case 0xFFD0 ... 0xFFE4:
+ /* Implementation defined identification registers */
+ goto write_impl_defined;
+
+ case GICR_PIDR2:
/* RO */
goto write_ignore_32;
+
+ case 0xFFEC ... 0xFFFC:
+ /* Implementation defined identification registers */
+ goto write_impl_defined;
+
default:
printk(XENLOG_G_ERR "%pv: vGICR: unhandled write r%d offset %#08x\n",
v, dabt.reg, gicr_reg);
@@ -354,6 +361,12 @@ write_ignore_64:
write_ignore_32:
if ( dabt.size != DABT_WORD ) goto bad_width;
return 1;
+
+write_impl_defined:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICR: WI on implementation defined register offset %#08x\n",
+ v, gicr_reg);
+ return 1;
}
static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
@@ -835,32 +848,21 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
case GICD_SPENDSGIR ... GICD_SPENDSGIRN:
/* Replaced with GICR_ISPENDR0. So ignore write */
goto read_as_zero_32;
- case GICD_PIDR0:
- /* GICv3 identification value */
- if ( dabt.size != DABT_WORD ) goto bad_width;
- *r = vgic_reg32_extract(GICV3_GICD_PIDR0, info);
- return 1;
- case GICD_PIDR1:
- /* GICv3 identification value */
- if ( dabt.size != DABT_WORD ) goto bad_width;
- *r = vgic_reg32_extract(GICV3_GICD_PIDR1, info);
- return 1;
+
+ case 0xFFD0 ... 0xFFE4:
+ /* Implementation defined identification registers */
+ goto read_impl_defined;
+
case GICD_PIDR2:
/* GICv3 identification value */
if ( dabt.size != DABT_WORD ) goto bad_width;
*r = vgic_reg32_extract(GICV3_GICD_PIDR2, info);
return 1;
- case GICD_PIDR3:
- /* GICv3 identification value. Manufacturer/Customer defined */
- goto read_as_zero_32;
- case GICD_PIDR4:
- /* GICv3 identification value */
- if ( dabt.size != DABT_WORD ) goto bad_width;
- *r = vgic_reg32_extract(GICV3_GICD_PIDR4, info);
- return 1;
- case GICD_PIDR5 ... GICD_PIDR7:
- /* Reserved0 */
- goto read_as_zero_32;
+
+ case 0xFFEC ... 0xFFFC:
+ /* Implementation defined identification registers */
+ goto read_impl_defined;
+
case 0x00c:
case 0x044:
case 0x04c:
@@ -892,6 +894,13 @@ read_as_zero_32:
read_as_zero:
*r = 0;
return 1;
+
+read_impl_defined:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICD: RAZ on implemention defined register offset %#08x\n",
+ v, gicd_reg);
+ *r = 0;
+ return 1;
}
static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
@@ -996,9 +1005,19 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
/* Replaced with GICR_ISPENDR0. So ignore write */
if ( dabt.size != DABT_WORD ) goto bad_width;
return 0;
- case GICD_PIDR7... GICD_PIDR0:
+
+ case 0xFFD0 ... 0xFFE4:
+ /* Implementation defined identification registers */
+ goto write_impl_defined;
+
+ case GICD_PIDR2:
/* RO -- write ignore */
goto write_ignore_32;
+
+ case 0xFFEC ... 0xFFFC:
+ /* Implementation defined identification registers */
+ goto write_impl_defined;
+
case 0x00c:
case 0x044:
case 0x04c:
@@ -1030,6 +1049,12 @@ write_ignore_32:
write_ignore:
return 1;
+
+write_impl_defined:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICD: WI on implementation defined register offset %#08x\n",
+ v, gicd_reg);
+ return 1;
}
static int vgic_v3_to_sgi(struct vcpu *v, register_t sgir)
diff --git a/xen/include/asm-arm/gic_v3_defs.h b/xen/include/asm-arm/gic_v3_defs.h
index 34e8b0a..5a6938c 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -31,13 +31,7 @@
#define GICD_IROUTER (0x6000)
#define GICD_IROUTER32 (0x6100)
#define GICD_IROUTER1019 (0x7FD8)
-#define GICD_PIDR0 (0xFFE0)
-#define GICD_PIDR1 (0xFFE4)
#define GICD_PIDR2 (0xFFE8)
-#define GICD_PIDR3 (0xFFEC)
-#define GICD_PIDR4 (0xFFD0)
-#define GICD_PIDR5 (0xFFD4)
-#define GICD_PIDR7 (0xFFDC)
/* Common between GICD_PIDR2 and GICR_PIDR2 */
#define GIC_PIDR2_ARCH_MASK (0xf0)
@@ -85,13 +79,7 @@
#define GICR_SYNCR (0x00C0)
#define GICR_MOVLPIR (0x100)
#define GICR_MOVALLR (0x0110)
-#define GICR_PIDR0 GICD_PIDR0
-#define GICR_PIDR1 GICD_PIDR1
#define GICR_PIDR2 GICD_PIDR2
-#define GICR_PIDR3 GICD_PIDR3
-#define GICR_PIDR4 GICD_PIDR4
-#define GICR_PIDR5 GICD_PIDR5
-#define GICR_PIDR7 GICD_PIDR7
/* GICR for SGI's & PPI's */
--
2.1.4
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v2 05/11] xen/arm: vgic: Properly emulate the full register
2015-11-18 17:27 [PATCH v2 00/11] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
` (3 preceding siblings ...)
2015-11-18 17:27 ` [PATCH v2 04/11] xen/arm: vgic-v3: Only emulate identification registers required by the spec Julien Grall
@ 2015-11-18 17:28 ` Julien Grall
2015-11-25 9:26 ` Shannon Zhao
2015-11-18 17:28 ` [PATCH v2 06/11] xen/arm: vgic-v3: Remove GICR_MOVALLR and GICR_MOVLPIR Julien Grall
` (5 subsequent siblings)
10 siblings, 1 reply; 24+ messages in thread
From: Julien Grall @ 2015-11-18 17:28 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
The offset in the emulation is based on byte. As most of the registers
are 64/32 bits, they will span over multiple bytes.
However, the current emulation only cares about the first offset. This
will result in not properly emulating any access on the register with
any other offset.
Introduce new macros to help implementing access on multiple byte and
use them over the vGIC emulation.
Note that I didn't convert the reserved/implementation defined
registers. It will be done in a follow-up.
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
Changes in v2:
- Add Ian's acked-by
- Fix typoes
---
xen/arch/arm/vgic-v2.c | 81 ++++++------
xen/arch/arm/vgic-v3.c | 287 ++++++++++++++++++++++++----------------
xen/include/asm-arm/vgic-emul.h | 24 ++++
3 files changed, 240 insertions(+), 152 deletions(-)
create mode 100644 xen/include/asm-arm/vgic-emul.h
diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index 4fb954b..d1860a9 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -31,6 +31,7 @@
#include <asm/mmio.h>
#include <asm/platform.h>
#include <asm/vgic.h>
+#include <asm/vgic-emul.h>
static struct {
bool_t enabled;
@@ -177,13 +178,14 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
switch ( gicd_reg )
{
- case GICD_CTLR:
+ case VREG32(GICD_CTLR):
if ( dabt.size != DABT_WORD ) goto bad_width;
vgic_lock(v);
*r = vgic_reg32_extract(v->domain->arch.vgic.ctlr, info);
vgic_unlock(v);
return 1;
- case GICD_TYPER:
+
+ case VREG32(GICD_TYPER):
{
uint32_t typer;
@@ -198,7 +200,8 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case GICD_IIDR:
+
+ case VREG32(GICD_IIDR):
if ( dabt.size != DABT_WORD ) goto bad_width;
/*
* XXX Do we need a JEP106 manufacturer ID?
@@ -211,11 +214,11 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
case 0x020 ... 0x03c:
goto read_as_zero;
- case GICD_IGROUPR ... GICD_IGROUPRN:
+ case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
/* We do not implement security extensions for guests, read zero */
goto read_as_zero_32;
- case GICD_ISENABLER ... GICD_ISENABLERN:
+ case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
if ( dabt.size != DABT_WORD ) goto bad_width;
rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ISENABLER, DABT_WORD);
if ( rank == NULL) goto read_as_zero;
@@ -224,7 +227,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
vgic_unlock_rank(v, rank, flags);
return 1;
- case GICD_ICENABLER ... GICD_ICENABLERN:
+ case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):
if ( dabt.size != DABT_WORD ) goto bad_width;
rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ICENABLER, DABT_WORD);
if ( rank == NULL) goto read_as_zero;
@@ -234,16 +237,16 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
return 1;
/* Read the pending status of an IRQ via GICD is not supported */
- case GICD_ISPENDR ... GICD_ISPENDRN:
- case GICD_ICPENDR ... GICD_ICPENDRN:
+ case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
+ case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
goto read_as_zero;
/* Read the active status of an IRQ via GICD is not supported */
- case GICD_ISACTIVER ... GICD_ISACTIVERN:
- case GICD_ICACTIVER ... GICD_ICACTIVERN:
+ case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN):
+ case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
goto read_as_zero;
- case GICD_ITARGETSR ... GICD_ITARGETSRN:
+ case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSRN):
{
uint32_t itargetsr;
@@ -258,7 +261,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
+ case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
{
uint32_t ipriorityr;
@@ -276,7 +279,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case GICD_ICFGR ... GICD_ICFGRN:
+ case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
{
uint32_t icfgr;
@@ -292,26 +295,26 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case GICD_NSACR ... GICD_NSACRN:
+ case VRANGE32(GICD_NSACR, GICD_NSACRN):
/* We do not implement security extensions for guests, read zero */
goto read_as_zero_32;
- case GICD_SGIR:
+ case VREG32(GICD_SGIR):
if ( dabt.size != DABT_WORD ) goto bad_width;
/* Write only -- read unknown */
*r = 0xdeadbeef;
return 1;
/* Setting/Clearing the SGI pending bit via GICD is not supported */
- case GICD_CPENDSGIR ... GICD_CPENDSGIRN:
- case GICD_SPENDSGIR ... GICD_SPENDSGIRN:
+ case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
+ case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
goto read_as_zero;
/* Implementation defined -- read as zero */
case 0xfd0 ... 0xfe4:
goto read_as_zero;
- case GICD_ICPIDR2:
+ case VREG32(GICD_ICPIDR2):
if ( dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR "%pv: vGICD: unhandled read from ICPIDR2\n", v);
return 0;
@@ -396,7 +399,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
switch ( gicd_reg )
{
- case GICD_CTLR:
+ case VREG32(GICD_CTLR):
if ( dabt.size != DABT_WORD ) goto bad_width;
/* Ignore all but the enable bit */
vgic_lock(v);
@@ -407,19 +410,19 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
return 1;
/* R/O -- write ignored */
- case GICD_TYPER:
- case GICD_IIDR:
+ case VREG32(GICD_TYPER):
+ case VREG32(GICD_IIDR):
goto write_ignore_32;
/* Implementation defined -- write ignored */
case 0x020 ... 0x03c:
goto write_ignore;
- case GICD_IGROUPR ... GICD_IGROUPRN:
+ case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
/* We do not implement security extensions for guests, write ignore */
goto write_ignore_32;
- case GICD_ISENABLER ... GICD_ISENABLERN:
+ case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
if ( dabt.size != DABT_WORD ) goto bad_width;
rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ISENABLER, DABT_WORD);
if ( rank == NULL) goto write_ignore;
@@ -430,7 +433,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
vgic_unlock_rank(v, rank, flags);
return 1;
- case GICD_ICENABLER ... GICD_ICENABLERN:
+ case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):
if ( dabt.size != DABT_WORD ) goto bad_width;
rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ICENABLER, DABT_WORD);
if ( rank == NULL) goto write_ignore;
@@ -441,39 +444,39 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
vgic_unlock_rank(v, rank, flags);
return 1;
- case GICD_ISPENDR ... GICD_ISPENDRN:
+ case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
if ( dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
"%pv: vGICD: unhandled word write %#"PRIregister" to ISPENDR%d\n",
v, r, gicd_reg - GICD_ISPENDR);
return 0;
- case GICD_ICPENDR ... GICD_ICPENDRN:
+ case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
if ( dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
"%pv: vGICD: unhandled word write %#"PRIregister" to ICPENDR%d\n",
v, r, gicd_reg - GICD_ICPENDR);
return 0;
- case GICD_ISACTIVER ... GICD_ISACTIVERN:
+ case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN):
if ( dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
"%pv: vGICD: unhandled word write %#"PRIregister" to ISACTIVER%d\n",
v, r, gicd_reg - GICD_ISACTIVER);
return 0;
- case GICD_ICACTIVER ... GICD_ICACTIVERN:
+ case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
if ( dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
"%pv: vGICD: unhandled word write %#"PRIregister" to ICACTIVER%d\n",
v, r, gicd_reg - GICD_ICACTIVER);
return 0;
- case GICD_ITARGETSR ... GICD_ITARGETSR7:
+ case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSR7):
/* SGI/PPI target is read only */
goto write_ignore_32;
- case GICD_ITARGETSR8 ... GICD_ITARGETSRN:
+ case VRANGE32(GICD_ITARGETSR8, GICD_ITARGETSRN):
{
uint32_t itargetsr;
@@ -489,7 +492,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
+ case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
{
uint32_t *ipriorityr;
@@ -505,14 +508,14 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case GICD_ICFGR: /* SGIs */
+ case VREG32(GICD_ICFGR): /* SGIs */
goto write_ignore_32;
- case GICD_ICFGR1:
+ case VREG32(GICD_ICFGR1):
/* It is implementation defined if these are writeable. We chose not */
goto write_ignore_32;
- case GICD_ICFGR2 ... GICD_ICFGRN: /* SPIs */
+ case VRANGE32(GICD_ICFGR2, GICD_ICFGRN): /* SPIs */
if ( dabt.size != DABT_WORD ) goto bad_width;
rank = vgic_rank_offset(v, 2, gicd_reg - GICD_ICFGR, DABT_WORD);
if ( rank == NULL) goto write_ignore;
@@ -523,22 +526,22 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
vgic_unlock_rank(v, rank, flags);
return 1;
- case GICD_NSACR ... GICD_NSACRN:
+ case VRANGE32(GICD_NSACR, GICD_NSACRN):
/* We do not implement security extensions for guests, write ignore */
goto write_ignore_32;
- case GICD_SGIR:
+ case VREG32(GICD_SGIR):
if ( dabt.size != DABT_WORD ) goto bad_width;
return vgic_v2_to_sgi(v, r);
- case GICD_CPENDSGIR ... GICD_CPENDSGIRN:
+ case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
"%pv: vGICD: unhandled %s write %#"PRIregister" to ICPENDSGIR%d\n",
v, dabt.size ? "word" : "byte", r, gicd_reg - GICD_CPENDSGIR);
return 0;
- case GICD_SPENDSGIR ... GICD_SPENDSGIRN:
+ case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
"%pv: vGICD: unhandled %s write %#"PRIregister" to ISPENDSGIR%d\n",
@@ -550,7 +553,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
goto write_ignore;
/* R/O -- write ignore */
- case GICD_ICPIDR2:
+ case VREG32(GICD_ICPIDR2):
goto write_ignore_32;
/* Implementation defined -- write ignored */
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 0f6cb95..892104d 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -30,6 +30,7 @@
#include <asm/mmio.h>
#include <asm/gic_v3_defs.h>
#include <asm/vgic.h>
+#include <asm/vgic-emul.h>
/*
* PIDR2: Only bits[7:4] are not implementation defined. We are
@@ -172,15 +173,16 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
switch ( gicr_reg )
{
- case GICR_CTLR:
+ case VREG32(GICR_CTLR):
/* We have not implemented LPI's, read zero */
goto read_as_zero_32;
- case GICR_IIDR:
+
+ case VREG32(GICR_IIDR):
if ( dabt.size != DABT_WORD ) goto bad_width;
*r = vgic_reg32_extract(GICV3_GICR_IIDR_VAL, info);
return 1;
- case GICR_TYPER:
- case GICR_TYPER + 4:
+
+ case VREG64(GICR_TYPER):
{
uint64_t typer, aff;
@@ -199,40 +201,51 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case GICR_STATUSR:
+
+ case VREG32(GICR_STATUSR):
/* Not implemented */
goto read_as_zero_32;
- case GICR_WAKER:
+
+ case VREG32(GICR_WAKER):
/* Power management is not implemented */
goto read_as_zero_32;
- case GICR_SETLPIR:
+
+ case VREG64(GICR_SETLPIR):
/* WO. Read as zero */
goto read_as_zero_64;
- case GICR_CLRLPIR:
+
+ case VREG64(GICR_CLRLPIR):
/* WO. Read as zero */
goto read_as_zero_64;
- case GICR_PROPBASER:
+
+ case VREG64(GICR_PROPBASER):
/* LPI's not implemented */
goto read_as_zero_64;
- case GICR_PENDBASER:
+
+ case VREG64(GICR_PENDBASER):
/* LPI's not implemented */
goto read_as_zero_64;
- case GICR_INVLPIR:
+
+ case VREG64(GICR_INVLPIR):
/* WO. Read as zero */
goto read_as_zero_64;
- case GICR_INVALLR:
+
+ case VREG64(GICR_INVALLR):
/* WO. Read as zero */
goto read_as_zero_64;
return 0;
- case GICR_SYNCR:
+
+ case VREG32(GICR_SYNCR):
if ( dabt.size != DABT_WORD ) goto bad_width;
/* RO . But when read it always returns busy bito bit[0] */
*r = vgic_reg32_extract(GICR_SYNCR_NOT_BUSY, info);
return 1;
- case GICR_MOVLPIR:
+
+ case VREG64(GICR_MOVLPIR):
/* WO Read as zero */
goto read_as_zero_64;
- case GICR_MOVALLR:
+
+ case VREG64(GICR_MOVALLR):
/* WO Read as zero */
goto read_as_zero_64;
@@ -240,7 +253,7 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
/* Implementation defined identification registers */
goto read_impl_defined;
- case GICR_PIDR2:
+ case VREG32(GICR_PIDR2):
if ( dabt.size != DABT_WORD ) goto bad_width;
*r = vgic_reg32_extract(GICV3_GICR_PIDR2, info);
return 1;
@@ -287,46 +300,59 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
switch ( gicr_reg )
{
- case GICR_CTLR:
+ case VREG32(GICR_CTLR):
/* LPI's not implemented */
goto write_ignore_32;
- case GICR_IIDR:
+
+ case VREG32(GICR_IIDR):
/* RO */
goto write_ignore_32;
- case GICR_TYPER:
+
+ case VREG64(GICR_TYPER):
/* RO */
goto write_ignore_64;
- case GICR_STATUSR:
+
+ case VREG32(GICR_STATUSR):
/* Not implemented */
goto write_ignore_32;
- case GICR_WAKER:
+
+ case VREG32(GICR_WAKER):
/* Power mgmt not implemented */
goto write_ignore_32;
- case GICR_SETLPIR:
+
+ case VREG64(GICR_SETLPIR):
/* LPI is not implemented */
goto write_ignore_64;
- case GICR_CLRLPIR:
+
+ case VREG64(GICR_CLRLPIR):
/* LPI is not implemented */
goto write_ignore_64;
- case GICR_PROPBASER:
+
+ case VREG64(GICR_PROPBASER):
/* LPI is not implemented */
goto write_ignore_64;
- case GICR_PENDBASER:
+
+ case VREG64(GICR_PENDBASER):
/* LPI is not implemented */
goto write_ignore_64;
- case GICR_INVLPIR:
+
+ case VREG64(GICR_INVLPIR):
/* LPI is not implemented */
goto write_ignore_64;
- case GICR_INVALLR:
+
+ case VREG64(GICR_INVALLR):
/* LPI is not implemented */
goto write_ignore_64;
- case GICR_SYNCR:
+
+ case VREG32(GICR_SYNCR):
/* RO */
goto write_ignore_32;
- case GICR_MOVLPIR:
+
+ case VREG64(GICR_MOVLPIR):
/* LPI is not implemented */
goto write_ignore_64;
- case GICR_MOVALLR:
+
+ case VREG64(GICR_MOVALLR):
/* LPI is not implemented */
goto write_ignore_64;
@@ -334,7 +360,7 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
/* Implementation defined identification registers */
goto write_impl_defined;
- case GICR_PIDR2:
+ case VREG32(GICR_PIDR2):
/* RO */
goto write_ignore_32;
@@ -379,11 +405,12 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
switch ( reg )
{
- case GICD_IGROUPR ... GICD_IGROUPRN:
+ case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
/* We do not implement security extensions for guests, read zero */
if ( dabt.size != DABT_WORD ) goto bad_width;
goto read_as_zero;
- case GICD_ISENABLER ... GICD_ISENABLERN:
+
+ case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
if ( dabt.size != DABT_WORD ) goto bad_width;
rank = vgic_rank_offset(v, 1, reg - GICD_ISENABLER, DABT_WORD);
if ( rank == NULL ) goto read_as_zero;
@@ -391,7 +418,8 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
*r = vgic_reg32_extract(rank->ienable, info);
vgic_unlock_rank(v, rank, flags);
return 1;
- case GICD_ICENABLER ... GICD_ICENABLERN:
+
+ case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):
if ( dabt.size != DABT_WORD ) goto bad_width;
rank = vgic_rank_offset(v, 1, reg - GICD_ICENABLER, DABT_WORD);
if ( rank == NULL ) goto read_as_zero;
@@ -399,17 +427,18 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
*r = vgic_reg32_extract(rank->ienable, info);
vgic_unlock_rank(v, rank, flags);
return 1;
+
/* Read the pending status of an IRQ via GICD/GICR is not supported */
- case GICD_ISPENDR ... GICD_ISPENDRN:
- case GICD_ICPENDR ... GICD_ICPENDRN:
+ case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
+ case VRANGE32(GICD_ICPENDR, GICD_ICPENDR):
goto read_as_zero;
/* Read the active status of an IRQ via GICD/GICR is not supported */
- case GICD_ISACTIVER ... GICD_ISACTIVERN:
- case GICD_ICACTIVER ... GICD_ICACTIVERN:
+ case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVER):
+ case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
goto read_as_zero;
- case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
+ case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
{
uint32_t ipriorityr;
@@ -427,7 +456,7 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
return 1;
}
- case GICD_ICFGR ... GICD_ICFGRN:
+ case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
{
uint32_t icfgr;
@@ -442,6 +471,7 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
return 1;
}
+
default:
printk(XENLOG_G_ERR
"%pv: %s: unhandled read r%d offset %#08x\n",
@@ -471,10 +501,11 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
switch ( reg )
{
- case GICD_IGROUPR ... GICD_IGROUPRN:
+ case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
/* We do not implement security extensions for guests, write ignore */
goto write_ignore_32;
- case GICD_ISENABLER ... GICD_ISENABLERN:
+
+ case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
if ( dabt.size != DABT_WORD ) goto bad_width;
rank = vgic_rank_offset(v, 1, reg - GICD_ISENABLER, DABT_WORD);
if ( rank == NULL ) goto write_ignore;
@@ -484,7 +515,8 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
vgic_enable_irqs(v, (rank->ienable) & (~tr), rank->index);
vgic_unlock_rank(v, rank, flags);
return 1;
- case GICD_ICENABLER ... GICD_ICENABLERN:
+
+ case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):
if ( dabt.size != DABT_WORD ) goto bad_width;
rank = vgic_rank_offset(v, 1, reg - GICD_ICENABLER, DABT_WORD);
if ( rank == NULL ) goto write_ignore;
@@ -494,35 +526,36 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
vgic_disable_irqs(v, (~rank->ienable) & tr, rank->index);
vgic_unlock_rank(v, rank, flags);
return 1;
- case GICD_ISPENDR ... GICD_ISPENDRN:
+
+ case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
if ( dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
"%pv: %s: unhandled word write %#"PRIregister" to ISPENDR%d\n",
v, name, r, reg - GICD_ISPENDR);
return 0;
- case GICD_ICPENDR ... GICD_ICPENDRN:
+ case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
if ( dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
"%pv: %s: unhandled word write %#"PRIregister" to ICPENDR%d\n",
v, name, r, reg - GICD_ICPENDR);
return 0;
- case GICD_ISACTIVER ... GICD_ISACTIVERN:
+ case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN):
if ( dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
"%pv: %s: unhandled word write %#"PRIregister" to ISACTIVER%d\n",
v, name, r, reg - GICD_ISACTIVER);
return 0;
- case GICD_ICACTIVER ... GICD_ICACTIVERN:
+ case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
if ( dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
"%pv: %s: unhandled word write %#"PRIregister" to ICACTIVER%d\n",
v, name, r, reg - GICD_ICACTIVER);
return 0;
- case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
+ case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
{
uint32_t *ipriorityr;
@@ -536,9 +569,11 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
vgic_unlock_rank(v, rank, flags);
return 1;
}
- case GICD_ICFGR: /* Restricted to configure SGIs */
+
+ case VREG32(GICD_ICFGR): /* Restricted to configure SGIs */
goto write_ignore_32;
- case GICD_ICFGR + 4 ... GICD_ICFGRN: /* PPI + SPIs */
+
+ case VRANGE32(GICD_ICFGR + 4, GICD_ICFGRN): /* PPI + SPIs */
/* ICFGR1 for PPI's, which is implementation defined
if ICFGR1 is programmable or not. We chose to program */
if ( dabt.size != DABT_WORD ) goto bad_width;
@@ -578,16 +613,17 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info,
switch ( gicr_reg )
{
- case GICR_IGRPMODR0:
+ case VREG32(GICR_IGRPMODR0):
/* We do not implement security extensions for guests, read zero */
goto read_as_zero_32;
- case GICR_IGROUPR0:
- case GICR_ISENABLER0:
- case GICR_ICENABLER0:
- case GICR_ISACTIVER0:
- case GICR_ICACTIVER0:
- case GICR_IPRIORITYR0...GICR_IPRIORITYR7:
- case GICR_ICFGR0... GICR_ICFGR1:
+
+ case VREG32(GICR_IGROUPR0):
+ case VREG32(GICR_ISENABLER0):
+ case VREG32(GICR_ICENABLER0):
+ case VREG32(GICR_ISACTIVER0):
+ case VREG32(GICR_ICACTIVER0):
+ case VRANGE32(GICR_IPRIORITYR0, GICR_IPRIORITYR7):
+ case VRANGE32(GICR_ICFGR0, GICR_ICFGR1):
/*
* Above registers offset are common with GICD.
* So handle in common with GICD handling
@@ -596,11 +632,11 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info,
gicr_reg, r);
/* Read the pending status of an SGI is via GICR is not supported */
- case GICR_ISPENDR0:
- case GICR_ICPENDR0:
+ case VREG32(GICR_ISPENDR0):
+ case VREG32(GICR_ICPENDR0):
goto read_as_zero;
- case GICR_NSACR:
+ case VREG32(GICR_NSACR):
/* We do not implement security extensions for guests, read zero */
goto read_as_zero_32;
@@ -630,39 +666,42 @@ static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info,
switch ( gicr_reg )
{
- case GICR_IGRPMODR0:
+ case VREG32(GICR_IGRPMODR0):
/* We do not implement security extensions for guests, write ignore */
goto write_ignore_32;
- case GICR_IGROUPR0:
- case GICR_ISENABLER0:
- case GICR_ICENABLER0:
- case GICR_ISACTIVER0:
- case GICR_ICACTIVER0:
- case GICR_ICFGR1:
- case GICR_IPRIORITYR0...GICR_IPRIORITYR7:
+
+ case VREG32(GICR_IGROUPR0):
+ case VREG32(GICR_ISENABLER0):
+ case VREG32(GICR_ICENABLER0):
+ case VREG32(GICR_ISACTIVER0):
+ case VREG32(GICR_ICACTIVER0):
+ case VREG32(GICR_ICFGR1):
+ case VRANGE32(GICR_IPRIORITYR0, GICR_IPRIORITYR7):
/*
* Above registers offset are common with GICD.
* So handle common with GICD handling
*/
return __vgic_v3_distr_common_mmio_write("vGICR: SGI", v,
info, gicr_reg, r);
- case GICR_ISPENDR0:
+
+ case VREG32(GICR_ISPENDR0):
if ( dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
"%pv: vGICR: SGI: unhandled word write %#"PRIregister" to ISPENDR0\n",
v, r);
return 0;
- case GICR_ICPENDR0:
+ case VREG32(GICR_ICPENDR0):
if ( dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
"%pv: vGICR: SGI: unhandled word write %#"PRIregister" to ICPENDR0\n",
v, r);
return 0;
- case GICR_NSACR:
+ case VREG32(GICR_NSACR):
/* We do not implement security extensions for guests, write ignore */
goto write_ignore_32;
+
default:
printk(XENLOG_G_ERR
"%pv: vGICR: SGI: unhandled write r%d offset %#08x\n",
@@ -761,13 +800,14 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
switch ( gicd_reg )
{
- case GICD_CTLR:
+ case VREG32(GICD_CTLR):
if ( dabt.size != DABT_WORD ) goto bad_width;
vgic_lock(v);
*r = vgic_reg32_extract(v->domain->arch.vgic.ctlr, info);
vgic_unlock(v);
return 1;
- case GICD_TYPER:
+
+ case VREG32(GICD_TYPER):
{
/*
* Number of interrupt identifier bits supported by the GIC
@@ -792,34 +832,39 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case GICD_STATUSR:
+
+ case VREG32(GICD_STATUSR):
/*
* Optional, Not implemented for now.
* Update to support guest debugging.
*/
goto read_as_zero_32;
- case GICD_IIDR:
+
+ case VREG32(GICD_IIDR):
if ( dabt.size != DABT_WORD ) goto bad_width;
*r = vgic_reg32_extract(GICV3_GICD_IIDR_VAL, info);
return 1;
+
case 0x020 ... 0x03c:
case 0xc000 ... 0xffcc:
/* Implementation defined -- read as zero */
goto read_as_zero_32;
- case GICD_IGROUPR ... GICD_IGROUPRN:
- case GICD_ISENABLER ... GICD_ISENABLERN:
- case GICD_ICENABLER ... GICD_ICENABLERN:
- case GICD_ISPENDR ... GICD_ISPENDRN:
- case GICD_ICPENDR ... GICD_ICPENDRN:
- case GICD_ISACTIVER ... GICD_ISACTIVERN:
- case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
- case GICD_ICFGR ... GICD_ICFGRN:
+
+ case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
+ case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
+ case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):
+ case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
+ case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
+ case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN):
+ case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
+ case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
/*
* Above all register are common with GICR and GICD
* Manage in common
*/
return __vgic_v3_distr_common_mmio_read("vGICD", v, info, gicd_reg, r);
- case GICD_IROUTER32 ... GICD_IROUTER1019:
+
+ case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
{
uint64_t irouter;
@@ -836,16 +881,19 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case GICD_NSACR ... GICD_NSACRN:
+ case VRANGE32(GICD_NSACR, GICD_NSACRN):
/* We do not implement security extensions for guests, read zero */
goto read_as_zero_32;
- case GICD_SGIR:
+
+ case VREG32(GICD_SGIR):
/* Read as ICH_SGIR system register with SRE set. So ignore */
goto read_as_zero_32;
- case GICD_CPENDSGIR ... GICD_CPENDSGIRN:
+
+ case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
/* Replaced with GICR_ICPENDR0. So ignore write */
goto read_as_zero_32;
- case GICD_SPENDSGIR ... GICD_SPENDSGIRN:
+
+ case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
/* Replaced with GICR_ISPENDR0. So ignore write */
goto read_as_zero_32;
@@ -853,7 +901,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
/* Implementation defined identification registers */
goto read_impl_defined;
- case GICD_PIDR2:
+ case VREG32(GICD_PIDR2):
/* GICv3 identification value */
if ( dabt.size != DABT_WORD ) goto bad_width;
*r = vgic_reg32_extract(GICV3_GICD_PIDR2, info);
@@ -915,7 +963,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
switch ( gicd_reg )
{
- case GICD_CTLR:
+ case VREG32(GICD_CTLR):
{
uint32_t ctlr = 0;
@@ -934,27 +982,35 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case GICD_TYPER:
+
+ case VREG32(GICD_TYPER):
/* RO -- write ignored */
goto write_ignore_32;
- case GICD_IIDR:
+
+ case VREG32(GICD_IIDR):
/* RO -- write ignored */
goto write_ignore_32;
- case GICD_STATUSR:
+
+ case VREG32(GICD_STATUSR):
/* RO -- write ignored */
goto write_ignore_32;
- case GICD_SETSPI_NSR:
+
+ case VREG32(GICD_SETSPI_NSR):
/* Message based SPI is not implemented */
goto write_ignore_32;
- case GICD_CLRSPI_NSR:
+
+ case VREG32(GICD_CLRSPI_NSR):
/* Message based SPI is not implemented */
goto write_ignore_32;
- case GICD_SETSPI_SR:
+
+ case VREG32(GICD_SETSPI_SR):
/* Message based SPI is not implemented */
goto write_ignore_32;
- case GICD_CLRSPI_SR:
+
+ case VREG32(GICD_CLRSPI_SR):
/* Message based SPI is not implemented */
goto write_ignore_32;
+
case 0x020 ... 0x03c:
case 0xc000 ... 0xffcc:
/* Implementation defined -- write ignored */
@@ -962,20 +1018,22 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
"%pv: vGICD: WI on implementation defined register offset %#08x\n",
v, gicd_reg);
goto write_ignore_32;
- case GICD_IGROUPR ... GICD_IGROUPRN:
- case GICD_ISENABLER ... GICD_ISENABLERN:
- case GICD_ICENABLER ... GICD_ICENABLERN:
- case GICD_ISPENDR ... GICD_ISPENDRN:
- case GICD_ICPENDR ... GICD_ICPENDRN:
- case GICD_ISACTIVER ... GICD_ISACTIVERN:
- case GICD_ICACTIVER ... GICD_ICACTIVERN:
- case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
- case GICD_ICFGR ... GICD_ICFGRN:
+
+ case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
+ case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
+ case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):
+ case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
+ case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
+ case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN):
+ case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
+ case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
+ case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
/* Above registers are common with GICR and GICD
* Manage in common */
return __vgic_v3_distr_common_mmio_write("vGICD", v, info,
gicd_reg, r);
- case GICD_IROUTER32 ... GICD_IROUTER1019:
+
+ case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
{
uint64_t irouter;
@@ -991,17 +1049,20 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case GICD_NSACR ... GICD_NSACRN:
+ case VRANGE32(GICD_NSACR, GICD_NSACRN):
/* We do not implement security extensions for guests, write ignore */
goto write_ignore_32;
- case GICD_SGIR:
+
+ case VREG32(GICD_SGIR):
/* it is accessed as system register in GICv3 */
goto write_ignore_32;
- case GICD_CPENDSGIR ... GICD_CPENDSGIRN:
+
+ case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
/* Replaced with GICR_ICPENDR0. So ignore write */
if ( dabt.size != DABT_WORD ) goto bad_width;
return 0;
- case GICD_SPENDSGIR ... GICD_SPENDSGIRN:
+
+ case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
/* Replaced with GICR_ISPENDR0. So ignore write */
if ( dabt.size != DABT_WORD ) goto bad_width;
return 0;
@@ -1010,7 +1071,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
/* Implementation defined identification registers */
goto write_impl_defined;
- case GICD_PIDR2:
+ case VREG32(GICD_PIDR2):
/* RO -- write ignore */
goto write_ignore_32;
diff --git a/xen/include/asm-arm/vgic-emul.h b/xen/include/asm-arm/vgic-emul.h
new file mode 100644
index 0000000..184a1f0
--- /dev/null
+++ b/xen/include/asm-arm/vgic-emul.h
@@ -0,0 +1,24 @@
+#ifndef __ASM_ARM_VGIC_EMUL_H__
+#define __ASM_ARM_VGIC_EMUL_H__
+
+/*
+ * Helpers to create easily a case to match emulate a single register or
+ * a range of registers
+ */
+
+#define VREG32(reg) reg ... reg + 3
+#define VREG64(reg) reg ... reg + 7
+
+#define VRANGE32(start, end) start ... end + 3
+#define VRANGE64(start, end) start ... end + 7
+
+#endif /* __ASM_ARM_VGIC_EMUL_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
2.1.4
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v2 05/11] xen/arm: vgic: Properly emulate the full register
2015-11-18 17:28 ` [PATCH v2 05/11] xen/arm: vgic: Properly emulate the full register Julien Grall
@ 2015-11-25 9:26 ` Shannon Zhao
2015-11-25 12:15 ` unhandled word causes Xen crash with recent Linux kernels, was: " Stefano Stabellini
0 siblings, 1 reply; 24+ messages in thread
From: Shannon Zhao @ 2015-11-25 9:26 UTC (permalink / raw)
To: Julien Grall, xen-devel; +Cc: ian.campbell, stefano.stabellini
Hi Julien,
On 2015/11/19 1:28, Julien Grall wrote:
> - case GICD_ICACTIVER ... GICD_ICACTIVERN:
> + case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
> if ( dabt.size != DABT_WORD ) goto bad_width;
> printk(XENLOG_G_ERR
> "%pv: vGICD: unhandled word write %#"PRIregister" to ICACTIVER%d\n",
> v, r, gicd_reg - GICD_ICACTIVER);
> return 0;
Maybe this question is not related to what this patch does. But I have a
problem when I rebase my ACPI patches on upstream Linux kernel.
Upstream Linux kernel applies below patch which will write
GICD_ICACTIVER. But since Xen doesn't support it, so it will cause Dom0
initializes GIC failed.
0eece2b22849c90b730815c893425a36b9d10fd5 (irqchip/gic: Make sure all
interrupts are deactivated at boot)
(XEN) d0v0: vGICD: unhandled word write 0xffffffff to ICACTIVER4
(XEN) traps.c:2447:d0v0 HSR=0x93860046 pc=0xffffffc0008d63f0
gva=0xffffff8000004384 gpa=0x0000002f000384
(XEN) DOM0: Unhandled fault: ttbr address size fault (0x96000000) at
0xffffff8000004384
(XEN) DOM0: Internal error: : 96000000 [#1] PREEMPT SMP
(XEN) DOM0: Modules linked in:
(XEN) DOM0: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.0-rc2+ #364
(XEN) DOM0: Hardware name: (null) (DT)
(XEN) DOM0: task: ffffffc000969970 ti: ffffffc00095c000 task.ti:
ffffffc00095c000
(XEN) DOM0: PC is at gic_dist_config+0x78/0xa0
(XEN) DOM0: LR is at __gic_init_bases+0x240/0x2bc
Do we have a plan to fix this?
Thanks,
--
Shannon
^ permalink raw reply [flat|nested] 24+ messages in thread
* unhandled word causes Xen crash with recent Linux kernels, was: Re: [PATCH v2 05/11] xen/arm: vgic: Properly emulate the full register
2015-11-25 9:26 ` Shannon Zhao
@ 2015-11-25 12:15 ` Stefano Stabellini
2015-11-25 12:26 ` Ian Campbell
2015-11-30 12:18 ` Julien Grall
0 siblings, 2 replies; 24+ messages in thread
From: Stefano Stabellini @ 2015-11-25 12:15 UTC (permalink / raw)
To: Shannon Zhao; +Cc: Julien Grall, xen-devel, ian.campbell, stefano.stabellini
Hi Shannon,
On Wed, 25 Nov 2015, Shannon Zhao wrote:
> Upstream Linux kernel applies below patch which will write
> GICD_ICACTIVER. But since Xen doesn't support it, so it will cause Dom0
> initializes GIC failed.
>
> 0eece2b22849c90b730815c893425a36b9d10fd5 (irqchip/gic: Make sure all
> interrupts are deactivated at boot)
>
> (XEN) d0v0: vGICD: unhandled word write 0xffffffff to ICACTIVER4
> (XEN) traps.c:2447:d0v0 HSR=0x93860046 pc=0xffffffc0008d63f0
> gva=0xffffff8000004384 gpa=0x0000002f000384
> (XEN) DOM0: Unhandled fault: ttbr address size fault (0x96000000) at
> 0xffffff8000004384
> (XEN) DOM0: Internal error: : 96000000 [#1] PREEMPT SMP
> (XEN) DOM0: Modules linked in:
> (XEN) DOM0: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.0-rc2+ #364
> (XEN) DOM0: Hardware name: (null) (DT)
> (XEN) DOM0: task: ffffffc000969970 ti: ffffffc00095c000 task.ti:
> ffffffc00095c000
> (XEN) DOM0: PC is at gic_dist_config+0x78/0xa0
> (XEN) DOM0: LR is at __gic_init_bases+0x240/0x2bc
>
> Do we have a plan to fix this?
Thanks for the reporting the issue, I can reproduce the problem. Given
that this is a very serious regression and that we cannot really "fix"
the Linux side because Linux is not doing anything wrong, I think we
have to go with a very simple change, something we can easily backport
to all past Xen releases.
I suggest we turn the "unhandled word write" into a write_ignore, see
below:
---
xen/arm: ignore GICD_ICACTIVER writes
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index f7d784b..8585c44 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -332,11 +332,8 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
return 0;
case GICD_ICACTIVER ... GICD_ICACTIVERN:
- if ( dabt.size != DABT_WORD ) goto bad_width;
- printk(XENLOG_G_ERR
- "%pv: vGICD: unhandled word write %#"PRIregister" to ICACTIVER%d\n",
- v, r, gicd_reg - GICD_ICACTIVER);
- return 0;
+ /* we should really be implementing this */
+ goto write_ignore_32;
case GICD_ITARGETSR ... GICD_ITARGETSR + 7:
/* SGI/PPI target is read only */
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index b5249ff..6d77373 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -421,11 +421,8 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
return 0;
case GICD_ICACTIVER ... GICD_ICACTIVERN:
- if ( dabt.size != DABT_WORD ) goto bad_width;
- printk(XENLOG_G_ERR
- "%pv: %s: unhandled word write %#"PRIregister" to ICACTIVER%d\n",
- v, name, r, reg - GICD_ICACTIVER);
- return 0;
+ /* we should really be implementing this */
+ goto write_ignore_32;
case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: unhandled word causes Xen crash with recent Linux kernels, was: Re: [PATCH v2 05/11] xen/arm: vgic: Properly emulate the full register
2015-11-25 12:15 ` unhandled word causes Xen crash with recent Linux kernels, was: " Stefano Stabellini
@ 2015-11-25 12:26 ` Ian Campbell
2015-11-30 12:22 ` Julien Grall
2015-11-30 12:18 ` Julien Grall
1 sibling, 1 reply; 24+ messages in thread
From: Ian Campbell @ 2015-11-25 12:26 UTC (permalink / raw)
To: Stefano Stabellini, Shannon Zhao; +Cc: Julien Grall, xen-devel
On Wed, 2015-11-25 at 12:15 +0000, Stefano Stabellini wrote:
> Hi Shannon,
>
> On Wed, 25 Nov 2015, Shannon Zhao wrote:
> > Upstream Linux kernel applies below patch which will write
> > GICD_ICACTIVER. But since Xen doesn't support it, so it will cause Dom0
> > initializes GIC failed.
> >
> > 0eece2b22849c90b730815c893425a36b9d10fd5 (irqchip/gic: Make sure all
> > interrupts are deactivated at boot)
> >
> > (XEN) d0v0: vGICD: unhandled word write 0xffffffff to ICACTIVER4
> > (XEN) traps.c:2447:d0v0 HSR=0x93860046 pc=0xffffffc0008d63f0
> > gva=0xffffff8000004384 gpa=0x0000002f000384
> > (XEN) DOM0: Unhandled fault: ttbr address size fault (0x96000000) at
> > 0xffffff8000004384
> > (XEN) DOM0: Internal error: : 96000000 [#1] PREEMPT SMP
> > (XEN) DOM0: Modules linked in:
> > (XEN) DOM0: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.0-rc2+ #364
> > (XEN) DOM0: Hardware name: (null) (DT)
> > (XEN) DOM0: task: ffffffc000969970 ti: ffffffc00095c000 task.ti:
> > ffffffc00095c000
> > (XEN) DOM0: PC is at gic_dist_config+0x78/0xa0
> > (XEN) DOM0: LR is at __gic_init_bases+0x240/0x2bc
> >
> > Do we have a plan to fix this?
>
> Thanks for the reporting the issue, I can reproduce the problem. Given
> that this is a very serious regression and that we cannot really "fix"
> the Linux side because Linux is not doing anything wrong, I think we
> have to go with a very simple change, something we can easily backport
> to all past Xen releases.
>
> I suggest we turn the "unhandled word write" into a write_ignore, see
> below:
As discussed IRL this might be tolerable as a patch intended for
backporting purposes, but I would want to see it in a series along with one
or more not-for-backport patches which actually makes the register work as
it should.
>
> ---
>
> xen/arm: ignore GICD_ICACTIVER writes
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>
> diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
> index f7d784b..8585c44 100644
> --- a/xen/arch/arm/vgic-v2.c
> +++ b/xen/arch/arm/vgic-v2.c
> @@ -332,11 +332,8 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v,
> mmio_info_t *info,
> return 0;
>
> case GICD_ICACTIVER ... GICD_ICACTIVERN:
> - if ( dabt.size != DABT_WORD ) goto bad_width;
> - printk(XENLOG_G_ERR
> - "%pv: vGICD: unhandled word write %#"PRIregister" to
> ICACTIVER%d\n",
> - v, r, gicd_reg - GICD_ICACTIVER);
> - return 0;
> + /* we should really be implementing this */
> + goto write_ignore_32;
>
> case GICD_ITARGETSR ... GICD_ITARGETSR + 7:
> /* SGI/PPI target is read only */
> diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
> index b5249ff..6d77373 100644
> --- a/xen/arch/arm/vgic-v3.c
> +++ b/xen/arch/arm/vgic-v3.c
> @@ -421,11 +421,8 @@ static int __vgic_v3_distr_common_mmio_write(const
> char *name, struct vcpu *v,
> return 0;
>
> case GICD_ICACTIVER ... GICD_ICACTIVERN:
> - if ( dabt.size != DABT_WORD ) goto bad_width;
> - printk(XENLOG_G_ERR
> - "%pv: %s: unhandled word write %#"PRIregister" to
> ICACTIVER%d\n",
> - v, name, r, reg - GICD_ICACTIVER);
> - return 0;
> + /* we should really be implementing this */
> + goto write_ignore_32;
>
> case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
> if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto
> bad_width;
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: unhandled word causes Xen crash with recent Linux kernels, was: Re: [PATCH v2 05/11] xen/arm: vgic: Properly emulate the full register
2015-11-25 12:26 ` Ian Campbell
@ 2015-11-30 12:22 ` Julien Grall
2015-11-30 12:38 ` Ian Campbell
0 siblings, 1 reply; 24+ messages in thread
From: Julien Grall @ 2015-11-30 12:22 UTC (permalink / raw)
To: Ian Campbell, Stefano Stabellini, Shannon Zhao; +Cc: xen-devel
Hi Ian,
On 25/11/15 12:26, Ian Campbell wrote:
> On Wed, 2015-11-25 at 12:15 +0000, Stefano Stabellini wrote:
>> On Wed, 25 Nov 2015, Shannon Zhao wrote:
>>> Upstream Linux kernel applies below patch which will write
>>> GICD_ICACTIVER. But since Xen doesn't support it, so it will cause Dom0
>>> initializes GIC failed.
>>>
>>> 0eece2b22849c90b730815c893425a36b9d10fd5 (irqchip/gic: Make sure all
>>> interrupts are deactivated at boot)
>>>
>>> (XEN) d0v0: vGICD: unhandled word write 0xffffffff to ICACTIVER4
>>> (XEN) traps.c:2447:d0v0 HSR=0x93860046 pc=0xffffffc0008d63f0
>>> gva=0xffffff8000004384 gpa=0x0000002f000384
>>> (XEN) DOM0: Unhandled fault: ttbr address size fault (0x96000000) at
>>> 0xffffff8000004384
>>> (XEN) DOM0: Internal error: : 96000000 [#1] PREEMPT SMP
>>> (XEN) DOM0: Modules linked in:
>>> (XEN) DOM0: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.0-rc2+ #364
>>> (XEN) DOM0: Hardware name: (null) (DT)
>>> (XEN) DOM0: task: ffffffc000969970 ti: ffffffc00095c000 task.ti:
>>> ffffffc00095c000
>>> (XEN) DOM0: PC is at gic_dist_config+0x78/0xa0
>>> (XEN) DOM0: LR is at __gic_init_bases+0x240/0x2bc
>>>
>>> Do we have a plan to fix this?
>>
>> Thanks for the reporting the issue, I can reproduce the problem. Given
>> that this is a very serious regression and that we cannot really "fix"
>> the Linux side because Linux is not doing anything wrong, I think we
>> have to go with a very simple change, something we can easily backport
>> to all past Xen releases.
>>
>> I suggest we turn the "unhandled word write" into a write_ignore, see
>> below:
>
> As discussed IRL this might be tolerable as a patch intended for
> backporting purposes, but I would want to see it in a series along with one
> or more not-for-backport patches which actually makes the register work as
> it should.
I have the feeling that fixing properly GICD_I*ACTIVER will take
sometimes as we also need to take into consideration hardware interrupt
routed to a guest.
As this is preventing Linux upstream to run on the latest, can we get a
simple fix for now?
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: unhandled word causes Xen crash with recent Linux kernels, was: Re: [PATCH v2 05/11] xen/arm: vgic: Properly emulate the full register
2015-11-30 12:22 ` Julien Grall
@ 2015-11-30 12:38 ` Ian Campbell
2015-12-03 10:50 ` Stefano Stabellini
0 siblings, 1 reply; 24+ messages in thread
From: Ian Campbell @ 2015-11-30 12:38 UTC (permalink / raw)
To: Julien Grall, Stefano Stabellini, Shannon Zhao; +Cc: xen-devel
On Mon, 2015-11-30 at 12:22 +0000, Julien Grall wrote:
> Hi Ian,
>
> On 25/11/15 12:26, Ian Campbell wrote:
> > On Wed, 2015-11-25 at 12:15 +0000, Stefano Stabellini wrote:
> > > On Wed, 25 Nov 2015, Shannon Zhao wrote:
> > > > Upstream Linux kernel applies below patch which will write
> > > > GICD_ICACTIVER. But since Xen doesn't support it, so it will cause
> > > > Dom0
> > > > initializes GIC failed.
> > > >
> > > > 0eece2b22849c90b730815c893425a36b9d10fd5 (irqchip/gic: Make sure
> > > > all
> > > > interrupts are deactivated at boot)
> > > >
> > > > (XEN) d0v0: vGICD: unhandled word write 0xffffffff to ICACTIVER4
> > > > (XEN) traps.c:2447:d0v0 HSR=0x93860046 pc=0xffffffc0008d63f0
> > > > gva=0xffffff8000004384 gpa=0x0000002f000384
> > > > (XEN) DOM0: Unhandled fault: ttbr address size fault (0x96000000)
> > > > at
> > > > 0xffffff8000004384
> > > > (XEN) DOM0: Internal error: : 96000000 [#1] PREEMPT SMP
> > > > (XEN) DOM0: Modules linked in:
> > > > (XEN) DOM0: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.0-rc2+
> > > > #364
> > > > (XEN) DOM0: Hardware name: (null) (DT)
> > > > (XEN) DOM0: task: ffffffc000969970 ti: ffffffc00095c000 task.ti:
> > > > ffffffc00095c000
> > > > (XEN) DOM0: PC is at gic_dist_config+0x78/0xa0
> > > > (XEN) DOM0: LR is at __gic_init_bases+0x240/0x2bc
> > > >
> > > > Do we have a plan to fix this?
> > >
> > > Thanks for the reporting the issue, I can reproduce the
> > > problem. Given
> > > that this is a very serious regression and that we cannot really
> > > "fix"
> > > the Linux side because Linux is not doing anything wrong, I think we
> > > have to go with a very simple change, something we can easily
> > > backport
> > > to all past Xen releases.
> > >
> > > I suggest we turn the "unhandled word write" into a write_ignore, see
> > > below:
> >
> > As discussed IRL this might be tolerable as a patch intended for
> > backporting purposes, but I would want to see it in a series along with
> > one
> > or more not-for-backport patches which actually makes the register work
> > as
> > it should.
>
> I have the feeling that fixing properly GICD_I*ACTIVER will take
> sometimes as we also need to take into consideration hardware interrupt
> routed to a guest.
>
> As this is preventing Linux upstream to run on the latest, can we get a
> simple fix for now?
With a suitable commit message explaining the interim/backportability
nature of this patch and the intention to do it properly I'd be willing to
accept it.
Ian.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: unhandled word causes Xen crash with recent Linux kernels, was: Re: [PATCH v2 05/11] xen/arm: vgic: Properly emulate the full register
2015-11-30 12:38 ` Ian Campbell
@ 2015-12-03 10:50 ` Stefano Stabellini
0 siblings, 0 replies; 24+ messages in thread
From: Stefano Stabellini @ 2015-12-03 10:50 UTC (permalink / raw)
To: Ian Campbell; +Cc: Julien Grall, xen-devel, Shannon Zhao, Stefano Stabellini
[-- Attachment #1: Type: text/plain, Size: 2915 bytes --]
On Mon, 30 Nov 2015, Ian Campbell wrote:
> On Mon, 2015-11-30 at 12:22 +0000, Julien Grall wrote:
> > Hi Ian,
> >
> > On 25/11/15 12:26, Ian Campbell wrote:
> > > On Wed, 2015-11-25 at 12:15 +0000, Stefano Stabellini wrote:
> > > > On Wed, 25 Nov 2015, Shannon Zhao wrote:
> > > > > Upstream Linux kernel applies below patch which will write
> > > > > GICD_ICACTIVER. But since Xen doesn't support it, so it will cause
> > > > > Dom0
> > > > > initializes GIC failed.
> > > > >
> > > > > 0eece2b22849c90b730815c893425a36b9d10fd5 (irqchip/gic: Make sure
> > > > > all
> > > > > interrupts are deactivated at boot)
> > > > >
> > > > > (XEN) d0v0: vGICD: unhandled word write 0xffffffff to ICACTIVER4
> > > > > (XEN) traps.c:2447:d0v0 HSR=0x93860046 pc=0xffffffc0008d63f0
> > > > > gva=0xffffff8000004384 gpa=0x0000002f000384
> > > > > (XEN) DOM0: Unhandled fault: ttbr address size fault (0x96000000)
> > > > > at
> > > > > 0xffffff8000004384
> > > > > (XEN) DOM0: Internal error: : 96000000 [#1] PREEMPT SMP
> > > > > (XEN) DOM0: Modules linked in:
> > > > > (XEN) DOM0: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.0-rc2+
> > > > > #364
> > > > > (XEN) DOM0: Hardware name: (null) (DT)
> > > > > (XEN) DOM0: task: ffffffc000969970 ti: ffffffc00095c000 task.ti:
> > > > > ffffffc00095c000
> > > > > (XEN) DOM0: PC is at gic_dist_config+0x78/0xa0
> > > > > (XEN) DOM0: LR is at __gic_init_bases+0x240/0x2bc
> > > > >
> > > > > Do we have a plan to fix this?
> > > >
> > > > Thanks for the reporting the issue, I can reproduce the
> > > > problem. Given
> > > > that this is a very serious regression and that we cannot really
> > > > "fix"
> > > > the Linux side because Linux is not doing anything wrong, I think we
> > > > have to go with a very simple change, something we can easily
> > > > backport
> > > > to all past Xen releases.
> > > >
> > > > I suggest we turn the "unhandled word write" into a write_ignore, see
> > > > below:
> > >
> > > As discussed IRL this might be tolerable as a patch intended for
> > > backporting purposes, but I would want to see it in a series along with
> > > one
> > > or more not-for-backport patches which actually makes the register work
> > > as
> > > it should.
> >
> > I have the feeling that fixing properly GICD_I*ACTIVER will take
> > sometimes as we also need to take into consideration hardware interrupt
> > routed to a guest.
> >
> > As this is preventing Linux upstream to run on the latest, can we get a
> > simple fix for now?
>
> With a suitable commit message explaining the interim/backportability
> nature of this patch and the intention to do it properly I'd be willing to
> accept it.
OK, I'll resend with a better description.
That said, I am not sure how these registers can be implemented
properly. Even the follow-up patch I sent, doesn't implement
GICD_ICACTIVER accurately.
[-- Attachment #2: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: unhandled word causes Xen crash with recent Linux kernels, was: Re: [PATCH v2 05/11] xen/arm: vgic: Properly emulate the full register
2015-11-25 12:15 ` unhandled word causes Xen crash with recent Linux kernels, was: " Stefano Stabellini
2015-11-25 12:26 ` Ian Campbell
@ 2015-11-30 12:18 ` Julien Grall
1 sibling, 0 replies; 24+ messages in thread
From: Julien Grall @ 2015-11-30 12:18 UTC (permalink / raw)
To: Stefano Stabellini, Shannon Zhao; +Cc: xen-devel, ian.campbell
Hi Stefano,
On 25/11/15 12:15, Stefano Stabellini wrote:
> Hi Shannon,
>
> On Wed, 25 Nov 2015, Shannon Zhao wrote:
>> Upstream Linux kernel applies below patch which will write
>> GICD_ICACTIVER. But since Xen doesn't support it, so it will cause Dom0
>> initializes GIC failed.
>>
>> 0eece2b22849c90b730815c893425a36b9d10fd5 (irqchip/gic: Make sure all
>> interrupts are deactivated at boot)
>>
>> (XEN) d0v0: vGICD: unhandled word write 0xffffffff to ICACTIVER4
>> (XEN) traps.c:2447:d0v0 HSR=0x93860046 pc=0xffffffc0008d63f0
>> gva=0xffffff8000004384 gpa=0x0000002f000384
>> (XEN) DOM0: Unhandled fault: ttbr address size fault (0x96000000) at
>> 0xffffff8000004384
>> (XEN) DOM0: Internal error: : 96000000 [#1] PREEMPT SMP
>> (XEN) DOM0: Modules linked in:
>> (XEN) DOM0: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.0-rc2+ #364
>> (XEN) DOM0: Hardware name: (null) (DT)
>> (XEN) DOM0: task: ffffffc000969970 ti: ffffffc00095c000 task.ti:
>> ffffffc00095c000
>> (XEN) DOM0: PC is at gic_dist_config+0x78/0xa0
>> (XEN) DOM0: LR is at __gic_init_bases+0x240/0x2bc
>>
>> Do we have a plan to fix this?
>
> Thanks for the reporting the issue, I can reproduce the problem. Given
> that this is a very serious regression and that we cannot really "fix"
> the Linux side because Linux is not doing anything wrong, I think we
> have to go with a very simple change, something we can easily backport
> to all past Xen releases.
>
> I suggest we turn the "unhandled word write" into a write_ignore, see
> below:
>
> ---
>
> xen/arm: ignore GICD_ICACTIVER writes
This need more rational in the commit message to explain why you decided
to implement write ignore.
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>
> diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
> index f7d784b..8585c44 100644
> --- a/xen/arch/arm/vgic-v2.c
> +++ b/xen/arch/arm/vgic-v2.c
> @@ -332,11 +332,8 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
> return 0;
>
> case GICD_ICACTIVER ... GICD_ICACTIVERN:
> - if ( dabt.size != DABT_WORD ) goto bad_width;
> - printk(XENLOG_G_ERR
> - "%pv: vGICD: unhandled word write %#"PRIregister" to ICACTIVER%d\n",
> - v, r, gicd_reg - GICD_ICACTIVER);implementing write ignore is fine.
> - return 0;
I would prefer if you retain the printk, it helps the guest developer to
know that we don't support GICD_I*ACTIVER registers.
Maybe you can turn it to a XENLOG_G_DEBUG.
> + /* we should really be implementing this */
> + goto write_ignore_32;
>
> case GICD_ITARGETSR ... GICD_ITARGETSR + 7:
> /* SGI/PPI target is read only */
> diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
> index b5249ff..6d77373 100644
> --- a/xen/arch/arm/vgic-v3.c
> +++ b/xen/arch/arm/vgic-v3.c
> @@ -421,11 +421,8 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
> return 0;
>
> case GICD_ICACTIVER ... GICD_ICACTIVERN:
> - if ( dabt.size != DABT_WORD ) goto bad_width;
> - printk(XENLOG_G_ERR
> - "%pv: %s: unhandled word write %#"PRIregister" to ICACTIVER%d\n",
> - v, name, r, reg - GICD_ICACTIVER);
Ditto
> - return 0;
> + /* we should really be implementing this */
> + goto write_ignore_32;
>
> case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
> if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
>
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 06/11] xen/arm: vgic-v3: Remove GICR_MOVALLR and GICR_MOVLPIR
2015-11-18 17:27 [PATCH v2 00/11] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
` (4 preceding siblings ...)
2015-11-18 17:28 ` [PATCH v2 05/11] xen/arm: vgic: Properly emulate the full register Julien Grall
@ 2015-11-18 17:28 ` Julien Grall
2015-11-18 17:28 ` [PATCH v2 07/11] xen/arm: vgic: Re-order the register emulations to match the memory map Julien Grall
` (4 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Julien Grall @ 2015-11-18 17:28 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
The 2 registers are not described in the software spec (ARM IHI 0069A)
and their offsets are marked "implementation defined".
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
Note that I didn't combine the 2 cases because a follow-up patch
will add reserved registers between the 2 cases.
Changes in v2:
- Add Ian's acked-by
---
xen/arch/arm/vgic-v3.c | 20 ++++++++------------
xen/include/asm-arm/gic_v3_defs.h | 2 --
2 files changed, 8 insertions(+), 14 deletions(-)
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 892104d..28f075a 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -241,13 +241,11 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
*r = vgic_reg32_extract(GICR_SYNCR_NOT_BUSY, info);
return 1;
- case VREG64(GICR_MOVLPIR):
- /* WO Read as zero */
- goto read_as_zero_64;
+ case VREG64(0x0100):
+ goto read_impl_defined;
- case VREG64(GICR_MOVALLR):
- /* WO Read as zero */
- goto read_as_zero_64;
+ case VREG64(0x0110):
+ goto read_impl_defined;
case 0xFFD0 ... 0xFFE4:
/* Implementation defined identification registers */
@@ -348,13 +346,11 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
/* RO */
goto write_ignore_32;
- case VREG64(GICR_MOVLPIR):
- /* LPI is not implemented */
- goto write_ignore_64;
+ case VREG64(0x0100):
+ goto write_impl_defined;
- case VREG64(GICR_MOVALLR):
- /* LPI is not implemented */
- goto write_ignore_64;
+ case VREG64(0x0110):
+ goto write_impl_defined;
case 0xFFD0 ... 0xFFE4:
/* Implementation defined identification registers */
diff --git a/xen/include/asm-arm/gic_v3_defs.h b/xen/include/asm-arm/gic_v3_defs.h
index 5a6938c..6d98491 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -77,8 +77,6 @@
#define GICR_INVLPIR (0x00A0)
#define GICR_INVALLR (0x00B0)
#define GICR_SYNCR (0x00C0)
-#define GICR_MOVLPIR (0x100)
-#define GICR_MOVALLR (0x0110)
#define GICR_PIDR2 GICD_PIDR2
/* GICR for SGI's & PPI's */
--
2.1.4
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v2 07/11] xen/arm: vgic: Re-order the register emulations to match the memory map
2015-11-18 17:27 [PATCH v2 00/11] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
` (5 preceding siblings ...)
2015-11-18 17:28 ` [PATCH v2 06/11] xen/arm: vgic-v3: Remove GICR_MOVALLR and GICR_MOVLPIR Julien Grall
@ 2015-11-18 17:28 ` Julien Grall
2015-11-18 17:28 ` [PATCH v2 08/11] xen/arm: vgic-v3: Emulate read to GICD_ICACTIVER<n> Julien Grall
` (3 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Julien Grall @ 2015-11-18 17:28 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
It helps to find quickly whether we forgot to emulate a register or not.
At the same time add the missing reserved/implementation defined
registers. All other missing registers will be added in a follow-up if
necessary.
Note that only the distributor register map explicitely say the
size of a register (see 8.8 in ARM IHI 0069A). When the size is not
known, the implementation defined/reserved may not be emulated
correctly.
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
Note that the reserved range after IROUTER<n> is overlapping in the
spec. It has been fixup in the code to avoid a build error.
Changes in v2:
- Add Ian's acked-by
---
xen/arch/arm/vgic-v2.c | 177 ++++++++++++++++++-----------
xen/arch/arm/vgic-v3.c | 298 +++++++++++++++++++++++++++++++++++--------------
2 files changed, 328 insertions(+), 147 deletions(-)
diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index d1860a9..2c73133 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -210,9 +210,14 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
*r = vgic_reg32_extract(0x0000043b, info);
return 1;
- /* Implementation defined -- read as zero */
- case 0x020 ... 0x03c:
- goto read_as_zero;
+ case VRANGE32(0x00C, 0x01C):
+ goto read_reserved;
+
+ case VRANGE32(0x020, 0x03C):
+ goto read_impl_defined;
+
+ case VRANGE32(0x040, 0x07C):
+ goto read_reserved;
case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
/* We do not implement security extensions for guests, read zero */
@@ -246,21 +251,6 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
goto read_as_zero;
- case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSRN):
- {
- uint32_t itargetsr;
-
- if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
- rank = vgic_rank_offset(v, 8, gicd_reg - GICD_ITARGETSR, DABT_WORD);
- if ( rank == NULL) goto read_as_zero;
- vgic_lock_rank(v, rank, flags);
- itargetsr = vgic_fetch_itargetsr(rank, gicd_reg - GICD_ITARGETSR);
- vgic_unlock_rank(v, rank, flags);
- *r = vgic_reg32_extract(itargetsr, info);
-
- return 1;
- }
-
case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
{
uint32_t ipriorityr;
@@ -279,6 +269,27 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
return 1;
}
+ case VREG32(0x7FC):
+ goto read_reserved;
+
+ case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSRN):
+ {
+ uint32_t itargetsr;
+
+ if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
+ rank = vgic_rank_offset(v, 8, gicd_reg - GICD_ITARGETSR, DABT_WORD);
+ if ( rank == NULL) goto read_as_zero;
+ vgic_lock_rank(v, rank, flags);
+ itargetsr = vgic_fetch_itargetsr(rank, gicd_reg - GICD_ITARGETSR);
+ vgic_unlock_rank(v, rank, flags);
+ *r = vgic_reg32_extract(itargetsr, info);
+
+ return 1;
+ }
+
+ case VREG32(0xBFC):
+ goto read_reserved;
+
case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
{
uint32_t icfgr;
@@ -295,6 +306,9 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
return 1;
}
+ case VRANGE32(0xD00, 0xDFC):
+ goto read_impl_defined;
+
case VRANGE32(GICD_NSACR, GICD_NSACRN):
/* We do not implement security extensions for guests, read zero */
goto read_as_zero_32;
@@ -305,32 +319,27 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
*r = 0xdeadbeef;
return 1;
+ case VRANGE32(0xF04, 0xF0C):
+ goto read_reserved;
+
/* Setting/Clearing the SGI pending bit via GICD is not supported */
case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
goto read_as_zero;
- /* Implementation defined -- read as zero */
- case 0xfd0 ... 0xfe4:
- goto read_as_zero;
+ case VRANGE32(0xF30, 0xFCC):
+ goto read_reserved;
+
+ case VRANGE32(0xFD0, 0xFE4):
+ goto read_impl_defined;
case VREG32(GICD_ICPIDR2):
if ( dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR "%pv: vGICD: unhandled read from ICPIDR2\n", v);
return 0;
- /* Implementation defined -- read as zero */
- case 0xfec ... 0xffc:
- goto read_as_zero;
-
- /* Reserved -- read as zero */
- case 0x00c ... 0x01c:
- case 0x040 ... 0x07c:
- case 0x7fc:
- case 0xbfc:
- case 0xf04 ... 0xf0c:
- case 0xf30 ... 0xfcc:
- goto read_as_zero;
+ case VRANGE32(0xFEC, 0xFFC):
+ goto read_impl_defined;
default:
printk(XENLOG_G_ERR "%pv: vGICD: unhandled read r%d offset %#08x\n",
@@ -349,6 +358,20 @@ read_as_zero_32:
read_as_zero:
*r = 0;
return 1;
+
+read_impl_defined:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICD: RAZ on implemention defined register offset %#08x\n",
+ v, gicd_reg);
+ *r = 0;
+ return 1;
+
+read_reserved:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICD: RAZ on reserved register offset %#08x\n",
+ v, gicd_reg);
+ *r = 0;
+ return 1;
}
static int vgic_v2_to_sgi(struct vcpu *v, register_t sgir)
@@ -414,9 +437,14 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
case VREG32(GICD_IIDR):
goto write_ignore_32;
- /* Implementation defined -- write ignored */
- case 0x020 ... 0x03c:
- goto write_ignore;
+ case VRANGE32(0x00C, 0x01C):
+ goto write_reserved;
+
+ case VRANGE32(0x020, 0x03C):
+ goto write_impl_defined;
+
+ case VRANGE32(0x040, 0x07C):
+ goto write_reserved;
case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
/* We do not implement security extensions for guests, write ignore */
@@ -472,6 +500,25 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
v, r, gicd_reg - GICD_ICACTIVER);
return 0;
+ case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
+ {
+ uint32_t *ipriorityr;
+
+ if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
+ rank = vgic_rank_offset(v, 8, gicd_reg - GICD_IPRIORITYR, DABT_WORD);
+ if ( rank == NULL) goto write_ignore;
+ vgic_lock_rank(v, rank, flags);
+ ipriorityr = &rank->ipriorityr[REG_RANK_INDEX(8,
+ gicd_reg - GICD_IPRIORITYR,
+ DABT_WORD)];
+ vgic_reg32_update(ipriorityr, r, info);
+ vgic_unlock_rank(v, rank, flags);
+ return 1;
+ }
+
+ case VREG32(0x7FC):
+ goto write_reserved;
+
case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSR7):
/* SGI/PPI target is read only */
goto write_ignore_32;
@@ -492,21 +539,8 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
- {
- uint32_t *ipriorityr;
-
- if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
- rank = vgic_rank_offset(v, 8, gicd_reg - GICD_IPRIORITYR, DABT_WORD);
- if ( rank == NULL) goto write_ignore;
- vgic_lock_rank(v, rank, flags);
- ipriorityr = &rank->ipriorityr[REG_RANK_INDEX(8,
- gicd_reg - GICD_IPRIORITYR,
- DABT_WORD)];
- vgic_reg32_update(ipriorityr, r, info);
- vgic_unlock_rank(v, rank, flags);
- return 1;
- }
+ case VREG32(0xBFC):
+ goto write_reserved;
case VREG32(GICD_ICFGR): /* SGIs */
goto write_ignore_32;
@@ -526,6 +560,9 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
vgic_unlock_rank(v, rank, flags);
return 1;
+ case VRANGE32(0xD00, 0xDFC):
+ goto write_impl_defined;
+
case VRANGE32(GICD_NSACR, GICD_NSACRN):
/* We do not implement security extensions for guests, write ignore */
goto write_ignore_32;
@@ -534,6 +571,9 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
if ( dabt.size != DABT_WORD ) goto bad_width;
return vgic_v2_to_sgi(v, r);
+ case VRANGE32(0xF04, 0xF0C):
+ goto write_reserved;
+
case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
printk(XENLOG_G_ERR
@@ -548,26 +588,19 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
v, dabt.size ? "word" : "byte", r, gicd_reg - GICD_SPENDSGIR);
return 0;
- /* Implementation defined -- write ignored */
- case 0xfd0 ... 0xfe4:
- goto write_ignore;
+ case VRANGE32(0xF30, 0xFCC):
+ goto write_reserved;
+
+ case VRANGE32(0xFD0, 0xFE4):
+ /* Implementation defined identification registers */
+ goto write_impl_defined;
/* R/O -- write ignore */
case VREG32(GICD_ICPIDR2):
goto write_ignore_32;
- /* Implementation defined -- write ignored */
- case 0xfec ... 0xffc:
- goto write_ignore;
-
- /* Reserved -- write ignored */
- case 0x00c ... 0x01c:
- case 0x040 ... 0x07c:
- case 0x7fc:
- case 0xbfc:
- case 0xf04 ... 0xf0c:
- case 0xf30 ... 0xfcc:
- goto write_ignore;
+ case VRANGE32(0xFEC, 0xFFC):
+ /* Implementation defined identification registers */
default:
printk(XENLOG_G_ERR
@@ -587,6 +620,18 @@ write_ignore_32:
if ( dabt.size != DABT_WORD ) goto bad_width;
write_ignore:
return 1;
+
+write_impl_defined:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICD: WI on implementation defined register offset %#08x\n",
+ v, gicd_reg);
+ return 1;
+
+write_reserved:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICD: WI on implementation defined register offset %#08x\n",
+ v, gicd_reg);
+ return 1;
}
static const struct mmio_handler_ops vgic_v2_distr_mmio_handler = {
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 28f075a..f9d8ecb 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -210,6 +210,12 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
/* Power management is not implemented */
goto read_as_zero_32;
+ case 0x0018:
+ goto read_reserved;
+
+ case 0x0020:
+ goto read_impl_defined;
+
case VREG64(GICR_SETLPIR):
/* WO. Read as zero */
goto read_as_zero_64;
@@ -218,6 +224,9 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
/* WO. Read as zero */
goto read_as_zero_64;
+ case 0x0050:
+ goto read_reserved;
+
case VREG64(GICR_PROPBASER):
/* LPI's not implemented */
goto read_as_zero_64;
@@ -226,27 +235,48 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
/* LPI's not implemented */
goto read_as_zero_64;
+ case 0x0080:
+ goto read_reserved;
+
case VREG64(GICR_INVLPIR):
/* WO. Read as zero */
goto read_as_zero_64;
+ case 0x00A8:
+ goto read_reserved;
+
case VREG64(GICR_INVALLR):
/* WO. Read as zero */
goto read_as_zero_64;
return 0;
+ case 0x00B8:
+ goto read_reserved;
+
case VREG32(GICR_SYNCR):
if ( dabt.size != DABT_WORD ) goto bad_width;
/* RO . But when read it always returns busy bito bit[0] */
*r = vgic_reg32_extract(GICR_SYNCR_NOT_BUSY, info);
return 1;
+ case 0x00C8:
+ goto read_reserved;
+
case VREG64(0x0100):
goto read_impl_defined;
+ case 0x0108:
+ goto read_reserved;
+
case VREG64(0x0110):
goto read_impl_defined;
+ case 0x0118 ... 0xBFFC:
+ goto read_reserved;
+
+ case 0xC000 ... 0xFFCC:
+ goto read_impl_defined;
+
case 0xFFD0 ... 0xFFE4:
/* Implementation defined identification registers */
goto read_impl_defined;
@@ -284,7 +314,14 @@ read_as_zero_32:
read_impl_defined:
printk(XENLOG_G_DEBUG
- "%pv: vGICR: RAZ on implemention defined register offset %#08x\n",
+ "%pv: vGICR: RAZ on implementation defined register offset %#08x\n",
+ v, gicr_reg);
+ *r = 0;
+ return 1;
+
+read_reserved:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICR: RAZ on reserved register offset %#08x\n",
v, gicr_reg);
*r = 0;
return 1;
@@ -318,6 +355,12 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
/* Power mgmt not implemented */
goto write_ignore_32;
+ case 0x0018:
+ goto write_reserved;
+
+ case 0x0020:
+ goto write_impl_defined;
+
case VREG64(GICR_SETLPIR):
/* LPI is not implemented */
goto write_ignore_64;
@@ -326,6 +369,9 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
/* LPI is not implemented */
goto write_ignore_64;
+ case 0x0050:
+ goto write_reserved;
+
case VREG64(GICR_PROPBASER):
/* LPI is not implemented */
goto write_ignore_64;
@@ -334,24 +380,45 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
/* LPI is not implemented */
goto write_ignore_64;
+ case 0x0080:
+ goto write_reserved;
+
case VREG64(GICR_INVLPIR):
/* LPI is not implemented */
goto write_ignore_64;
+ case 0x00A8:
+ goto write_reserved;
+
case VREG64(GICR_INVALLR):
/* LPI is not implemented */
goto write_ignore_64;
+ case 0x00B8:
+ goto write_reserved;
+
case VREG32(GICR_SYNCR):
/* RO */
goto write_ignore_32;
+ case 0x00C8:
+ goto write_reserved;
+
case VREG64(0x0100):
goto write_impl_defined;
+ case 0x0108:
+ goto write_reserved;
+
case VREG64(0x0110):
goto write_impl_defined;
+ case 0x0118 ... 0xBFFC:
+ goto write_reserved;
+
+ case 0xC000 ... 0xFFCC:
+ goto write_impl_defined;
+
case 0xFFD0 ... 0xFFE4:
/* Implementation defined identification registers */
goto write_impl_defined;
@@ -389,6 +456,12 @@ write_impl_defined:
"%pv: vGICR: WI on implementation defined register offset %#08x\n",
v, gicr_reg);
return 1;
+
+write_reserved:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICR: WI on reserved register offset %#08x\n",
+ v, gicr_reg);
+ return 1;
}
static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
@@ -609,10 +682,6 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info,
switch ( gicr_reg )
{
- case VREG32(GICR_IGRPMODR0):
- /* We do not implement security extensions for guests, read zero */
- goto read_as_zero_32;
-
case VREG32(GICR_IGROUPR0):
case VREG32(GICR_ISENABLER0):
case VREG32(GICR_ICENABLER0):
@@ -632,10 +701,23 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info,
case VREG32(GICR_ICPENDR0):
goto read_as_zero;
+ case VREG32(GICR_IGRPMODR0):
+ /* We do not implement security extensions for guests, read zero */
+ goto read_as_zero_32;
+
case VREG32(GICR_NSACR):
/* We do not implement security extensions for guests, read zero */
goto read_as_zero_32;
+ case 0x0E04 ... 0xBFFC:
+ goto read_reserved;
+
+ case 0xC000 ... 0xFFCC:
+ goto read_impl_defined;
+
+ case 0xFFD0 ... 0xFFFC:
+ goto read_reserved;
+
default:
printk(XENLOG_G_ERR
"%pv: vGICR: SGI: unhandled read r%d offset %#08x\n",
@@ -653,6 +735,21 @@ read_as_zero_32:
read_as_zero:
*r = 0;
return 1;
+
+read_impl_defined:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICR: SGI: RAZ on implementation defined register offset %#08x\n",
+ v, gicr_reg);
+ *r = 0;
+ return 1;
+
+read_reserved:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICR: SGI: RAZ on reserved register offset %#08x\n",
+ v, gicr_reg);
+ *r = 0;
+ return 1;
+
}
static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info,
@@ -662,10 +759,6 @@ static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info,
switch ( gicr_reg )
{
- case VREG32(GICR_IGRPMODR0):
- /* We do not implement security extensions for guests, write ignore */
- goto write_ignore_32;
-
case VREG32(GICR_IGROUPR0):
case VREG32(GICR_ISENABLER0):
case VREG32(GICR_ICENABLER0):
@@ -694,6 +787,11 @@ static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info,
v, r);
return 0;
+ case VREG32(GICR_IGRPMODR0):
+ /* We do not implement security extensions for guests, write ignore */
+ goto write_ignore_32;
+
+
case VREG32(GICR_NSACR):
/* We do not implement security extensions for guests, write ignore */
goto write_ignore_32;
@@ -829,6 +927,14 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
return 1;
}
+ case VREG32(GICD_IIDR):
+ if ( dabt.size != DABT_WORD ) goto bad_width;
+ *r = vgic_reg32_extract(GICV3_GICD_IIDR_VAL, info);
+ return 1;
+
+ case VREG32(0x000C):
+ goto read_reserved;
+
case VREG32(GICD_STATUSR):
/*
* Optional, Not implemented for now.
@@ -836,15 +942,23 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
*/
goto read_as_zero_32;
- case VREG32(GICD_IIDR):
- if ( dabt.size != DABT_WORD ) goto bad_width;
- *r = vgic_reg32_extract(GICV3_GICD_IIDR_VAL, info);
- return 1;
+ case VRANGE32(0x0014, 0x001C):
+ goto read_reserved;
- case 0x020 ... 0x03c:
- case 0xc000 ... 0xffcc:
- /* Implementation defined -- read as zero */
- goto read_as_zero_32;
+ case VRANGE32(0x0020, 0x003C):
+ goto read_impl_defined;
+
+ case VREG32(0x0044):
+ goto read_reserved;
+
+ case VREG32(0x004C):
+ goto read_reserved;
+
+ case VREG32(0x0054):
+ goto read_reserved;
+
+ case VRANGE32(0x005C, 0x007C):
+ goto read_reserved;
case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
@@ -860,6 +974,25 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
*/
return __vgic_v3_distr_common_mmio_read("vGICD", v, info, gicd_reg, r);
+ case VRANGE32(GICD_NSACR, GICD_NSACRN):
+ /* We do not implement security extensions for guests, read zero */
+ goto read_as_zero_32;
+
+ case VREG32(GICD_SGIR):
+ /* Read as ICH_SGIR system register with SRE set. So ignore */
+ goto read_as_zero_32;
+
+ case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
+ /* Replaced with GICR_ICPENDR0. So ignore write */
+ goto read_as_zero_32;
+
+ case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
+ /* Replaced with GICR_ISPENDR0. So ignore write */
+ goto read_as_zero_32;
+
+ case VRANGE32(0x0F30, 0x60FC):
+ goto read_reserved;
+
case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
{
uint64_t irouter;
@@ -877,23 +1010,13 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
return 1;
}
- case VRANGE32(GICD_NSACR, GICD_NSACRN):
- /* We do not implement security extensions for guests, read zero */
- goto read_as_zero_32;
+ case VRANGE32(0x7FE0, 0xBFFC):
+ goto read_reserved;
- case VREG32(GICD_SGIR):
- /* Read as ICH_SGIR system register with SRE set. So ignore */
- goto read_as_zero_32;
-
- case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
- /* Replaced with GICR_ICPENDR0. So ignore write */
- goto read_as_zero_32;
-
- case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
- /* Replaced with GICR_ISPENDR0. So ignore write */
- goto read_as_zero_32;
+ case VRANGE32(0xC000, 0xFFCC):
+ goto read_impl_defined;
- case 0xFFD0 ... 0xFFE4:
+ case VRANGE32(0xFFD0, 0xFFE4):
/* Implementation defined identification registers */
goto read_impl_defined;
@@ -903,21 +1026,10 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
*r = vgic_reg32_extract(GICV3_GICD_PIDR2, info);
return 1;
- case 0xFFEC ... 0xFFFC:
+ case VRANGE32(0xFFEC, 0xFFFC):
/* Implementation defined identification registers */
goto read_impl_defined;
- case 0x00c:
- case 0x044:
- case 0x04c:
- case 0x05c ... 0x07c:
- case 0xf30 ... 0x5fcc:
- case 0x8000 ... 0xbfcc:
- /* These are reserved register addresses */
- printk(XENLOG_G_DEBUG
- "%pv: vGICD: RAZ on reserved register offset %#08x\n",
- v, gicd_reg);
- goto read_as_zero;
default:
printk(XENLOG_G_ERR "%pv: vGICD: unhandled read r%d offset %#08x\n",
v, dabt.reg, gicd_reg);
@@ -941,7 +1053,14 @@ read_as_zero:
read_impl_defined:
printk(XENLOG_G_DEBUG
- "%pv: vGICD: RAZ on implemention defined register offset %#08x\n",
+ "%pv: vGICD: RAZ on implementation defined register offset %#08x\n",
+ v, gicd_reg);
+ *r = 0;
+ return 1;
+
+read_reserved:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICD: RAZ on reserved register offset %#08x\n",
v, gicd_reg);
*r = 0;
return 1;
@@ -987,33 +1106,46 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
/* RO -- write ignored */
goto write_ignore_32;
+ case VREG32(0x000C):
+ goto write_reserved;
+
case VREG32(GICD_STATUSR):
/* RO -- write ignored */
goto write_ignore_32;
+ case VRANGE32(0x0014, 0x001C):
+ goto write_reserved;
+
+ case VRANGE32(0x0020, 0x003C):
+ goto write_impl_defined;
+
case VREG32(GICD_SETSPI_NSR):
/* Message based SPI is not implemented */
goto write_ignore_32;
+ case VREG32(0x0044):
+ goto write_reserved;
+
case VREG32(GICD_CLRSPI_NSR):
/* Message based SPI is not implemented */
goto write_ignore_32;
+ case VREG32(0x004C):
+ goto write_reserved;
+
case VREG32(GICD_SETSPI_SR):
/* Message based SPI is not implemented */
goto write_ignore_32;
+ case VREG32(0x0054):
+ goto write_reserved;
+
case VREG32(GICD_CLRSPI_SR):
/* Message based SPI is not implemented */
goto write_ignore_32;
- case 0x020 ... 0x03c:
- case 0xc000 ... 0xffcc:
- /* Implementation defined -- write ignored */
- printk(XENLOG_G_DEBUG
- "%pv: vGICD: WI on implementation defined register offset %#08x\n",
- v, gicd_reg);
- goto write_ignore_32;
+ case VRANGE32(0x005C, 0x007C):
+ goto write_reserved;
case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
@@ -1029,22 +1161,6 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
return __vgic_v3_distr_common_mmio_write("vGICD", v, info,
gicd_reg, r);
- case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
- {
- uint64_t irouter;
-
- if ( !vgic_reg64_check_access(dabt) ) goto bad_width;
- rank = vgic_rank_offset(v, 64, gicd_reg - GICD_IROUTER,
- DABT_DOUBLE_WORD);
- if ( rank == NULL ) goto write_ignore;
- vgic_lock_rank(v, rank, flags);
- irouter = vgic_fetch_irouter(rank, gicd_reg - GICD_IROUTER);
- vgic_reg64_update(&irouter, r, info);
- vgic_store_irouter(v->domain, rank, gicd_reg - GICD_IROUTER, irouter);
- vgic_unlock_rank(v, rank, flags);
- return 1;
- }
-
case VRANGE32(GICD_NSACR, GICD_NSACRN):
/* We do not implement security extensions for guests, write ignore */
goto write_ignore_32;
@@ -1063,7 +1179,32 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
if ( dabt.size != DABT_WORD ) goto bad_width;
return 0;
- case 0xFFD0 ... 0xFFE4:
+ case VRANGE32(0x0F30, 0x60FC):
+ goto write_reserved;
+
+ case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
+ {
+ uint64_t irouter;
+
+ if ( !vgic_reg64_check_access(dabt) ) goto bad_width;
+ rank = vgic_rank_offset(v, 64, gicd_reg - GICD_IROUTER,
+ DABT_DOUBLE_WORD);
+ if ( rank == NULL ) goto write_ignore;
+ vgic_lock_rank(v, rank, flags);
+ irouter = vgic_fetch_irouter(rank, gicd_reg - GICD_IROUTER);
+ vgic_reg64_update(&irouter, r, info);
+ vgic_store_irouter(v->domain, rank, gicd_reg - GICD_IROUTER, irouter);
+ vgic_unlock_rank(v, rank, flags);
+ return 1;
+ }
+
+ case VRANGE32(0x7FE0, 0xBFFC):
+ goto write_reserved;
+
+ case VRANGE32(0xC000, 0xFFCC):
+ goto write_impl_defined;
+
+ case VRANGE32(0xFFD0, 0xFFE4):
/* Implementation defined identification registers */
goto write_impl_defined;
@@ -1071,21 +1212,10 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
/* RO -- write ignore */
goto write_ignore_32;
- case 0xFFEC ... 0xFFFC:
+ case VRANGE32(0xFFEC, 0xFFFC):
/* Implementation defined identification registers */
goto write_impl_defined;
- case 0x00c:
- case 0x044:
- case 0x04c:
- case 0x05c ... 0x07c:
- case 0xf30 ... 0x5fcc:
- case 0x8000 ... 0xbfcc:
- /* Reserved register addresses */
- printk(XENLOG_G_DEBUG
- "%pv: vGICD: write unknown 0x00c 0xfcc r%d offset %#08x\n",
- v, dabt.reg, gicd_reg);
- goto write_ignore;
default:
printk(XENLOG_G_ERR
"%pv: vGICD: unhandled write r%d=%"PRIregister" offset %#08x\n",
@@ -1112,6 +1242,12 @@ write_impl_defined:
"%pv: vGICD: WI on implementation defined register offset %#08x\n",
v, gicd_reg);
return 1;
+
+write_reserved:
+ printk(XENLOG_G_DEBUG
+ "%pv: vGICD: WI on reserved register offset %#08x\n",
+ v, gicd_reg);
+ return 1;
}
static int vgic_v3_to_sgi(struct vcpu *v, register_t sgir)
--
2.1.4
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v2 08/11] xen/arm: vgic-v3: Emulate read to GICD_ICACTIVER<n>
2015-11-18 17:27 [PATCH v2 00/11] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
` (6 preceding siblings ...)
2015-11-18 17:28 ` [PATCH v2 07/11] xen/arm: vgic: Re-order the register emulations to match the memory map Julien Grall
@ 2015-11-18 17:28 ` Julien Grall
2015-11-18 17:28 ` [PATCH v2 09/11] xen/arm: vgic-v3: Remove spurious return in GICR_INVALLR Julien Grall
` (2 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Julien Grall @ 2015-11-18 17:28 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
The GICD_ICACTIVER<n> registers are missing in the read emulation of the
distributor.
Call the common emulation for the whole range.
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
Changes in v2:
- Add Ian's acked-by
---
xen/arch/arm/vgic-v3.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index f9d8ecb..98104ba 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -966,6 +966,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN):
+ case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
/*
--
2.1.4
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v2 09/11] xen/arm: vgic-v3: Remove spurious return in GICR_INVALLR
2015-11-18 17:27 [PATCH v2 00/11] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
` (7 preceding siblings ...)
2015-11-18 17:28 ` [PATCH v2 08/11] xen/arm: vgic-v3: Emulate read to GICD_ICACTIVER<n> Julien Grall
@ 2015-11-18 17:28 ` Julien Grall
2015-11-18 17:28 ` [PATCH v2 10/11] xen/arm: vgic-v3: Don't implement write-only register read as zero Julien Grall
2015-11-18 17:28 ` [PATCH v2 11/11] xen/arm: vgic-v3: Make clear that GICD_*SPI_* registers are reserved Julien Grall
10 siblings, 0 replies; 24+ messages in thread
From: Julien Grall @ 2015-11-18 17:28 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
Changes in v2:
- Add Ian's acked-by
---
xen/arch/arm/vgic-v3.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 98104ba..c68afdb 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -248,7 +248,6 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
case VREG64(GICR_INVALLR):
/* WO. Read as zero */
goto read_as_zero_64;
- return 0;
case 0x00B8:
goto read_reserved;
--
2.1.4
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v2 10/11] xen/arm: vgic-v3: Don't implement write-only register read as zero
2015-11-18 17:27 [PATCH v2 00/11] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
` (8 preceding siblings ...)
2015-11-18 17:28 ` [PATCH v2 09/11] xen/arm: vgic-v3: Remove spurious return in GICR_INVALLR Julien Grall
@ 2015-11-18 17:28 ` Julien Grall
2015-11-18 17:28 ` [PATCH v2 11/11] xen/arm: vgic-v3: Make clear that GICD_*SPI_* registers are reserved Julien Grall
10 siblings, 0 replies; 24+ messages in thread
From: Julien Grall @ 2015-11-18 17:28 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
A read to a write only register is unknown. Use a memorable value to
differentiate from an actual RAZ register.
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
Changes in v2:
- Add Ian's acked-by
---
xen/arch/arm/vgic-v3.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index c68afdb..44e926a 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -217,12 +217,12 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
goto read_impl_defined;
case VREG64(GICR_SETLPIR):
- /* WO. Read as zero */
- goto read_as_zero_64;
+ /* WO. Read unknown */
+ goto read_unknown;
case VREG64(GICR_CLRLPIR):
- /* WO. Read as zero */
- goto read_as_zero_64;
+ /* WO. Read unknown */
+ goto read_unknown;
case 0x0050:
goto read_reserved;
@@ -239,15 +239,15 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
goto read_reserved;
case VREG64(GICR_INVLPIR):
- /* WO. Read as zero */
- goto read_as_zero_64;
+ /* WO. Read unknown */
+ goto read_unknown;
case 0x00A8:
goto read_reserved;
case VREG64(GICR_INVALLR):
- /* WO. Read as zero */
- goto read_as_zero_64;
+ /* WO. Read unknown */
+ goto read_unknown;
case 0x00B8:
goto read_reserved;
@@ -324,6 +324,10 @@ read_reserved:
v, gicr_reg);
*r = 0;
return 1;
+
+read_unknown:
+ *r = vgic_reg64_extract(0xdeadbeafdeadbeaf, info);
+ return 1;
}
static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
--
2.1.4
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v2 11/11] xen/arm: vgic-v3: Make clear that GICD_*SPI_* registers are reserved
2015-11-18 17:27 [PATCH v2 00/11] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
` (9 preceding siblings ...)
2015-11-18 17:28 ` [PATCH v2 10/11] xen/arm: vgic-v3: Don't implement write-only register read as zero Julien Grall
@ 2015-11-18 17:28 ` Julien Grall
10 siblings, 0 replies; 24+ messages in thread
From: Julien Grall @ 2015-11-18 17:28 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
Our vGIC emulation have GICD_TYPER.MBIS set to 0 which means that
GICD_*SPI_* registers are reserved. Implement them using the *_reserved
labels.
Also, implement theses registers for the read part.
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
Changes in v2:
- Add Ian's acked-by
- Fix typoes
---
xen/arch/arm/vgic-v3.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 44e926a..985e866 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -951,15 +951,31 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
case VRANGE32(0x0020, 0x003C):
goto read_impl_defined;
+ case VREG32(GICD_SETSPI_NSR):
+ /* Message based SPI is not implemented */
+ goto read_reserved;
+
case VREG32(0x0044):
goto read_reserved;
+ case VREG32(GICD_CLRSPI_NSR):
+ /* Message based SPI is not implemented */
+ goto read_reserved;
+
case VREG32(0x004C):
goto read_reserved;
+ case VREG32(GICD_SETSPI_SR):
+ /* Message based SPI is not implemented */
+ goto read_reserved;
+
case VREG32(0x0054):
goto read_reserved;
+ case VREG32(GICD_CLRSPI_SR):
+ /* Message based SPI is not implemented */
+ goto read_reserved;
+
case VRANGE32(0x005C, 0x007C):
goto read_reserved;
@@ -1125,28 +1141,28 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
case VREG32(GICD_SETSPI_NSR):
/* Message based SPI is not implemented */
- goto write_ignore_32;
+ goto write_reserved;
case VREG32(0x0044):
goto write_reserved;
case VREG32(GICD_CLRSPI_NSR):
/* Message based SPI is not implemented */
- goto write_ignore_32;
+ goto write_reserved;
case VREG32(0x004C):
goto write_reserved;
case VREG32(GICD_SETSPI_SR):
/* Message based SPI is not implemented */
- goto write_ignore_32;
+ goto write_reserved;
case VREG32(0x0054):
goto write_reserved;
case VREG32(GICD_CLRSPI_SR):
/* Message based SPI is not implemented */
- goto write_ignore_32;
+ goto write_reserved;
case VRANGE32(0x005C, 0x007C):
goto write_reserved;
--
2.1.4
^ permalink raw reply related [flat|nested] 24+ messages in thread