Skip to content

Commit 1cf7b28

Browse files
bibo-maochenhuacai
authored andcommitted
LoongArch: KVM: Add implementation with IOCSR_IPI_SET
IPI IOCSR register IOCSR_IPI_SET can send ipi interrupt to other vCPUs, but it can also send an interrupt to vCPU itself. Indeed there are such operations on Linux as arch_irq_work_raise() which will send ipi message to vCPU itself. Here add implementation of write operation with IOCSR_IPI_SET register. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent 44598fe commit 1cf7b28

1 file changed

Lines changed: 20 additions & 15 deletions

File tree

  • arch/loongarch/kvm/intc

arch/loongarch/kvm/intc/ipi.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,34 @@
77
#include <asm/kvm_ipi.h>
88
#include <asm/kvm_vcpu.h>
99

10-
static void ipi_send(struct kvm *kvm, uint64_t data)
10+
static void ipi_set(struct kvm_vcpu *vcpu, uint32_t data)
1111
{
12-
int cpu, action;
1312
uint32_t status;
14-
struct kvm_vcpu *vcpu;
1513
struct kvm_interrupt irq;
1614

15+
spin_lock(&vcpu->arch.ipi_state.lock);
16+
status = vcpu->arch.ipi_state.status;
17+
vcpu->arch.ipi_state.status |= data;
18+
spin_unlock(&vcpu->arch.ipi_state.lock);
19+
if ((status == 0) && data) {
20+
irq.irq = LARCH_INT_IPI;
21+
kvm_vcpu_ioctl_interrupt(vcpu, &irq);
22+
}
23+
}
24+
25+
static void ipi_send(struct kvm *kvm, uint64_t data)
26+
{
27+
int cpu;
28+
struct kvm_vcpu *vcpu;
29+
1730
cpu = ((data & 0xffffffff) >> 16) & 0x3ff;
1831
vcpu = kvm_get_vcpu_by_cpuid(kvm, cpu);
1932
if (unlikely(vcpu == NULL)) {
2033
kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
2134
return;
2235
}
2336

24-
action = BIT(data & 0x1f);
25-
spin_lock(&vcpu->arch.ipi_state.lock);
26-
status = vcpu->arch.ipi_state.status;
27-
vcpu->arch.ipi_state.status |= action;
28-
spin_unlock(&vcpu->arch.ipi_state.lock);
29-
if (status == 0) {
30-
irq.irq = LARCH_INT_IPI;
31-
kvm_vcpu_ioctl_interrupt(vcpu, &irq);
32-
}
37+
ipi_set(vcpu, BIT(data & 0x1f));
3338
}
3439

3540
static void ipi_clear(struct kvm_vcpu *vcpu, uint64_t data)
@@ -231,7 +236,7 @@ static int loongarch_ipi_writel(struct kvm_vcpu *vcpu, gpa_t addr, int len, cons
231236
spin_unlock(&vcpu->arch.ipi_state.lock);
232237
break;
233238
case IOCSR_IPI_SET:
234-
ret = -EINVAL;
239+
ipi_set(vcpu, data);
235240
break;
236241
case IOCSR_IPI_CLEAR:
237242
/* Just clear the status of the current vcpu */
@@ -250,10 +255,10 @@ static int loongarch_ipi_writel(struct kvm_vcpu *vcpu, gpa_t addr, int len, cons
250255
ipi_send(vcpu->kvm, data);
251256
break;
252257
case IOCSR_MAIL_SEND:
253-
ret = mail_send(vcpu->kvm, *(uint64_t *)val);
258+
ret = mail_send(vcpu->kvm, data);
254259
break;
255260
case IOCSR_ANY_SEND:
256-
ret = any_send(vcpu->kvm, *(uint64_t *)val);
261+
ret = any_send(vcpu->kvm, data);
257262
break;
258263
default:
259264
kvm_err("%s: unknown addr: %llx\n", __func__, addr);

0 commit comments

Comments
 (0)