mirror of
https://github.com/torvalds/linux.git
synced 2024-11-14 16:12:02 +00:00
powerpc/kvm: Fix VSID usage in 64-bit "PR" KVM
The code forgot to scramble the VSIDs the way we normally do and was basically using the "proto VSID" directly with the MMU. This means that in practice, KVM used random VSIDs that could collide with segments used by other user space programs. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> [agraf: simplify ppc32 case] Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
32c7dbfd47
commit
ffe3649282
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user