Browse Source

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@huawei.com>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Andre Przywara 11 years ago
parent
commit
f2ae85b2ab
1 changed files with 4 additions and 5 deletions
  1. 4 5
      virt/kvm/arm/vgic.c

+ 4 - 5
virt/kvm/arm/vgic.c

@@ -548,11 +548,10 @@ static bool handle_mmio_cfg_reg(struct kvm_vcpu *vcpu,
 	u32 val;
 	u32 val;
 	u32 *reg;
 	u32 *reg;
 
 
-	offset >>= 1;
 	reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_cfg,
 	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;
 		val = *reg >> 16;
 	else
 	else
 		val = *reg & 0xffff;
 		val = *reg & 0xffff;
@@ -561,13 +560,13 @@ static bool handle_mmio_cfg_reg(struct kvm_vcpu *vcpu,
 	vgic_reg_access(mmio, &val, offset,
 	vgic_reg_access(mmio, &val, offset,
 			ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
 			ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
 	if (mmio->is_write) {
 	if (mmio->is_write) {
-		if (offset < 4) {
+		if (offset < 8) {
 			*reg = ~0U; /* Force PPIs/SGIs to 1 */
 			*reg = ~0U; /* Force PPIs/SGIs to 1 */
 			return false;
 			return false;
 		}
 		}
 
 
 		val = vgic_cfg_compress(val);
 		val = vgic_cfg_compress(val);
-		if (offset & 2) {
+		if (offset & 4) {
 			*reg &= 0xffff;
 			*reg &= 0xffff;
 			*reg |= val << 16;
 			*reg |= val << 16;
 		} else {
 		} else {