diff options
author | Andre Przywara <andre.przywara@arm.com> | 2014-04-10 18:07:18 -0400 |
---|---|---|
committer | Christoffer Dall <christoffer.dall@linaro.org> | 2014-04-28 07:06:22 -0400 |
commit | f2ae85b2ab3776b9e4e42e5b6fa090f40d396794 (patch) | |
tree | 0e50e7efae91b482d97a87da377896a3b7917c78 /virt/kvm/arm/vgic.c | |
parent | 91021a6c8ffdc55804dab5acdfc7de4f278b9ac3 (diff) |
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>
Diffstat (limited to 'virt/kvm/arm/vgic.c')
-rw-r--r-- | virt/kvm/arm/vgic.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 7e8b44efb739..f9af48c9eb37 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, | |||
548 | u32 val; | 548 | u32 val; |
549 | u32 *reg; | 549 | u32 *reg; |
550 | 550 | ||
551 | offset >>= 1; | ||
552 | reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_cfg, | 551 | reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_cfg, |
553 | vcpu->vcpu_id, offset); | 552 | vcpu->vcpu_id, offset >> 1); |
554 | 553 | ||
555 | if (offset & 2) | 554 | if (offset & 4) |
556 | val = *reg >> 16; | 555 | val = *reg >> 16; |
557 | else | 556 | else |
558 | val = *reg & 0xffff; | 557 | val = *reg & 0xffff; |
@@ -561,13 +560,13 @@ static bool handle_mmio_cfg_reg(struct kvm_vcpu *vcpu, | |||
561 | vgic_reg_access(mmio, &val, offset, | 560 | vgic_reg_access(mmio, &val, offset, |
562 | ACCESS_READ_VALUE | ACCESS_WRITE_VALUE); | 561 | ACCESS_READ_VALUE | ACCESS_WRITE_VALUE); |
563 | if (mmio->is_write) { | 562 | if (mmio->is_write) { |
564 | if (offset < 4) { | 563 | if (offset < 8) { |
565 | *reg = ~0U; /* Force PPIs/SGIs to 1 */ | 564 | *reg = ~0U; /* Force PPIs/SGIs to 1 */ |
566 | return false; | 565 | return false; |
567 | } | 566 | } |
568 | 567 | ||
569 | val = vgic_cfg_compress(val); | 568 | val = vgic_cfg_compress(val); |
570 | if (offset & 2) { | 569 | if (offset & 4) { |
571 | *reg &= 0xffff; | 570 | *reg &= 0xffff; |
572 | *reg |= val << 16; | 571 | *reg |= val << 16; |
573 | } else { | 572 | } else { |