Merge git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm powerpc fixes from Marcelo Tosatti: "Urgent KVM PPC updates, quoting Alexander Graf: There are a few bugs in 3.4 that really should be fixed before people can be all happy and fuzzy about KVM on PowerPC. These fixes are: * fix POWER7 bare metal with PR=y * fix deadlock on HV=y book3s_64 mode in low memory cases * fix invalid MMU scope of PR=y mode on book3s_64, possibly eading to memory corruption" * git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: PPC: Book3S HV: Fix bug leading to deadlock in guest HPT updates powerpc/kvm: Fix VSID usage in 64-bit "PR" KVM KVM: PPC: Book3S: PR: Fix hsrr code KVM: PPC: Fix PR KVM on POWER7 bare metal KVM: PPC: Book3S: PR: Handle EMUL_ASSIST
This commit is contained in:
@@ -81,12 +81,13 @@ struct kvmppc_vcpu_book3s {
|
|||||||
u64 sdr1;
|
u64 sdr1;
|
||||||
u64 hior;
|
u64 hior;
|
||||||
u64 msr_mask;
|
u64 msr_mask;
|
||||||
u64 vsid_next;
|
|
||||||
#ifdef CONFIG_PPC_BOOK3S_32
|
#ifdef CONFIG_PPC_BOOK3S_32
|
||||||
u32 vsid_pool[VSID_POOL_SIZE];
|
u32 vsid_pool[VSID_POOL_SIZE];
|
||||||
|
u32 vsid_next;
|
||||||
#else
|
#else
|
||||||
u64 vsid_first;
|
u64 proto_vsid_first;
|
||||||
u64 vsid_max;
|
u64 proto_vsid_max;
|
||||||
|
u64 proto_vsid_next;
|
||||||
#endif
|
#endif
|
||||||
int context_id[SID_CONTEXTS];
|
int context_id[SID_CONTEXTS];
|
||||||
|
|
||||||
|
@@ -194,14 +194,14 @@ static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid)
|
|||||||
backwards_map = !backwards_map;
|
backwards_map = !backwards_map;
|
||||||
|
|
||||||
/* Uh-oh ... out of mappings. Let's flush! */
|
/* Uh-oh ... out of mappings. Let's flush! */
|
||||||
if (vcpu_book3s->vsid_next == vcpu_book3s->vsid_max) {
|
if (vcpu_book3s->proto_vsid_next == vcpu_book3s->proto_vsid_max) {
|
||||||
vcpu_book3s->vsid_next = vcpu_book3s->vsid_first;
|
vcpu_book3s->proto_vsid_next = vcpu_book3s->proto_vsid_first;
|
||||||
memset(vcpu_book3s->sid_map, 0,
|
memset(vcpu_book3s->sid_map, 0,
|
||||||
sizeof(struct kvmppc_sid_map) * SID_MAP_NUM);
|
sizeof(struct kvmppc_sid_map) * SID_MAP_NUM);
|
||||||
kvmppc_mmu_pte_flush(vcpu, 0, 0);
|
kvmppc_mmu_pte_flush(vcpu, 0, 0);
|
||||||
kvmppc_mmu_flush_segments(vcpu);
|
kvmppc_mmu_flush_segments(vcpu);
|
||||||
}
|
}
|
||||||
map->host_vsid = vcpu_book3s->vsid_next++;
|
map->host_vsid = vsid_scramble(vcpu_book3s->proto_vsid_next++, 256M);
|
||||||
|
|
||||||
map->guest_vsid = gvsid;
|
map->guest_vsid = gvsid;
|
||||||
map->valid = true;
|
map->valid = true;
|
||||||
@@ -319,9 +319,10 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu)
|
|||||||
return -1;
|
return -1;
|
||||||
vcpu3s->context_id[0] = err;
|
vcpu3s->context_id[0] = err;
|
||||||
|
|
||||||
vcpu3s->vsid_max = ((vcpu3s->context_id[0] + 1) << USER_ESID_BITS) - 1;
|
vcpu3s->proto_vsid_max = ((vcpu3s->context_id[0] + 1)
|
||||||
vcpu3s->vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS;
|
<< USER_ESID_BITS) - 1;
|
||||||
vcpu3s->vsid_next = vcpu3s->vsid_first;
|
vcpu3s->proto_vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS;
|
||||||
|
vcpu3s->proto_vsid_next = vcpu3s->proto_vsid_first;
|
||||||
|
|
||||||
kvmppc_mmu_hpte_init(vcpu);
|
kvmppc_mmu_hpte_init(vcpu);
|
||||||
|
|
||||||
|
@@ -463,6 +463,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu)
|
|||||||
/* insert R and C bits from PTE */
|
/* insert R and C bits from PTE */
|
||||||
rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C);
|
rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C);
|
||||||
args[j] |= rcbits << (56 - 5);
|
args[j] |= rcbits << (56 - 5);
|
||||||
|
hp[0] = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -197,7 +197,8 @@ kvmppc_interrupt:
|
|||||||
/* Save guest PC and MSR */
|
/* Save guest PC and MSR */
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
BEGIN_FTR_SECTION
|
BEGIN_FTR_SECTION
|
||||||
andi. r0,r12,0x2
|
andi. r0, r12, 0x2
|
||||||
|
cmpwi cr1, r0, 0
|
||||||
beq 1f
|
beq 1f
|
||||||
mfspr r3,SPRN_HSRR0
|
mfspr r3,SPRN_HSRR0
|
||||||
mfspr r4,SPRN_HSRR1
|
mfspr r4,SPRN_HSRR1
|
||||||
@@ -250,6 +251,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
|||||||
beq ld_last_prev_inst
|
beq ld_last_prev_inst
|
||||||
cmpwi r12, BOOK3S_INTERRUPT_ALIGNMENT
|
cmpwi r12, BOOK3S_INTERRUPT_ALIGNMENT
|
||||||
beq- ld_last_inst
|
beq- ld_last_inst
|
||||||
|
#ifdef CONFIG_PPC64
|
||||||
|
BEGIN_FTR_SECTION
|
||||||
|
cmpwi r12, BOOK3S_INTERRUPT_H_EMUL_ASSIST
|
||||||
|
beq- ld_last_inst
|
||||||
|
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
||||||
|
#endif
|
||||||
|
|
||||||
b no_ld_last_inst
|
b no_ld_last_inst
|
||||||
|
|
||||||
@@ -316,23 +323,17 @@ no_dcbz32_off:
|
|||||||
* Having set up SRR0/1 with the address where we want
|
* Having set up SRR0/1 with the address where we want
|
||||||
* to continue with relocation on (potentially in module
|
* to continue with relocation on (potentially in module
|
||||||
* space), we either just go straight there with rfi[d],
|
* space), we either just go straight there with rfi[d],
|
||||||
* or we jump to an interrupt handler with bctr if there
|
* or we jump to an interrupt handler if there is an
|
||||||
* is an interrupt to be handled first. In the latter
|
* interrupt to be handled first. In the latter case,
|
||||||
* case, the rfi[d] at the end of the interrupt handler
|
* the rfi[d] at the end of the interrupt handler will
|
||||||
* will get us back to where we want to continue.
|
* get us back to where we want to continue.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
|
|
||||||
beq 1f
|
|
||||||
cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER
|
|
||||||
beq 1f
|
|
||||||
cmpwi r12, BOOK3S_INTERRUPT_PERFMON
|
|
||||||
1: mtctr r12
|
|
||||||
|
|
||||||
/* Register usage at this point:
|
/* Register usage at this point:
|
||||||
*
|
*
|
||||||
* R1 = host R1
|
* R1 = host R1
|
||||||
* R2 = host R2
|
* R2 = host R2
|
||||||
|
* R10 = raw exit handler id
|
||||||
* R12 = exit handler id
|
* R12 = exit handler id
|
||||||
* R13 = shadow vcpu (32-bit) or PACA (64-bit)
|
* R13 = shadow vcpu (32-bit) or PACA (64-bit)
|
||||||
* SVCPU.* = guest *
|
* SVCPU.* = guest *
|
||||||
@@ -342,12 +343,25 @@ no_dcbz32_off:
|
|||||||
PPC_LL r6, HSTATE_HOST_MSR(r13)
|
PPC_LL r6, HSTATE_HOST_MSR(r13)
|
||||||
PPC_LL r8, HSTATE_VMHANDLER(r13)
|
PPC_LL r8, HSTATE_VMHANDLER(r13)
|
||||||
|
|
||||||
/* Restore host msr -> SRR1 */
|
#ifdef CONFIG_PPC64
|
||||||
|
BEGIN_FTR_SECTION
|
||||||
|
beq cr1, 1f
|
||||||
|
mtspr SPRN_HSRR1, r6
|
||||||
|
mtspr SPRN_HSRR0, r8
|
||||||
|
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
||||||
|
#endif
|
||||||
|
1: /* Restore host msr -> SRR1 */
|
||||||
mtsrr1 r6
|
mtsrr1 r6
|
||||||
/* Load highmem handler address */
|
/* Load highmem handler address */
|
||||||
mtsrr0 r8
|
mtsrr0 r8
|
||||||
|
|
||||||
/* RFI into the highmem handler, or jump to interrupt handler */
|
/* RFI into the highmem handler, or jump to interrupt handler */
|
||||||
beqctr
|
cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
|
||||||
|
beqa BOOK3S_INTERRUPT_EXTERNAL
|
||||||
|
cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER
|
||||||
|
beqa BOOK3S_INTERRUPT_DECREMENTER
|
||||||
|
cmpwi r12, BOOK3S_INTERRUPT_PERFMON
|
||||||
|
beqa BOOK3S_INTERRUPT_PERFMON
|
||||||
|
|
||||||
RFI
|
RFI
|
||||||
kvmppc_handler_trampoline_exit_end:
|
kvmppc_handler_trampoline_exit_end:
|
||||||
|
Reference in New Issue
Block a user