Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ffe36492 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Alexander Graf
Browse files

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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
[agraf: simplify ppc32 case]
Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
parent 32c7dbfd
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -81,12 +81,13 @@ struct kvmppc_vcpu_book3s {
	u64 sdr1;
	u64 hior;
	u64 msr_mask;
	u64 vsid_next;
#ifdef CONFIG_PPC_BOOK3S_32
	u32 vsid_pool[VSID_POOL_SIZE];
	u32 vsid_next;
#else
	u64 vsid_first;
	u64 vsid_max;
	u64 proto_vsid_first;
	u64 proto_vsid_max;
	u64 proto_vsid_next;
#endif
	int context_id[SID_CONTEXTS];

+7 −6
Original line number Diff line number Diff line
@@ -194,14 +194,14 @@ static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid)
	backwards_map = !backwards_map;

	/* Uh-oh ... out of mappings. Let's flush! */
	if (vcpu_book3s->vsid_next == vcpu_book3s->vsid_max) {
		vcpu_book3s->vsid_next = vcpu_book3s->vsid_first;
	if (vcpu_book3s->proto_vsid_next == vcpu_book3s->proto_vsid_max) {
		vcpu_book3s->proto_vsid_next = vcpu_book3s->proto_vsid_first;
		memset(vcpu_book3s->sid_map, 0,
		       sizeof(struct kvmppc_sid_map) * SID_MAP_NUM);
		kvmppc_mmu_pte_flush(vcpu, 0, 0);
		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->valid = true;
@@ -319,9 +319,10 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu)
		return -1;
	vcpu3s->context_id[0] = err;

	vcpu3s->vsid_max = ((vcpu3s->context_id[0] + 1) << USER_ESID_BITS) - 1;
	vcpu3s->vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS;
	vcpu3s->vsid_next = vcpu3s->vsid_first;
	vcpu3s->proto_vsid_max = ((vcpu3s->context_id[0] + 1)
				  << USER_ESID_BITS) - 1;
	vcpu3s->proto_vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS;
	vcpu3s->proto_vsid_next = vcpu3s->proto_vsid_first;

	kvmppc_mmu_hpte_init(vcpu);