diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2014-09-27 05:03:33 -0400 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-09-27 05:03:33 -0400 |
| commit | e77d99d4a4ec761ad061f1ec890c71040a92efe3 (patch) | |
| tree | aea6fe2ee5bb6e699045a3629b48208f3e2a26b6 /virt | |
| parent | bb0ca6acd466af55c95b7ce508f29e23a24cabd9 (diff) | |
| parent | 0496daa5cf99741ce8db82686b4c7446a37feabb (diff) | |
Merge tag 'kvm-arm-for-3.18' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into kvm-next
Changes for KVM for arm/arm64 for 3.18
This includes a bunch of changes:
- Support read-only memory slots on arm/arm64
- Various changes to fix Sparse warnings
- Correctly detect write vs. read Stage-2 faults
- Various VGIC cleanups and fixes
- Dynamic VGIC data strcuture sizing
- Fix SGI set_clear_pend offset bug
- Fix VTTBR_BADDR Mask
- Correctly report the FSC on Stage-2 faults
Conflicts:
virt/kvm/eventfd.c
[duplicate, different patch where the kvm-arm version broke x86.
The kvm tree instead has the right one]
Diffstat (limited to 'virt')
| -rw-r--r-- | virt/kvm/arm/vgic.c | 631 | ||||
| -rw-r--r-- | virt/kvm/kvm_main.c | 11 |
2 files changed, 520 insertions, 122 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 3ee3ce06bbec..862967852d5a 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c | |||
| @@ -36,21 +36,22 @@ | |||
| 36 | * How the whole thing works (courtesy of Christoffer Dall): | 36 | * How the whole thing works (courtesy of Christoffer Dall): |
| 37 | * | 37 | * |
| 38 | * - At any time, the dist->irq_pending_on_cpu is the oracle that knows if | 38 | * - At any time, the dist->irq_pending_on_cpu is the oracle that knows if |
| 39 | * something is pending | 39 | * something is pending on the CPU interface. |
| 40 | * - VGIC pending interrupts are stored on the vgic.irq_state vgic | 40 | * - Interrupts that are pending on the distributor are stored on the |
| 41 | * bitmap (this bitmap is updated by both user land ioctls and guest | 41 | * vgic.irq_pending vgic bitmap (this bitmap is updated by both user land |
| 42 | * mmio ops, and other in-kernel peripherals such as the | 42 | * ioctls and guest mmio ops, and other in-kernel peripherals such as the |
| 43 | * arch. timers) and indicate the 'wire' state. | 43 | * arch. timers). |
| 44 | * - Every time the bitmap changes, the irq_pending_on_cpu oracle is | 44 | * - Every time the bitmap changes, the irq_pending_on_cpu oracle is |
| 45 | * recalculated | 45 | * recalculated |
| 46 | * - To calculate the oracle, we need info for each cpu from | 46 | * - To calculate the oracle, we need info for each cpu from |
| 47 | * compute_pending_for_cpu, which considers: | 47 | * compute_pending_for_cpu, which considers: |
| 48 | * - PPI: dist->irq_state & dist->irq_enable | 48 | * - PPI: dist->irq_pending & dist->irq_enable |
| 49 | * - SPI: dist->irq_state & dist->irq_enable & dist->irq_spi_target | 49 | * - SPI: dist->irq_pending & dist->irq_enable & dist->irq_spi_target |
| 50 | * - irq_spi_target is a 'formatted' version of the GICD_ICFGR | 50 | * - irq_spi_target is a 'formatted' version of the GICD_ITARGETSRn |
| 51 | * registers, stored on each vcpu. We only keep one bit of | 51 | * registers, stored on each vcpu. We only keep one bit of |
| 52 | * information per interrupt, making sure that only one vcpu can | 52 | * information per interrupt, making sure that only one vcpu can |
| 53 | * accept the interrupt. | 53 | * accept the interrupt. |
| 54 | * - If any of the above state changes, we must recalculate the oracle. | ||
| 54 | * - The same is true when injecting an interrupt, except that we only | 55 | * - The same is true when injecting an interrupt, except that we only |
| 55 | * consider a single interrupt at a time. The irq_spi_cpu array | 56 | * consider a single interrupt at a time. The irq_spi_cpu array |
| 56 | * contains the target CPU for each SPI. | 57 | * contains the target CPU for each SPI. |
| @@ -60,13 +61,18 @@ | |||
| 60 | * the 'line' again. This is achieved as such: | 61 | * the 'line' again. This is achieved as such: |
| 61 | * | 62 | * |
| 62 | * - When a level interrupt is moved onto a vcpu, the corresponding | 63 | * - When a level interrupt is moved onto a vcpu, the corresponding |
| 63 | * bit in irq_active is set. As long as this bit is set, the line | 64 | * bit in irq_queued is set. As long as this bit is set, the line |
| 64 | * will be ignored for further interrupts. The interrupt is injected | 65 | * will be ignored for further interrupts. The interrupt is injected |
| 65 | * into the vcpu with the GICH_LR_EOI bit set (generate a | 66 | * into the vcpu with the GICH_LR_EOI bit set (generate a |
| 66 | * maintenance interrupt on EOI). | 67 | * maintenance interrupt on EOI). |
| 67 | * - When the interrupt is EOIed, the maintenance interrupt fires, | 68 | * - When the interrupt is EOIed, the maintenance interrupt fires, |
| 68 | * and clears the corresponding bit in irq_active. This allow the | 69 | * and clears the corresponding bit in irq_queued. This allows the |
| 69 | * interrupt line to be sampled again. | 70 | * interrupt line to be sampled again. |
| 71 | * - Note that level-triggered interrupts can also be set to pending from | ||
| 72 | * writes to GICD_ISPENDRn and lowering the external input line does not | ||
| 73 | * cause the interrupt to become inactive in such a situation. | ||
| 74 | * Conversely, writes to GICD_ICPENDRn do not cause the interrupt to become | ||
| 75 | * inactive as long as the external input line is held high. | ||
| 70 | */ | 76 | */ |
| 71 | 77 | ||
| 72 | #define VGIC_ADDR_UNDEF (-1) | 78 | #define VGIC_ADDR_UNDEF (-1) |
| @@ -89,6 +95,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); | |||
| 89 | static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu); | 95 | static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu); |
| 90 | static void vgic_update_state(struct kvm *kvm); | 96 | static void vgic_update_state(struct kvm *kvm); |
| 91 | static void vgic_kick_vcpus(struct kvm *kvm); | 97 | static void vgic_kick_vcpus(struct kvm *kvm); |
| 98 | static u8 *vgic_get_sgi_sources(struct vgic_dist *dist, int vcpu_id, int sgi); | ||
| 92 | static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg); | 99 | static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg); |
| 93 | static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr); | 100 | static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr); |
| 94 | static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc); | 101 | static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc); |
| @@ -99,10 +106,8 @@ static const struct vgic_ops *vgic_ops; | |||
| 99 | static const struct vgic_params *vgic; | 106 | static const struct vgic_params *vgic; |
| 100 | 107 | ||
| 101 | /* | 108 | /* |
| 102 | * struct vgic_bitmap contains unions that provide two views of | 109 | * struct vgic_bitmap contains a bitmap made of unsigned longs, but |
| 103 | * the same data. In one case it is an array of registers of | 110 | * extracts u32s out of them. |
| 104 | * u32's, and in the other case it is a bitmap of unsigned | ||
| 105 | * longs. | ||
| 106 | * | 111 | * |
| 107 | * This does not work on 64-bit BE systems, because the bitmap access | 112 | * This does not work on 64-bit BE systems, because the bitmap access |
| 108 | * will store two consecutive 32-bit words with the higher-addressed | 113 | * will store two consecutive 32-bit words with the higher-addressed |
| @@ -118,23 +123,45 @@ static const struct vgic_params *vgic; | |||
| 118 | #define REG_OFFSET_SWIZZLE 0 | 123 | #define REG_OFFSET_SWIZZLE 0 |
| 119 | #endif | 124 | #endif |
| 120 | 125 | ||
| 126 | static int vgic_init_bitmap(struct vgic_bitmap *b, int nr_cpus, int nr_irqs) | ||
| 127 | { | ||
| 128 | int nr_longs; | ||
| 129 | |||
| 130 | nr_longs = nr_cpus + BITS_TO_LONGS(nr_irqs - VGIC_NR_PRIVATE_IRQS); | ||
| 131 | |||
| 132 | b->private = kzalloc(sizeof(unsigned long) * nr_longs, GFP_KERNEL); | ||
| 133 | if (!b->private) | ||
| 134 | return -ENOMEM; | ||
| 135 | |||
| 136 | b->shared = b->private + nr_cpus; | ||
| 137 | |||
| 138 | return 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | static void vgic_free_bitmap(struct vgic_bitmap *b) | ||
| 142 | { | ||
| 143 | kfree(b->private); | ||
| 144 | b->private = NULL; | ||
| 145 | b->shared = NULL; | ||
| 146 | } | ||
| 147 | |||
| 121 | static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, | 148 | static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, |
| 122 | int cpuid, u32 offset) | 149 | int cpuid, u32 offset) |
| 123 | { | 150 | { |
| 124 | offset >>= 2; | 151 | offset >>= 2; |
| 125 | if (!offset) | 152 | if (!offset) |
| 126 | return x->percpu[cpuid].reg + (offset ^ REG_OFFSET_SWIZZLE); | 153 | return (u32 *)(x->private + cpuid) + REG_OFFSET_SWIZZLE; |
| 127 | else | 154 | else |
| 128 | return x->shared.reg + ((offset - 1) ^ REG_OFFSET_SWIZZLE); | 155 | return (u32 *)(x->shared) + ((offset - 1) ^ REG_OFFSET_SWIZZLE); |
| 129 | } | 156 | } |
| 130 | 157 | ||
| 131 | static int vgic_bitmap_get_irq_val(struct vgic_bitmap *x, | 158 | static int vgic_bitmap_get_irq_val(struct vgic_bitmap *x, |
| 132 | int cpuid, int irq) | 159 | int cpuid, int irq) |
| 133 | { | 160 | { |
| 134 | if (irq < VGIC_NR_PRIVATE_IRQS) | 161 | if (irq < VGIC_NR_PRIVATE_IRQS) |
| 135 | return test_bit(irq, x->percpu[cpuid].reg_ul); | 162 | return test_bit(irq, x->private + cpuid); |
| 136 | 163 | ||
| 137 | return test_bit(irq - VGIC_NR_PRIVATE_IRQS, x->shared.reg_ul); | 164 | return test_bit(irq - VGIC_NR_PRIVATE_IRQS, x->shared); |
| 138 | } | 165 | } |
| 139 | 166 | ||
| 140 | static void vgic_bitmap_set_irq_val(struct vgic_bitmap *x, int cpuid, | 167 | static void vgic_bitmap_set_irq_val(struct vgic_bitmap *x, int cpuid, |
| @@ -143,9 +170,9 @@ static void vgic_bitmap_set_irq_val(struct vgic_bitmap *x, int cpuid, | |||
| 143 | unsigned long *reg; | 170 | unsigned long *reg; |
| 144 | 171 | ||
| 145 | if (irq < VGIC_NR_PRIVATE_IRQS) { | 172 | if (irq < VGIC_NR_PRIVATE_IRQS) { |
| 146 | reg = x->percpu[cpuid].reg_ul; | 173 | reg = x->private + cpuid; |
| 147 | } else { | 174 | } else { |
| 148 | reg = x->shared.reg_ul; | 175 | reg = x->shared; |
| 149 | irq -= VGIC_NR_PRIVATE_IRQS; | 176 | irq -= VGIC_NR_PRIVATE_IRQS; |
| 150 | } | 177 | } |
| 151 | 178 | ||
| @@ -157,24 +184,49 @@ static void vgic_bitmap_set_irq_val(struct vgic_bitmap *x, int cpuid, | |||
| 157 | 184 | ||
| 158 | static unsigned long *vgic_bitmap_get_cpu_map(struct vgic_bitmap *x, int cpuid) | 185 | static unsigned long *vgic_bitmap_get_cpu_map(struct vgic_bitmap *x, int cpuid) |
| 159 | { | 186 | { |
| 160 | if (unlikely(cpuid >= VGIC_MAX_CPUS)) | 187 | return x->private + cpuid; |
| 161 | return NULL; | ||
| 162 | return x->percpu[cpuid].reg_ul; | ||
| 163 | } | 188 | } |
| 164 | 189 | ||
| 165 | static unsigned long *vgic_bitmap_get_shared_map(struct vgic_bitmap *x) | 190 | static unsigned long *vgic_bitmap_get_shared_map(struct vgic_bitmap *x) |
| 166 | { | 191 | { |
| 167 | return x->shared.reg_ul; | 192 | return x->shared; |
| 193 | } | ||
| 194 | |||
| 195 | static int vgic_init_bytemap(struct vgic_bytemap *x, int nr_cpus, int nr_irqs) | ||
| 196 | { | ||
| 197 | int size; | ||
| 198 | |||
| 199 | size = nr_cpus * VGIC_NR_PRIVATE_IRQS; | ||
| 200 | size += nr_irqs - VGIC_NR_PRIVATE_IRQS; | ||
| 201 | |||
| 202 | x->private = kzalloc(size, GFP_KERNEL); | ||
| 203 | if | ||
