arch/loongarch/kvm/intc/ipi.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
With function mail_send(), it is to write mailbox of other VCPUs.
Existing simple APIs read_mailbox/write_mailbox can be used directly
rather than send command on IOCSR address.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
arch/loongarch/kvm/intc/ipi.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c
index fe734dc062ed..832b2d4aa2ef 100644
--- a/arch/loongarch/kvm/intc/ipi.c
+++ b/arch/loongarch/kvm/intc/ipi.c
@@ -134,7 +134,8 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)
static int mail_send(struct kvm *kvm, uint64_t data)
{
- int cpu, mailbox, offset;
+ int i, cpu, mailbox, offset;
+ uint32_t val = 0, mask = 0;
struct kvm_vcpu *vcpu;
cpu = ((data & 0xffffffff) >> 16) & 0x3ff;
@@ -144,9 +145,18 @@ static int mail_send(struct kvm *kvm, uint64_t data)
return -EINVAL;
}
mailbox = ((data & 0xffffffff) >> 2) & 0x7;
- offset = IOCSR_IPI_BASE + IOCSR_IPI_BUF_20 + mailbox * 4;
+ offset = IOCSR_IPI_BUF_20 + mailbox * 4;
+ if ((data >> 27) & 0xf) {
+ val = read_mailbox(vcpu, offset, 4);
+ for (i = 0; i < 4; i++)
+ if (data & (BIT(27 + i)))
+ mask |= (0xff << (i * 8));
+ val &= mask;
+ }
- return send_ipi_data(vcpu, offset, data);
+ val |= ((uint32_t)(data >> 32) & ~mask);
+ write_mailbox(vcpu, offset, val, 4);
+ return 0;
}
static int any_send(struct kvm *kvm, uint64_t data)
base-commit: 038d61fd642278bab63ee8ef722c50d10ab01e8f
--
2.39.3
在 7/31/25 3:59 PM, Bibo Mao 写道: > With function mail_send(), it is to write mailbox of other VCPUs. > Existing simple APIs read_mailbox/write_mailbox can be used directly > rather than send command on IOCSR address. Hmm, that's indeed a feasible approach. However, I'm curious: what is the purpose of designing IOCSR in LoongArch? Is it merely to make things "complicated"? Thanks, Yanteng > > Signed-off-by: Bibo Mao <maobibo@loongson.cn> > --- > arch/loongarch/kvm/intc/ipi.c | 16 +++++++++++++--- > 1 file changed, 13 insertions(+), 3 deletions(-) > > diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c > index fe734dc062ed..832b2d4aa2ef 100644 > --- a/arch/loongarch/kvm/intc/ipi.c > +++ b/arch/loongarch/kvm/intc/ipi.c > @@ -134,7 +134,8 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data) > > static int mail_send(struct kvm *kvm, uint64_t data) > { > - int cpu, mailbox, offset; > + int i, cpu, mailbox, offset; > + uint32_t val = 0, mask = 0; > struct kvm_vcpu *vcpu; > > cpu = ((data & 0xffffffff) >> 16) & 0x3ff; > @@ -144,9 +145,18 @@ static int mail_send(struct kvm *kvm, uint64_t data) > return -EINVAL; > } > mailbox = ((data & 0xffffffff) >> 2) & 0x7; > - offset = IOCSR_IPI_BASE + IOCSR_IPI_BUF_20 + mailbox * 4; > + offset = IOCSR_IPI_BUF_20 + mailbox * 4; > + if ((data >> 27) & 0xf) { > + val = read_mailbox(vcpu, offset, 4); > + for (i = 0; i < 4; i++) > + if (data & (BIT(27 + i))) > + mask |= (0xff << (i * 8)); > + val &= mask; > + } > > - return send_ipi_data(vcpu, offset, data); > + val |= ((uint32_t)(data >> 32) & ~mask); > + write_mailbox(vcpu, offset, val, 4); > + return 0; > } > > static int any_send(struct kvm *kvm, uint64_t data) > > base-commit: 038d61fd642278bab63ee8ef722c50d10ab01e8f
On 2025/7/31 下午5:30, Yanteng Si wrote: > 在 7/31/25 3:59 PM, Bibo Mao 写道: >> With function mail_send(), it is to write mailbox of other VCPUs. >> Existing simple APIs read_mailbox/write_mailbox can be used directly >> rather than send command on IOCSR address. > Hmm, that's indeed a feasible approach. However, I'm > curious: what is the purpose of designing IOCSR in > LoongArch? Is it merely to make things "complicated"? I am not chip designer -:). MMIO address space is ok from my side, however I do not know how to solve multi-chip problem with MMIO method. Regards Bibo Mao > > Thanks, > Yanteng >> >> Signed-off-by: Bibo Mao <maobibo@loongson.cn> >> --- >> arch/loongarch/kvm/intc/ipi.c | 16 +++++++++++++--- >> 1 file changed, 13 insertions(+), 3 deletions(-) >> >> diff --git a/arch/loongarch/kvm/intc/ipi.c >> b/arch/loongarch/kvm/intc/ipi.c >> index fe734dc062ed..832b2d4aa2ef 100644 >> --- a/arch/loongarch/kvm/intc/ipi.c >> +++ b/arch/loongarch/kvm/intc/ipi.c >> @@ -134,7 +134,8 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, >> gpa_t addr, uint64_t data) >> static int mail_send(struct kvm *kvm, uint64_t data) >> { >> - int cpu, mailbox, offset; >> + int i, cpu, mailbox, offset; >> + uint32_t val = 0, mask = 0; >> struct kvm_vcpu *vcpu; >> cpu = ((data & 0xffffffff) >> 16) & 0x3ff; >> @@ -144,9 +145,18 @@ static int mail_send(struct kvm *kvm, uint64_t data) >> return -EINVAL; >> } >> mailbox = ((data & 0xffffffff) >> 2) & 0x7; >> - offset = IOCSR_IPI_BASE + IOCSR_IPI_BUF_20 + mailbox * 4; >> + offset = IOCSR_IPI_BUF_20 + mailbox * 4; >> + if ((data >> 27) & 0xf) { >> + val = read_mailbox(vcpu, offset, 4); >> + for (i = 0; i < 4; i++) >> + if (data & (BIT(27 + i))) >> + mask |= (0xff << (i * 8)); >> + val &= mask; >> + } >> - return send_ipi_data(vcpu, offset, data); >> + val |= ((uint32_t)(data >> 32) & ~mask); >> + write_mailbox(vcpu, offset, val, 4); >> + return 0; >> } >> static int any_send(struct kvm *kvm, uint64_t data) >> >> base-commit: 038d61fd642278bab63ee8ef722c50d10ab01e8f >
在 7/31/25 7:24 PM, Bibo Mao 写道: > > > On 2025/7/31 下午5:30, Yanteng Si wrote: >> 在 7/31/25 3:59 PM, Bibo Mao 写道: >>> With function mail_send(), it is to write mailbox of other VCPUs. >>> Existing simple APIs read_mailbox/write_mailbox can be used directly >>> rather than send command on IOCSR address. >> Hmm, that's indeed a feasible approach. However, I'm >> curious: what is the purpose of designing IOCSR in >> LoongArch? Is it merely to make things "complicated"? > > I am not chip designer -:). MMIO address space is ok from my side, however I do not know how to solve multi-chip problem with MMIO method. I have reviewed many manuals published on loongson.cn and found that your chip engineers recommend using IOCSR. Although I don't know the specific reason, I believe it must have solved some problems, so let's continue to use IOCSR. see: 《龙芯 3D5000 处理器 寄存器使用手册》第10章 龙芯 3D5000 中支持两种不同的访问方式,一种是地址访问模式,另一种是为了支持处理器寄存器空间的直接指令访问.后面章节进行分别说明.推荐使用处理器 IOCSR 指令访问 Thanks, Yanteng > > Regards > Bibo Mao >> >> Thanks, >> Yanteng >>> >>> Signed-off-by: Bibo Mao <maobibo@loongson.cn> >>> --- >>> arch/loongarch/kvm/intc/ipi.c | 16 +++++++++++++--- >>> 1 file changed, 13 insertions(+), 3 deletions(-) >>> >>> diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c >>> index fe734dc062ed..832b2d4aa2ef 100644 >>> --- a/arch/loongarch/kvm/intc/ipi.c >>> +++ b/arch/loongarch/kvm/intc/ipi.c >>> @@ -134,7 +134,8 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data) >>> static int mail_send(struct kvm *kvm, uint64_t data) >>> { >>> - int cpu, mailbox, offset; >>> + int i, cpu, mailbox, offset; >>> + uint32_t val = 0, mask = 0; >>> struct kvm_vcpu *vcpu; >>> cpu = ((data & 0xffffffff) >> 16) & 0x3ff; >>> @@ -144,9 +145,18 @@ static int mail_send(struct kvm *kvm, uint64_t data) >>> return -EINVAL; >>> } >>> mailbox = ((data & 0xffffffff) >> 2) & 0x7; >>> - offset = IOCSR_IPI_BASE + IOCSR_IPI_BUF_20 + mailbox * 4; >>> + offset = IOCSR_IPI_BUF_20 + mailbox * 4; >>> + if ((data >> 27) & 0xf) { >>> + val = read_mailbox(vcpu, offset, 4); >>> + for (i = 0; i < 4; i++) >>> + if (data & (BIT(27 + i))) >>> + mask |= (0xff << (i * 8)); >>> + val &= mask; >>> + } >>> - return send_ipi_data(vcpu, offset, data); >>> + val |= ((uint32_t)(data >> 32) & ~mask); >>> + write_mailbox(vcpu, offset, val, 4); >>> + return 0; >>> } >>> static int any_send(struct kvm *kvm, uint64_t data) >>> >>> base-commit: 038d61fd642278bab63ee8ef722c50d10ab01e8f >> >
© 2016 - 2025 Red Hat, Inc.