Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 35 additions & 11 deletions arch/riscv/kvm/tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,14 +325,11 @@ void kvm_riscv_hfence_process(struct kvm_vcpu *vcpu)
}
}

static void make_xfence_request(struct kvm *kvm,
unsigned long hbase, unsigned long hmask,
unsigned int req, unsigned int fallback_req,
const struct kvm_riscv_hfence *data)
static void make_xfence_request_nodata(struct kvm *kvm, unsigned long hbase,
unsigned long hmask, unsigned int req)
{
unsigned long i;
struct kvm_vcpu *vcpu;
unsigned int actual_req = req;
DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS);

bitmap_zero(vcpu_mask, KVM_MAX_VCPUS);
Expand All @@ -346,27 +343,54 @@ static void make_xfence_request(struct kvm *kvm,
}

bitmap_set(vcpu_mask, i, 1);
}

kvm_make_vcpus_request_mask(kvm, req, vcpu_mask);
}

if (!data || !data->type)
continue;
static void make_xfence_request(struct kvm *kvm,
unsigned long hbase, unsigned long hmask,
unsigned int req, unsigned int fallback_req,
const struct kvm_riscv_hfence *data)
{
unsigned long i;
struct kvm_vcpu *vcpu;
DECLARE_BITMAP(req_vcpu_mask, KVM_MAX_VCPUS);
DECLARE_BITMAP(fallback_req_vcpu_mask, KVM_MAX_VCPUS);

if (!data || !data->type)
return;

bitmap_zero(req_vcpu_mask, KVM_MAX_VCPUS);
bitmap_zero(fallback_req_vcpu_mask, KVM_MAX_VCPUS);
kvm_for_each_vcpu(i, vcpu, kvm) {
if (hbase != -1UL) {
if (vcpu->vcpu_id < hbase ||
vcpu->vcpu_id >= hbase + BITS_PER_LONG)
continue;
if (!(hmask & (1UL << (vcpu->vcpu_id - hbase))))
continue;
}

/*
* Enqueue hfence data to VCPU hfence queue. If we don't
* have space in the VCPU hfence queue then fallback to
* a more conservative hfence request.
*/
if (!vcpu_hfence_enqueue(vcpu, data))
actual_req = fallback_req;
bitmap_set(fallback_req_vcpu_mask, i, 1);
else
bitmap_set(req_vcpu_mask, i, 1);
}

kvm_make_vcpus_request_mask(kvm, actual_req, vcpu_mask);
kvm_make_vcpus_request_mask(kvm, req, req_vcpu_mask);
kvm_make_vcpus_request_mask(kvm, fallback_req, fallback_req_vcpu_mask);
}

void kvm_riscv_fence_i(struct kvm *kvm,
unsigned long hbase, unsigned long hmask)
{
make_xfence_request(kvm, hbase, hmask, KVM_REQ_FENCE_I,
KVM_REQ_FENCE_I, NULL);
make_xfence_request_nodata(kvm, hbase, hmask, KVM_REQ_FENCE_I);
}

void kvm_riscv_hfence_gvma_vmid_gpa(struct kvm *kvm,
Expand Down
Loading