Re: [PATCH] KVM: ARM: vgic: Fix the accessing GICD_ICFGRn register problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> From: Haibin Wang <wanghaibin.wang@xxxxxxxxxx>
> 
> It needs to use the bitmap to save the GICD_ICFGRn value
> (the real hardware register need two bits pre irq), Here
> before access this cfg bitmap, we did "offset >>= 1;". Later,
> it use the vgic_cfg_expand function to expend these bits.
> 
> But, It's incorrect to pass offset parameter to vgic_reg_access,
> it should pass "offset << 1".

Good catch, but I think the patch is wrong:
1) If you write above (and mean) "shift left", you should do so in
   the patch, too ;-)

> -	vgic_reg_access(mmio, &val, offset,
> +	vgic_reg_access(mmio, &val, offset >> 1,

2) We should not drop the LSB of offset, otherwise byte accesses to
   uneven addresses will be wrong (think of ldrb r0, [r1, #5])

So I propose the below patch instead.

Cheers,
Andre.

----------------
KVM: arm/arm64: vgic: fix GICD_ICFGR register accesses

Since KVM internally represents the ICFGR registers by stuffing two
of them into one word, the offset for accessing the internal
representation and the one for the MMIO based access are different.
So keep the original offset around, but adjust the internal array
offset by one bit.

Reported-by: Haibin Wang <wanghaibin.wang@xxxxxxxxxx>
Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx>
---
 virt/kvm/arm/vgic.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 8ca405c..2c71535 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -548,11 +548,10 @@ static bool handle_mmio_cfg_reg(struct kvm_vcpu *vcpu,
 	u32 val;
 	u32 *reg;
 
-	offset >>= 1;
 	reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_cfg,
-				  vcpu->vcpu_id, offset);
+				  vcpu->vcpu_id, offset >> 1);
 
-	if (offset & 2)
+	if (offset & 4)
 		val = *reg >> 16;
 	else
 		val = *reg & 0xffff;
@@ -561,13 +560,13 @@ static bool handle_mmio_cfg_reg(struct kvm_vcpu *vcpu,
 	vgic_reg_access(mmio, &val, offset,
 			ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
 	if (mmio->is_write) {
-		if (offset < 4) {
+		if (offset < 8) {
 			*reg = ~0U; /* Force PPIs/SGIs to 1 */
 			return false;
 		}
 
 		val = vgic_cfg_compress(val);
-		if (offset & 2) {
+		if (offset & 4) {
 			*reg &= 0xffff;
 			*reg |= val << 16;
 		} else {
-- 
1.8.4

_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm




[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux