Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-08 Thread maobibo




On 2024/5/8 下午1:00, Huacai Chen wrote:

On Tue, May 7, 2024 at 11:06 AM maobibo  wrote:




On 2024/5/7 上午10:05, Huacai Chen wrote:

On Tue, May 7, 2024 at 9:40 AM maobibo  wrote:




On 2024/5/6 下午10:17, Huacai Chen wrote:

On Mon, May 6, 2024 at 6:05 PM maobibo  wrote:




On 2024/5/6 下午5:40, Huacai Chen wrote:

On Mon, May 6, 2024 at 5:35 PM maobibo  wrote:




On 2024/5/6 下午4:59, Huacai Chen wrote:

On Mon, May 6, 2024 at 4:18 PM maobibo  wrote:




On 2024/5/6 下午3:06, Huacai Chen wrote:

Hi, Bibo,

On Mon, May 6, 2024 at 2:36 PM maobibo  wrote:




On 2024/5/6 上午9:49, Huacai Chen wrote:

Hi, Bibo,

On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:


Physical cpuid is used for interrupt routing for irqchips such as
ipi/msi/extioi interrupt controller. And physical cpuid is stored
at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
is created and physical cpuid of two vcpus cannot be the same.

Different irqchips have different size declaration about physical cpuid,
max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
for MSI irqchip.

The smallest value from all interrupt controllers is selected now,
and the max cpuid size is defines as 256 by KVM which comes from
extioi irqchip.

Signed-off-by: Bibo Mao 
---
arch/loongarch/include/asm/kvm_host.h | 26 
arch/loongarch/include/asm/kvm_vcpu.h |  1 +
arch/loongarch/kvm/vcpu.c | 93 ++-
arch/loongarch/kvm/vm.c   | 11 
4 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/arch/loongarch/include/asm/kvm_host.h 
b/arch/loongarch/include/asm/kvm_host.h
index 2d62f7b0d377..3ba16ef1fe69 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -64,6 +64,30 @@ struct kvm_world_switch {

#define MAX_PGTABLE_LEVELS 4

+/*
+ * Physical cpu id is used for interrupt routing, there are different
+ * definitions about physical cpuid on different hardwares.
+ *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
+ *  For IPI HW, max dest CPUID size 1024
+ *  For extioi interrupt controller, max dest CPUID size is 256
+ *  For MSI interrupt controller, max supported CPUID size is 65536
+ *
+ * Currently max CPUID is defined as 256 for KVM hypervisor, in future
+ * it will be expanded to 4096, including 16 packages at most. And every
+ * package supports at most 256 vcpus
+ */
+#define KVM_MAX_PHYID  256
+
+struct kvm_phyid_info {
+   struct kvm_vcpu *vcpu;
+   boolenabled;
+};
+
+struct kvm_phyid_map {
+   int max_phyid;
+   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
+};
+
struct kvm_arch {
   /* Guest physical mm */
   kvm_pte_t *pgd;
@@ -71,6 +95,8 @@ struct kvm_arch {
   unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
   unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
   unsigned int  root_level;
+   spinlock_tphyid_map_lock;
+   struct kvm_phyid_map  *phyid_map;

   s64 time_offset;
   struct kvm_context __percpu *vmcs;
diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
b/arch/loongarch/include/asm/kvm_vcpu.h
index 0cb4fdb8a9b5..9f53950959da 100644
--- a/arch/loongarch/include/asm/kvm_vcpu.h
+++ b/arch/loongarch/include/asm/kvm_vcpu.h
@@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
void kvm_restore_timer(struct kvm_vcpu *vcpu);

int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct 
kvm_interrupt *irq);
+struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);

/*
 * Loongarch KVM guest interrupt handling
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 3a8779065f73..b633fd28b8db 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int 
id, u64 *val)
   return 0;
}

+static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
+{
+   int cpuid;
+   struct loongarch_csrs *csr = vcpu->arch.csr;
+   struct kvm_phyid_map  *map;
+
+   if (val >= KVM_MAX_PHYID)
+   return -EINVAL;
+
+   cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT);
+   map = vcpu->kvm->arch.phyid_map;
+   spin_lock(>kvm->arch.phyid_map_lock);
+   if (map->phys_map[cpuid].enabled) {
+   /*
+* Cpuid is already set before
+* Forbid changing different cpuid at runtime
+*/
+   if (cpuid != val) {
+   /*
+* Cpuid 0 is initial value for vcpu, maybe invalid
+* unset value for vcpu
+*/
+   if (cpuid) {
+   spin_unlock(>kvm->arch.phyid_map_lock);
+ 

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-07 Thread Huacai Chen
On Tue, May 7, 2024 at 11:06 AM maobibo  wrote:
>
>
>
> On 2024/5/7 上午10:05, Huacai Chen wrote:
> > On Tue, May 7, 2024 at 9:40 AM maobibo  wrote:
> >>
> >>
> >>
> >> On 2024/5/6 下午10:17, Huacai Chen wrote:
> >>> On Mon, May 6, 2024 at 6:05 PM maobibo  wrote:
> 
> 
> 
>  On 2024/5/6 下午5:40, Huacai Chen wrote:
> > On Mon, May 6, 2024 at 5:35 PM maobibo  wrote:
> >>
> >>
> >>
> >> On 2024/5/6 下午4:59, Huacai Chen wrote:
> >>> On Mon, May 6, 2024 at 4:18 PM maobibo  wrote:
> 
> 
> 
>  On 2024/5/6 下午3:06, Huacai Chen wrote:
> > Hi, Bibo,
> >
> > On Mon, May 6, 2024 at 2:36 PM maobibo  wrote:
> >>
> >>
> >>
> >> On 2024/5/6 上午9:49, Huacai Chen wrote:
> >>> Hi, Bibo,
> >>>
> >>> On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  
> >>> wrote:
> 
>  Physical cpuid is used for interrupt routing for irqchips such as
>  ipi/msi/extioi interrupt controller. And physical cpuid is stored
>  at CSR register LOONGARCH_CSR_CPUID, it can not be changed once 
>  vcpu
>  is created and physical cpuid of two vcpus cannot be the same.
> 
>  Different irqchips have different size declaration about 
>  physical cpuid,
>  max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, 
>  max cpuid
>  supported by IPI hardware is 1024, 256 for extioi irqchip, and 
>  65536
>  for MSI irqchip.
> 
>  The smallest value from all interrupt controllers is selected 
>  now,
>  and the max cpuid size is defines as 256 by KVM which comes from
>  extioi irqchip.
> 
>  Signed-off-by: Bibo Mao 
>  ---
> arch/loongarch/include/asm/kvm_host.h | 26 
> arch/loongarch/include/asm/kvm_vcpu.h |  1 +
> arch/loongarch/kvm/vcpu.c | 93 
>  ++-
> arch/loongarch/kvm/vm.c   | 11 
> 4 files changed, 130 insertions(+), 1 deletion(-)
> 
>  diff --git a/arch/loongarch/include/asm/kvm_host.h 
>  b/arch/loongarch/include/asm/kvm_host.h
>  index 2d62f7b0d377..3ba16ef1fe69 100644
>  --- a/arch/loongarch/include/asm/kvm_host.h
>  +++ b/arch/loongarch/include/asm/kvm_host.h
>  @@ -64,6 +64,30 @@ struct kvm_world_switch {
> 
> #define MAX_PGTABLE_LEVELS 4
> 
>  +/*
>  + * Physical cpu id is used for interrupt routing, there are 
>  different
>  + * definitions about physical cpuid on different hardwares.
>  + *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
>  + *  For IPI HW, max dest CPUID size 1024
>  + *  For extioi interrupt controller, max dest CPUID size is 256
>  + *  For MSI interrupt controller, max supported CPUID size is 
>  65536
>  + *
>  + * Currently max CPUID is defined as 256 for KVM hypervisor, in 
>  future
>  + * it will be expanded to 4096, including 16 packages at most. 
>  And every
>  + * package supports at most 256 vcpus
>  + */
>  +#define KVM_MAX_PHYID  256
>  +
>  +struct kvm_phyid_info {
>  +   struct kvm_vcpu *vcpu;
>  +   boolenabled;
>  +};
>  +
>  +struct kvm_phyid_map {
>  +   int max_phyid;
>  +   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
>  +};
>  +
> struct kvm_arch {
>    /* Guest physical mm */
>    kvm_pte_t *pgd;
>  @@ -71,6 +95,8 @@ struct kvm_arch {
>    unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
>    unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
>    unsigned int  root_level;
>  +   spinlock_tphyid_map_lock;
>  +   struct kvm_phyid_map  *phyid_map;
> 
>    s64 time_offset;
>    struct kvm_context __percpu *vmcs;
>  diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
>  b/arch/loongarch/include/asm/kvm_vcpu.h
>  index 0cb4fdb8a9b5..9f53950959da 100644
>  --- a/arch/loongarch/include/asm/kvm_vcpu.h
>  +++ b/arch/loongarch/include/asm/kvm_vcpu.h
>  @@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
> 

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-06 Thread maobibo




On 2024/5/7 上午10:05, Huacai Chen wrote:

On Tue, May 7, 2024 at 9:40 AM maobibo  wrote:




On 2024/5/6 下午10:17, Huacai Chen wrote:

On Mon, May 6, 2024 at 6:05 PM maobibo  wrote:




On 2024/5/6 下午5:40, Huacai Chen wrote:

On Mon, May 6, 2024 at 5:35 PM maobibo  wrote:




On 2024/5/6 下午4:59, Huacai Chen wrote:

On Mon, May 6, 2024 at 4:18 PM maobibo  wrote:




On 2024/5/6 下午3:06, Huacai Chen wrote:

Hi, Bibo,

On Mon, May 6, 2024 at 2:36 PM maobibo  wrote:




On 2024/5/6 上午9:49, Huacai Chen wrote:

Hi, Bibo,

On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:


Physical cpuid is used for interrupt routing for irqchips such as
ipi/msi/extioi interrupt controller. And physical cpuid is stored
at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
is created and physical cpuid of two vcpus cannot be the same.

Different irqchips have different size declaration about physical cpuid,
max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
for MSI irqchip.

The smallest value from all interrupt controllers is selected now,
and the max cpuid size is defines as 256 by KVM which comes from
extioi irqchip.

Signed-off-by: Bibo Mao 
---
   arch/loongarch/include/asm/kvm_host.h | 26 
   arch/loongarch/include/asm/kvm_vcpu.h |  1 +
   arch/loongarch/kvm/vcpu.c | 93 ++-
   arch/loongarch/kvm/vm.c   | 11 
   4 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/arch/loongarch/include/asm/kvm_host.h 
b/arch/loongarch/include/asm/kvm_host.h
index 2d62f7b0d377..3ba16ef1fe69 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -64,6 +64,30 @@ struct kvm_world_switch {

   #define MAX_PGTABLE_LEVELS 4

+/*
+ * Physical cpu id is used for interrupt routing, there are different
+ * definitions about physical cpuid on different hardwares.
+ *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
+ *  For IPI HW, max dest CPUID size 1024
+ *  For extioi interrupt controller, max dest CPUID size is 256
+ *  For MSI interrupt controller, max supported CPUID size is 65536
+ *
+ * Currently max CPUID is defined as 256 for KVM hypervisor, in future
+ * it will be expanded to 4096, including 16 packages at most. And every
+ * package supports at most 256 vcpus
+ */
+#define KVM_MAX_PHYID  256
+
+struct kvm_phyid_info {
+   struct kvm_vcpu *vcpu;
+   boolenabled;
+};
+
+struct kvm_phyid_map {
+   int max_phyid;
+   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
+};
+
   struct kvm_arch {
  /* Guest physical mm */
  kvm_pte_t *pgd;
@@ -71,6 +95,8 @@ struct kvm_arch {
  unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
  unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
  unsigned int  root_level;
+   spinlock_tphyid_map_lock;
+   struct kvm_phyid_map  *phyid_map;

  s64 time_offset;
  struct kvm_context __percpu *vmcs;
diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
b/arch/loongarch/include/asm/kvm_vcpu.h
index 0cb4fdb8a9b5..9f53950959da 100644
--- a/arch/loongarch/include/asm/kvm_vcpu.h
+++ b/arch/loongarch/include/asm/kvm_vcpu.h
@@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
   void kvm_restore_timer(struct kvm_vcpu *vcpu);

   int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt 
*irq);
+struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);

   /*
* Loongarch KVM guest interrupt handling
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 3a8779065f73..b633fd28b8db 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int 
id, u64 *val)
  return 0;
   }

+static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
+{
+   int cpuid;
+   struct loongarch_csrs *csr = vcpu->arch.csr;
+   struct kvm_phyid_map  *map;
+
+   if (val >= KVM_MAX_PHYID)
+   return -EINVAL;
+
+   cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT);
+   map = vcpu->kvm->arch.phyid_map;
+   spin_lock(>kvm->arch.phyid_map_lock);
+   if (map->phys_map[cpuid].enabled) {
+   /*
+* Cpuid is already set before
+* Forbid changing different cpuid at runtime
+*/
+   if (cpuid != val) {
+   /*
+* Cpuid 0 is initial value for vcpu, maybe invalid
+* unset value for vcpu
+*/
+   if (cpuid) {
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return -EINVAL;
+   }
+   } else {
+  

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-06 Thread Huacai Chen
On Tue, May 7, 2024 at 9:40 AM maobibo  wrote:
>
>
>
> On 2024/5/6 下午10:17, Huacai Chen wrote:
> > On Mon, May 6, 2024 at 6:05 PM maobibo  wrote:
> >>
> >>
> >>
> >> On 2024/5/6 下午5:40, Huacai Chen wrote:
> >>> On Mon, May 6, 2024 at 5:35 PM maobibo  wrote:
> 
> 
> 
>  On 2024/5/6 下午4:59, Huacai Chen wrote:
> > On Mon, May 6, 2024 at 4:18 PM maobibo  wrote:
> >>
> >>
> >>
> >> On 2024/5/6 下午3:06, Huacai Chen wrote:
> >>> Hi, Bibo,
> >>>
> >>> On Mon, May 6, 2024 at 2:36 PM maobibo  wrote:
> 
> 
> 
>  On 2024/5/6 上午9:49, Huacai Chen wrote:
> > Hi, Bibo,
> >
> > On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  
> > wrote:
> >>
> >> Physical cpuid is used for interrupt routing for irqchips such as
> >> ipi/msi/extioi interrupt controller. And physical cpuid is stored
> >> at CSR register LOONGARCH_CSR_CPUID, it can not be changed once 
> >> vcpu
> >> is created and physical cpuid of two vcpus cannot be the same.
> >>
> >> Different irqchips have different size declaration about physical 
> >> cpuid,
> >> max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max 
> >> cpuid
> >> supported by IPI hardware is 1024, 256 for extioi irqchip, and 
> >> 65536
> >> for MSI irqchip.
> >>
> >> The smallest value from all interrupt controllers is selected now,
> >> and the max cpuid size is defines as 256 by KVM which comes from
> >> extioi irqchip.
> >>
> >> Signed-off-by: Bibo Mao 
> >> ---
> >>   arch/loongarch/include/asm/kvm_host.h | 26 
> >>   arch/loongarch/include/asm/kvm_vcpu.h |  1 +
> >>   arch/loongarch/kvm/vcpu.c | 93 
> >> ++-
> >>   arch/loongarch/kvm/vm.c   | 11 
> >>   4 files changed, 130 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/arch/loongarch/include/asm/kvm_host.h 
> >> b/arch/loongarch/include/asm/kvm_host.h
> >> index 2d62f7b0d377..3ba16ef1fe69 100644
> >> --- a/arch/loongarch/include/asm/kvm_host.h
> >> +++ b/arch/loongarch/include/asm/kvm_host.h
> >> @@ -64,6 +64,30 @@ struct kvm_world_switch {
> >>
> >>   #define MAX_PGTABLE_LEVELS 4
> >>
> >> +/*
> >> + * Physical cpu id is used for interrupt routing, there are 
> >> different
> >> + * definitions about physical cpuid on different hardwares.
> >> + *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
> >> + *  For IPI HW, max dest CPUID size 1024
> >> + *  For extioi interrupt controller, max dest CPUID size is 256
> >> + *  For MSI interrupt controller, max supported CPUID size is 
> >> 65536
> >> + *
> >> + * Currently max CPUID is defined as 256 for KVM hypervisor, in 
> >> future
> >> + * it will be expanded to 4096, including 16 packages at most. 
> >> And every
> >> + * package supports at most 256 vcpus
> >> + */
> >> +#define KVM_MAX_PHYID  256
> >> +
> >> +struct kvm_phyid_info {
> >> +   struct kvm_vcpu *vcpu;
> >> +   boolenabled;
> >> +};
> >> +
> >> +struct kvm_phyid_map {
> >> +   int max_phyid;
> >> +   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
> >> +};
> >> +
> >>   struct kvm_arch {
> >>  /* Guest physical mm */
> >>  kvm_pte_t *pgd;
> >> @@ -71,6 +95,8 @@ struct kvm_arch {
> >>  unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
> >>  unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
> >>  unsigned int  root_level;
> >> +   spinlock_tphyid_map_lock;
> >> +   struct kvm_phyid_map  *phyid_map;
> >>
> >>  s64 time_offset;
> >>  struct kvm_context __percpu *vmcs;
> >> diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
> >> b/arch/loongarch/include/asm/kvm_vcpu.h
> >> index 0cb4fdb8a9b5..9f53950959da 100644
> >> --- a/arch/loongarch/include/asm/kvm_vcpu.h
> >> +++ b/arch/loongarch/include/asm/kvm_vcpu.h
> >> @@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
> >>   void kvm_restore_timer(struct kvm_vcpu *vcpu);
> >>
> >>   int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct 
> >> kvm_interrupt *irq);
> >> +struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int 
> >> cpuid);
> >>
> >>   /*
> >>* Loongarch KVM guest 

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-06 Thread maobibo




On 2024/5/6 下午10:17, Huacai Chen wrote:

On Mon, May 6, 2024 at 6:05 PM maobibo  wrote:




On 2024/5/6 下午5:40, Huacai Chen wrote:

On Mon, May 6, 2024 at 5:35 PM maobibo  wrote:




On 2024/5/6 下午4:59, Huacai Chen wrote:

On Mon, May 6, 2024 at 4:18 PM maobibo  wrote:




On 2024/5/6 下午3:06, Huacai Chen wrote:

Hi, Bibo,

On Mon, May 6, 2024 at 2:36 PM maobibo  wrote:




On 2024/5/6 上午9:49, Huacai Chen wrote:

Hi, Bibo,

On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:


Physical cpuid is used for interrupt routing for irqchips such as
ipi/msi/extioi interrupt controller. And physical cpuid is stored
at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
is created and physical cpuid of two vcpus cannot be the same.

Different irqchips have different size declaration about physical cpuid,
max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
for MSI irqchip.

The smallest value from all interrupt controllers is selected now,
and the max cpuid size is defines as 256 by KVM which comes from
extioi irqchip.

Signed-off-by: Bibo Mao 
---
  arch/loongarch/include/asm/kvm_host.h | 26 
  arch/loongarch/include/asm/kvm_vcpu.h |  1 +
  arch/loongarch/kvm/vcpu.c | 93 ++-
  arch/loongarch/kvm/vm.c   | 11 
  4 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/arch/loongarch/include/asm/kvm_host.h 
b/arch/loongarch/include/asm/kvm_host.h
index 2d62f7b0d377..3ba16ef1fe69 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -64,6 +64,30 @@ struct kvm_world_switch {

  #define MAX_PGTABLE_LEVELS 4

+/*
+ * Physical cpu id is used for interrupt routing, there are different
+ * definitions about physical cpuid on different hardwares.
+ *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
+ *  For IPI HW, max dest CPUID size 1024
+ *  For extioi interrupt controller, max dest CPUID size is 256
+ *  For MSI interrupt controller, max supported CPUID size is 65536
+ *
+ * Currently max CPUID is defined as 256 for KVM hypervisor, in future
+ * it will be expanded to 4096, including 16 packages at most. And every
+ * package supports at most 256 vcpus
+ */
+#define KVM_MAX_PHYID  256
+
+struct kvm_phyid_info {
+   struct kvm_vcpu *vcpu;
+   boolenabled;
+};
+
+struct kvm_phyid_map {
+   int max_phyid;
+   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
+};
+
  struct kvm_arch {
 /* Guest physical mm */
 kvm_pte_t *pgd;
@@ -71,6 +95,8 @@ struct kvm_arch {
 unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
 unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
 unsigned int  root_level;
+   spinlock_tphyid_map_lock;
+   struct kvm_phyid_map  *phyid_map;

 s64 time_offset;
 struct kvm_context __percpu *vmcs;
diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
b/arch/loongarch/include/asm/kvm_vcpu.h
index 0cb4fdb8a9b5..9f53950959da 100644
--- a/arch/loongarch/include/asm/kvm_vcpu.h
+++ b/arch/loongarch/include/asm/kvm_vcpu.h
@@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
  void kvm_restore_timer(struct kvm_vcpu *vcpu);

  int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt 
*irq);
+struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);

  /*
   * Loongarch KVM guest interrupt handling
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 3a8779065f73..b633fd28b8db 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int 
id, u64 *val)
 return 0;
  }

+static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
+{
+   int cpuid;
+   struct loongarch_csrs *csr = vcpu->arch.csr;
+   struct kvm_phyid_map  *map;
+
+   if (val >= KVM_MAX_PHYID)
+   return -EINVAL;
+
+   cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT);
+   map = vcpu->kvm->arch.phyid_map;
+   spin_lock(>kvm->arch.phyid_map_lock);
+   if (map->phys_map[cpuid].enabled) {
+   /*
+* Cpuid is already set before
+* Forbid changing different cpuid at runtime
+*/
+   if (cpuid != val) {
+   /*
+* Cpuid 0 is initial value for vcpu, maybe invalid
+* unset value for vcpu
+*/
+   if (cpuid) {
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return -EINVAL;
+   }
+   } else {
+/* Discard duplicated cpuid set */
+   spin_unlock(>kvm->arch.phyid_map_lock);
+  

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-06 Thread Huacai Chen
On Mon, May 6, 2024 at 6:05 PM maobibo  wrote:
>
>
>
> On 2024/5/6 下午5:40, Huacai Chen wrote:
> > On Mon, May 6, 2024 at 5:35 PM maobibo  wrote:
> >>
> >>
> >>
> >> On 2024/5/6 下午4:59, Huacai Chen wrote:
> >>> On Mon, May 6, 2024 at 4:18 PM maobibo  wrote:
> 
> 
> 
>  On 2024/5/6 下午3:06, Huacai Chen wrote:
> > Hi, Bibo,
> >
> > On Mon, May 6, 2024 at 2:36 PM maobibo  wrote:
> >>
> >>
> >>
> >> On 2024/5/6 上午9:49, Huacai Chen wrote:
> >>> Hi, Bibo,
> >>>
> >>> On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:
> 
>  Physical cpuid is used for interrupt routing for irqchips such as
>  ipi/msi/extioi interrupt controller. And physical cpuid is stored
>  at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
>  is created and physical cpuid of two vcpus cannot be the same.
> 
>  Different irqchips have different size declaration about physical 
>  cpuid,
>  max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max 
>  cpuid
>  supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
>  for MSI irqchip.
> 
>  The smallest value from all interrupt controllers is selected now,
>  and the max cpuid size is defines as 256 by KVM which comes from
>  extioi irqchip.
> 
>  Signed-off-by: Bibo Mao 
>  ---
>   arch/loongarch/include/asm/kvm_host.h | 26 
>   arch/loongarch/include/asm/kvm_vcpu.h |  1 +
>   arch/loongarch/kvm/vcpu.c | 93 
>  ++-
>   arch/loongarch/kvm/vm.c   | 11 
>   4 files changed, 130 insertions(+), 1 deletion(-)
> 
>  diff --git a/arch/loongarch/include/asm/kvm_host.h 
>  b/arch/loongarch/include/asm/kvm_host.h
>  index 2d62f7b0d377..3ba16ef1fe69 100644
>  --- a/arch/loongarch/include/asm/kvm_host.h
>  +++ b/arch/loongarch/include/asm/kvm_host.h
>  @@ -64,6 +64,30 @@ struct kvm_world_switch {
> 
>   #define MAX_PGTABLE_LEVELS 4
> 
>  +/*
>  + * Physical cpu id is used for interrupt routing, there are 
>  different
>  + * definitions about physical cpuid on different hardwares.
>  + *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
>  + *  For IPI HW, max dest CPUID size 1024
>  + *  For extioi interrupt controller, max dest CPUID size is 256
>  + *  For MSI interrupt controller, max supported CPUID size is 65536
>  + *
>  + * Currently max CPUID is defined as 256 for KVM hypervisor, in 
>  future
>  + * it will be expanded to 4096, including 16 packages at most. And 
>  every
>  + * package supports at most 256 vcpus
>  + */
>  +#define KVM_MAX_PHYID  256
>  +
>  +struct kvm_phyid_info {
>  +   struct kvm_vcpu *vcpu;
>  +   boolenabled;
>  +};
>  +
>  +struct kvm_phyid_map {
>  +   int max_phyid;
>  +   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
>  +};
>  +
>   struct kvm_arch {
>  /* Guest physical mm */
>  kvm_pte_t *pgd;
>  @@ -71,6 +95,8 @@ struct kvm_arch {
>  unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
>  unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
>  unsigned int  root_level;
>  +   spinlock_tphyid_map_lock;
>  +   struct kvm_phyid_map  *phyid_map;
> 
>  s64 time_offset;
>  struct kvm_context __percpu *vmcs;
>  diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
>  b/arch/loongarch/include/asm/kvm_vcpu.h
>  index 0cb4fdb8a9b5..9f53950959da 100644
>  --- a/arch/loongarch/include/asm/kvm_vcpu.h
>  +++ b/arch/loongarch/include/asm/kvm_vcpu.h
>  @@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
>   void kvm_restore_timer(struct kvm_vcpu *vcpu);
> 
>   int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct 
>  kvm_interrupt *irq);
>  +struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);
> 
>   /*
>    * Loongarch KVM guest interrupt handling
>  diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
>  index 3a8779065f73..b633fd28b8db 100644
>  --- a/arch/loongarch/kvm/vcpu.c
>  +++ b/arch/loongarch/kvm/vcpu.c
>  @@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, 
>  unsigned int id, u64 *val)
>  return 0;
>   }
> 
> 

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-06 Thread maobibo




On 2024/5/6 下午5:40, Huacai Chen wrote:

On Mon, May 6, 2024 at 5:35 PM maobibo  wrote:




On 2024/5/6 下午4:59, Huacai Chen wrote:

On Mon, May 6, 2024 at 4:18 PM maobibo  wrote:




On 2024/5/6 下午3:06, Huacai Chen wrote:

Hi, Bibo,

On Mon, May 6, 2024 at 2:36 PM maobibo  wrote:




On 2024/5/6 上午9:49, Huacai Chen wrote:

Hi, Bibo,

On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:


Physical cpuid is used for interrupt routing for irqchips such as
ipi/msi/extioi interrupt controller. And physical cpuid is stored
at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
is created and physical cpuid of two vcpus cannot be the same.

Different irqchips have different size declaration about physical cpuid,
max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
for MSI irqchip.

The smallest value from all interrupt controllers is selected now,
and the max cpuid size is defines as 256 by KVM which comes from
extioi irqchip.

Signed-off-by: Bibo Mao 
---
 arch/loongarch/include/asm/kvm_host.h | 26 
 arch/loongarch/include/asm/kvm_vcpu.h |  1 +
 arch/loongarch/kvm/vcpu.c | 93 ++-
 arch/loongarch/kvm/vm.c   | 11 
 4 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/arch/loongarch/include/asm/kvm_host.h 
b/arch/loongarch/include/asm/kvm_host.h
index 2d62f7b0d377..3ba16ef1fe69 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -64,6 +64,30 @@ struct kvm_world_switch {

 #define MAX_PGTABLE_LEVELS 4

+/*
+ * Physical cpu id is used for interrupt routing, there are different
+ * definitions about physical cpuid on different hardwares.
+ *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
+ *  For IPI HW, max dest CPUID size 1024
+ *  For extioi interrupt controller, max dest CPUID size is 256
+ *  For MSI interrupt controller, max supported CPUID size is 65536
+ *
+ * Currently max CPUID is defined as 256 for KVM hypervisor, in future
+ * it will be expanded to 4096, including 16 packages at most. And every
+ * package supports at most 256 vcpus
+ */
+#define KVM_MAX_PHYID  256
+
+struct kvm_phyid_info {
+   struct kvm_vcpu *vcpu;
+   boolenabled;
+};
+
+struct kvm_phyid_map {
+   int max_phyid;
+   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
+};
+
 struct kvm_arch {
/* Guest physical mm */
kvm_pte_t *pgd;
@@ -71,6 +95,8 @@ struct kvm_arch {
unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
unsigned int  root_level;
+   spinlock_tphyid_map_lock;
+   struct kvm_phyid_map  *phyid_map;

s64 time_offset;
struct kvm_context __percpu *vmcs;
diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
b/arch/loongarch/include/asm/kvm_vcpu.h
index 0cb4fdb8a9b5..9f53950959da 100644
--- a/arch/loongarch/include/asm/kvm_vcpu.h
+++ b/arch/loongarch/include/asm/kvm_vcpu.h
@@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
 void kvm_restore_timer(struct kvm_vcpu *vcpu);

 int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt 
*irq);
+struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);

 /*
  * Loongarch KVM guest interrupt handling
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 3a8779065f73..b633fd28b8db 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int 
id, u64 *val)
return 0;
 }

+static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
+{
+   int cpuid;
+   struct loongarch_csrs *csr = vcpu->arch.csr;
+   struct kvm_phyid_map  *map;
+
+   if (val >= KVM_MAX_PHYID)
+   return -EINVAL;
+
+   cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT);
+   map = vcpu->kvm->arch.phyid_map;
+   spin_lock(>kvm->arch.phyid_map_lock);
+   if (map->phys_map[cpuid].enabled) {
+   /*
+* Cpuid is already set before
+* Forbid changing different cpuid at runtime
+*/
+   if (cpuid != val) {
+   /*
+* Cpuid 0 is initial value for vcpu, maybe invalid
+* unset value for vcpu
+*/
+   if (cpuid) {
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return -EINVAL;
+   }
+   } else {
+/* Discard duplicated cpuid set */
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return 0;
+   }
+   }

I have changed the logic and comments when I apply, you 

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-06 Thread Huacai Chen
On Mon, May 6, 2024 at 5:35 PM maobibo  wrote:
>
>
>
> On 2024/5/6 下午4:59, Huacai Chen wrote:
> > On Mon, May 6, 2024 at 4:18 PM maobibo  wrote:
> >>
> >>
> >>
> >> On 2024/5/6 下午3:06, Huacai Chen wrote:
> >>> Hi, Bibo,
> >>>
> >>> On Mon, May 6, 2024 at 2:36 PM maobibo  wrote:
> 
> 
> 
>  On 2024/5/6 上午9:49, Huacai Chen wrote:
> > Hi, Bibo,
> >
> > On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:
> >>
> >> Physical cpuid is used for interrupt routing for irqchips such as
> >> ipi/msi/extioi interrupt controller. And physical cpuid is stored
> >> at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
> >> is created and physical cpuid of two vcpus cannot be the same.
> >>
> >> Different irqchips have different size declaration about physical 
> >> cpuid,
> >> max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
> >> supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
> >> for MSI irqchip.
> >>
> >> The smallest value from all interrupt controllers is selected now,
> >> and the max cpuid size is defines as 256 by KVM which comes from
> >> extioi irqchip.
> >>
> >> Signed-off-by: Bibo Mao 
> >> ---
> >> arch/loongarch/include/asm/kvm_host.h | 26 
> >> arch/loongarch/include/asm/kvm_vcpu.h |  1 +
> >> arch/loongarch/kvm/vcpu.c | 93 
> >> ++-
> >> arch/loongarch/kvm/vm.c   | 11 
> >> 4 files changed, 130 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/arch/loongarch/include/asm/kvm_host.h 
> >> b/arch/loongarch/include/asm/kvm_host.h
> >> index 2d62f7b0d377..3ba16ef1fe69 100644
> >> --- a/arch/loongarch/include/asm/kvm_host.h
> >> +++ b/arch/loongarch/include/asm/kvm_host.h
> >> @@ -64,6 +64,30 @@ struct kvm_world_switch {
> >>
> >> #define MAX_PGTABLE_LEVELS 4
> >>
> >> +/*
> >> + * Physical cpu id is used for interrupt routing, there are different
> >> + * definitions about physical cpuid on different hardwares.
> >> + *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
> >> + *  For IPI HW, max dest CPUID size 1024
> >> + *  For extioi interrupt controller, max dest CPUID size is 256
> >> + *  For MSI interrupt controller, max supported CPUID size is 65536
> >> + *
> >> + * Currently max CPUID is defined as 256 for KVM hypervisor, in future
> >> + * it will be expanded to 4096, including 16 packages at most. And 
> >> every
> >> + * package supports at most 256 vcpus
> >> + */
> >> +#define KVM_MAX_PHYID  256
> >> +
> >> +struct kvm_phyid_info {
> >> +   struct kvm_vcpu *vcpu;
> >> +   boolenabled;
> >> +};
> >> +
> >> +struct kvm_phyid_map {
> >> +   int max_phyid;
> >> +   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
> >> +};
> >> +
> >> struct kvm_arch {
> >>/* Guest physical mm */
> >>kvm_pte_t *pgd;
> >> @@ -71,6 +95,8 @@ struct kvm_arch {
> >>unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
> >>unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
> >>unsigned int  root_level;
> >> +   spinlock_tphyid_map_lock;
> >> +   struct kvm_phyid_map  *phyid_map;
> >>
> >>s64 time_offset;
> >>struct kvm_context __percpu *vmcs;
> >> diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
> >> b/arch/loongarch/include/asm/kvm_vcpu.h
> >> index 0cb4fdb8a9b5..9f53950959da 100644
> >> --- a/arch/loongarch/include/asm/kvm_vcpu.h
> >> +++ b/arch/loongarch/include/asm/kvm_vcpu.h
> >> @@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
> >> void kvm_restore_timer(struct kvm_vcpu *vcpu);
> >>
> >> int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct 
> >> kvm_interrupt *irq);
> >> +struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);
> >>
> >> /*
> >>  * Loongarch KVM guest interrupt handling
> >> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
> >> index 3a8779065f73..b633fd28b8db 100644
> >> --- a/arch/loongarch/kvm/vcpu.c
> >> +++ b/arch/loongarch/kvm/vcpu.c
> >> @@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, 
> >> unsigned int id, u64 *val)
> >>return 0;
> >> }
> >>
> >> +static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
> >> +{
> >> +   int cpuid;
> >> +   struct loongarch_csrs *csr = vcpu->arch.csr;
> >> +   struct kvm_phyid_map  *map;
> >> +
> >> +   if (val >= KVM_MAX_PHYID)
> >> +   return -EINVAL;
> >> +
> >> +   cpuid = kvm_read_sw_gcsr(csr, 

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-06 Thread maobibo




On 2024/5/6 下午4:59, Huacai Chen wrote:

On Mon, May 6, 2024 at 4:18 PM maobibo  wrote:




On 2024/5/6 下午3:06, Huacai Chen wrote:

Hi, Bibo,

On Mon, May 6, 2024 at 2:36 PM maobibo  wrote:




On 2024/5/6 上午9:49, Huacai Chen wrote:

Hi, Bibo,

On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:


Physical cpuid is used for interrupt routing for irqchips such as
ipi/msi/extioi interrupt controller. And physical cpuid is stored
at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
is created and physical cpuid of two vcpus cannot be the same.

Different irqchips have different size declaration about physical cpuid,
max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
for MSI irqchip.

The smallest value from all interrupt controllers is selected now,
and the max cpuid size is defines as 256 by KVM which comes from
extioi irqchip.

Signed-off-by: Bibo Mao 
---
arch/loongarch/include/asm/kvm_host.h | 26 
arch/loongarch/include/asm/kvm_vcpu.h |  1 +
arch/loongarch/kvm/vcpu.c | 93 ++-
arch/loongarch/kvm/vm.c   | 11 
4 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/arch/loongarch/include/asm/kvm_host.h 
b/arch/loongarch/include/asm/kvm_host.h
index 2d62f7b0d377..3ba16ef1fe69 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -64,6 +64,30 @@ struct kvm_world_switch {

#define MAX_PGTABLE_LEVELS 4

+/*
+ * Physical cpu id is used for interrupt routing, there are different
+ * definitions about physical cpuid on different hardwares.
+ *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
+ *  For IPI HW, max dest CPUID size 1024
+ *  For extioi interrupt controller, max dest CPUID size is 256
+ *  For MSI interrupt controller, max supported CPUID size is 65536
+ *
+ * Currently max CPUID is defined as 256 for KVM hypervisor, in future
+ * it will be expanded to 4096, including 16 packages at most. And every
+ * package supports at most 256 vcpus
+ */
+#define KVM_MAX_PHYID  256
+
+struct kvm_phyid_info {
+   struct kvm_vcpu *vcpu;
+   boolenabled;
+};
+
+struct kvm_phyid_map {
+   int max_phyid;
+   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
+};
+
struct kvm_arch {
   /* Guest physical mm */
   kvm_pte_t *pgd;
@@ -71,6 +95,8 @@ struct kvm_arch {
   unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
   unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
   unsigned int  root_level;
+   spinlock_tphyid_map_lock;
+   struct kvm_phyid_map  *phyid_map;

   s64 time_offset;
   struct kvm_context __percpu *vmcs;
diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
b/arch/loongarch/include/asm/kvm_vcpu.h
index 0cb4fdb8a9b5..9f53950959da 100644
--- a/arch/loongarch/include/asm/kvm_vcpu.h
+++ b/arch/loongarch/include/asm/kvm_vcpu.h
@@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
void kvm_restore_timer(struct kvm_vcpu *vcpu);

int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt 
*irq);
+struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);

/*
 * Loongarch KVM guest interrupt handling
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 3a8779065f73..b633fd28b8db 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int 
id, u64 *val)
   return 0;
}

+static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
+{
+   int cpuid;
+   struct loongarch_csrs *csr = vcpu->arch.csr;
+   struct kvm_phyid_map  *map;
+
+   if (val >= KVM_MAX_PHYID)
+   return -EINVAL;
+
+   cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT);
+   map = vcpu->kvm->arch.phyid_map;
+   spin_lock(>kvm->arch.phyid_map_lock);
+   if (map->phys_map[cpuid].enabled) {
+   /*
+* Cpuid is already set before
+* Forbid changing different cpuid at runtime
+*/
+   if (cpuid != val) {
+   /*
+* Cpuid 0 is initial value for vcpu, maybe invalid
+* unset value for vcpu
+*/
+   if (cpuid) {
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return -EINVAL;
+   }
+   } else {
+/* Discard duplicated cpuid set */
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return 0;
+   }
+   }

I have changed the logic and comments when I apply, you can double
check whether it is correct.

I checkout the latest version, the modification in function

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-06 Thread Huacai Chen
On Mon, May 6, 2024 at 4:18 PM maobibo  wrote:
>
>
>
> On 2024/5/6 下午3:06, Huacai Chen wrote:
> > Hi, Bibo,
> >
> > On Mon, May 6, 2024 at 2:36 PM maobibo  wrote:
> >>
> >>
> >>
> >> On 2024/5/6 上午9:49, Huacai Chen wrote:
> >>> Hi, Bibo,
> >>>
> >>> On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:
> 
>  Physical cpuid is used for interrupt routing for irqchips such as
>  ipi/msi/extioi interrupt controller. And physical cpuid is stored
>  at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
>  is created and physical cpuid of two vcpus cannot be the same.
> 
>  Different irqchips have different size declaration about physical cpuid,
>  max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
>  supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
>  for MSI irqchip.
> 
>  The smallest value from all interrupt controllers is selected now,
>  and the max cpuid size is defines as 256 by KVM which comes from
>  extioi irqchip.
> 
>  Signed-off-by: Bibo Mao 
>  ---
> arch/loongarch/include/asm/kvm_host.h | 26 
> arch/loongarch/include/asm/kvm_vcpu.h |  1 +
> arch/loongarch/kvm/vcpu.c | 93 ++-
> arch/loongarch/kvm/vm.c   | 11 
> 4 files changed, 130 insertions(+), 1 deletion(-)
> 
>  diff --git a/arch/loongarch/include/asm/kvm_host.h 
>  b/arch/loongarch/include/asm/kvm_host.h
>  index 2d62f7b0d377..3ba16ef1fe69 100644
>  --- a/arch/loongarch/include/asm/kvm_host.h
>  +++ b/arch/loongarch/include/asm/kvm_host.h
>  @@ -64,6 +64,30 @@ struct kvm_world_switch {
> 
> #define MAX_PGTABLE_LEVELS 4
> 
>  +/*
>  + * Physical cpu id is used for interrupt routing, there are different
>  + * definitions about physical cpuid on different hardwares.
>  + *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
>  + *  For IPI HW, max dest CPUID size 1024
>  + *  For extioi interrupt controller, max dest CPUID size is 256
>  + *  For MSI interrupt controller, max supported CPUID size is 65536
>  + *
>  + * Currently max CPUID is defined as 256 for KVM hypervisor, in future
>  + * it will be expanded to 4096, including 16 packages at most. And every
>  + * package supports at most 256 vcpus
>  + */
>  +#define KVM_MAX_PHYID  256
>  +
>  +struct kvm_phyid_info {
>  +   struct kvm_vcpu *vcpu;
>  +   boolenabled;
>  +};
>  +
>  +struct kvm_phyid_map {
>  +   int max_phyid;
>  +   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
>  +};
>  +
> struct kvm_arch {
>    /* Guest physical mm */
>    kvm_pte_t *pgd;
>  @@ -71,6 +95,8 @@ struct kvm_arch {
>    unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
>    unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
>    unsigned int  root_level;
>  +   spinlock_tphyid_map_lock;
>  +   struct kvm_phyid_map  *phyid_map;
> 
>    s64 time_offset;
>    struct kvm_context __percpu *vmcs;
>  diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
>  b/arch/loongarch/include/asm/kvm_vcpu.h
>  index 0cb4fdb8a9b5..9f53950959da 100644
>  --- a/arch/loongarch/include/asm/kvm_vcpu.h
>  +++ b/arch/loongarch/include/asm/kvm_vcpu.h
>  @@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
> void kvm_restore_timer(struct kvm_vcpu *vcpu);
> 
> int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct 
>  kvm_interrupt *irq);
>  +struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);
> 
> /*
>  * Loongarch KVM guest interrupt handling
>  diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
>  index 3a8779065f73..b633fd28b8db 100644
>  --- a/arch/loongarch/kvm/vcpu.c
>  +++ b/arch/loongarch/kvm/vcpu.c
>  @@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, 
>  unsigned int id, u64 *val)
>    return 0;
> }
> 
>  +static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
>  +{
>  +   int cpuid;
>  +   struct loongarch_csrs *csr = vcpu->arch.csr;
>  +   struct kvm_phyid_map  *map;
>  +
>  +   if (val >= KVM_MAX_PHYID)
>  +   return -EINVAL;
>  +
>  +   cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT);
>  +   map = vcpu->kvm->arch.phyid_map;
>  +   spin_lock(>kvm->arch.phyid_map_lock);
>  +   if (map->phys_map[cpuid].enabled) {
>  +   /*
>  +* Cpuid is already set before
>  +* Forbid changing different cpuid at runtime
>  +*/
>  +   if (cpuid != val) {
>  

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-06 Thread maobibo




On 2024/5/6 下午3:06, Huacai Chen wrote:

Hi, Bibo,

On Mon, May 6, 2024 at 2:36 PM maobibo  wrote:




On 2024/5/6 上午9:49, Huacai Chen wrote:

Hi, Bibo,

On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:


Physical cpuid is used for interrupt routing for irqchips such as
ipi/msi/extioi interrupt controller. And physical cpuid is stored
at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
is created and physical cpuid of two vcpus cannot be the same.

Different irqchips have different size declaration about physical cpuid,
max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
for MSI irqchip.

The smallest value from all interrupt controllers is selected now,
and the max cpuid size is defines as 256 by KVM which comes from
extioi irqchip.

Signed-off-by: Bibo Mao 
---
   arch/loongarch/include/asm/kvm_host.h | 26 
   arch/loongarch/include/asm/kvm_vcpu.h |  1 +
   arch/loongarch/kvm/vcpu.c | 93 ++-
   arch/loongarch/kvm/vm.c   | 11 
   4 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/arch/loongarch/include/asm/kvm_host.h 
b/arch/loongarch/include/asm/kvm_host.h
index 2d62f7b0d377..3ba16ef1fe69 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -64,6 +64,30 @@ struct kvm_world_switch {

   #define MAX_PGTABLE_LEVELS 4

+/*
+ * Physical cpu id is used for interrupt routing, there are different
+ * definitions about physical cpuid on different hardwares.
+ *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
+ *  For IPI HW, max dest CPUID size 1024
+ *  For extioi interrupt controller, max dest CPUID size is 256
+ *  For MSI interrupt controller, max supported CPUID size is 65536
+ *
+ * Currently max CPUID is defined as 256 for KVM hypervisor, in future
+ * it will be expanded to 4096, including 16 packages at most. And every
+ * package supports at most 256 vcpus
+ */
+#define KVM_MAX_PHYID  256
+
+struct kvm_phyid_info {
+   struct kvm_vcpu *vcpu;
+   boolenabled;
+};
+
+struct kvm_phyid_map {
+   int max_phyid;
+   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
+};
+
   struct kvm_arch {
  /* Guest physical mm */
  kvm_pte_t *pgd;
@@ -71,6 +95,8 @@ struct kvm_arch {
  unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
  unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
  unsigned int  root_level;
+   spinlock_tphyid_map_lock;
+   struct kvm_phyid_map  *phyid_map;

  s64 time_offset;
  struct kvm_context __percpu *vmcs;
diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
b/arch/loongarch/include/asm/kvm_vcpu.h
index 0cb4fdb8a9b5..9f53950959da 100644
--- a/arch/loongarch/include/asm/kvm_vcpu.h
+++ b/arch/loongarch/include/asm/kvm_vcpu.h
@@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
   void kvm_restore_timer(struct kvm_vcpu *vcpu);

   int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt 
*irq);
+struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);

   /*
* Loongarch KVM guest interrupt handling
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 3a8779065f73..b633fd28b8db 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int 
id, u64 *val)
  return 0;
   }

+static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
+{
+   int cpuid;
+   struct loongarch_csrs *csr = vcpu->arch.csr;
+   struct kvm_phyid_map  *map;
+
+   if (val >= KVM_MAX_PHYID)
+   return -EINVAL;
+
+   cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT);
+   map = vcpu->kvm->arch.phyid_map;
+   spin_lock(>kvm->arch.phyid_map_lock);
+   if (map->phys_map[cpuid].enabled) {
+   /*
+* Cpuid is already set before
+* Forbid changing different cpuid at runtime
+*/
+   if (cpuid != val) {
+   /*
+* Cpuid 0 is initial value for vcpu, maybe invalid
+* unset value for vcpu
+*/
+   if (cpuid) {
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return -EINVAL;
+   }
+   } else {
+/* Discard duplicated cpuid set */
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return 0;
+   }
+   }

I have changed the logic and comments when I apply, you can double
check whether it is correct.

I checkout the latest version, the modification in function
kvm_set_cpuid() is good for me.

Now the modified version is like this:

+ if (map->phys_map[cpuid].enabled) {
+ /* 

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-06 Thread Huacai Chen
Hi, Bibo,

On Mon, May 6, 2024 at 2:36 PM maobibo  wrote:
>
>
>
> On 2024/5/6 上午9:49, Huacai Chen wrote:
> > Hi, Bibo,
> >
> > On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:
> >>
> >> Physical cpuid is used for interrupt routing for irqchips such as
> >> ipi/msi/extioi interrupt controller. And physical cpuid is stored
> >> at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
> >> is created and physical cpuid of two vcpus cannot be the same.
> >>
> >> Different irqchips have different size declaration about physical cpuid,
> >> max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
> >> supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
> >> for MSI irqchip.
> >>
> >> The smallest value from all interrupt controllers is selected now,
> >> and the max cpuid size is defines as 256 by KVM which comes from
> >> extioi irqchip.
> >>
> >> Signed-off-by: Bibo Mao 
> >> ---
> >>   arch/loongarch/include/asm/kvm_host.h | 26 
> >>   arch/loongarch/include/asm/kvm_vcpu.h |  1 +
> >>   arch/loongarch/kvm/vcpu.c | 93 ++-
> >>   arch/loongarch/kvm/vm.c   | 11 
> >>   4 files changed, 130 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/arch/loongarch/include/asm/kvm_host.h 
> >> b/arch/loongarch/include/asm/kvm_host.h
> >> index 2d62f7b0d377..3ba16ef1fe69 100644
> >> --- a/arch/loongarch/include/asm/kvm_host.h
> >> +++ b/arch/loongarch/include/asm/kvm_host.h
> >> @@ -64,6 +64,30 @@ struct kvm_world_switch {
> >>
> >>   #define MAX_PGTABLE_LEVELS 4
> >>
> >> +/*
> >> + * Physical cpu id is used for interrupt routing, there are different
> >> + * definitions about physical cpuid on different hardwares.
> >> + *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
> >> + *  For IPI HW, max dest CPUID size 1024
> >> + *  For extioi interrupt controller, max dest CPUID size is 256
> >> + *  For MSI interrupt controller, max supported CPUID size is 65536
> >> + *
> >> + * Currently max CPUID is defined as 256 for KVM hypervisor, in future
> >> + * it will be expanded to 4096, including 16 packages at most. And every
> >> + * package supports at most 256 vcpus
> >> + */
> >> +#define KVM_MAX_PHYID  256
> >> +
> >> +struct kvm_phyid_info {
> >> +   struct kvm_vcpu *vcpu;
> >> +   boolenabled;
> >> +};
> >> +
> >> +struct kvm_phyid_map {
> >> +   int max_phyid;
> >> +   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
> >> +};
> >> +
> >>   struct kvm_arch {
> >>  /* Guest physical mm */
> >>  kvm_pte_t *pgd;
> >> @@ -71,6 +95,8 @@ struct kvm_arch {
> >>  unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
> >>  unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
> >>  unsigned int  root_level;
> >> +   spinlock_tphyid_map_lock;
> >> +   struct kvm_phyid_map  *phyid_map;
> >>
> >>  s64 time_offset;
> >>  struct kvm_context __percpu *vmcs;
> >> diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
> >> b/arch/loongarch/include/asm/kvm_vcpu.h
> >> index 0cb4fdb8a9b5..9f53950959da 100644
> >> --- a/arch/loongarch/include/asm/kvm_vcpu.h
> >> +++ b/arch/loongarch/include/asm/kvm_vcpu.h
> >> @@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
> >>   void kvm_restore_timer(struct kvm_vcpu *vcpu);
> >>
> >>   int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt 
> >> *irq);
> >> +struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);
> >>
> >>   /*
> >>* Loongarch KVM guest interrupt handling
> >> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
> >> index 3a8779065f73..b633fd28b8db 100644
> >> --- a/arch/loongarch/kvm/vcpu.c
> >> +++ b/arch/loongarch/kvm/vcpu.c
> >> @@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, 
> >> unsigned int id, u64 *val)
> >>  return 0;
> >>   }
> >>
> >> +static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
> >> +{
> >> +   int cpuid;
> >> +   struct loongarch_csrs *csr = vcpu->arch.csr;
> >> +   struct kvm_phyid_map  *map;
> >> +
> >> +   if (val >= KVM_MAX_PHYID)
> >> +   return -EINVAL;
> >> +
> >> +   cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT);
> >> +   map = vcpu->kvm->arch.phyid_map;
> >> +   spin_lock(>kvm->arch.phyid_map_lock);
> >> +   if (map->phys_map[cpuid].enabled) {
> >> +   /*
> >> +* Cpuid is already set before
> >> +* Forbid changing different cpuid at runtime
> >> +*/
> >> +   if (cpuid != val) {
> >> +   /*
> >> +* Cpuid 0 is initial value for vcpu, maybe invalid
> >> +* unset value for vcpu
> >> +*/
> >> +   if (cpuid) {
> >> +   
> >> spin_unlock(>kvm->arch.phyid_map_lock);
> >> +   return 

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-06 Thread maobibo




On 2024/5/6 上午9:49, Huacai Chen wrote:

Hi, Bibo,

On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:


Physical cpuid is used for interrupt routing for irqchips such as
ipi/msi/extioi interrupt controller. And physical cpuid is stored
at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
is created and physical cpuid of two vcpus cannot be the same.

Different irqchips have different size declaration about physical cpuid,
max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
for MSI irqchip.

The smallest value from all interrupt controllers is selected now,
and the max cpuid size is defines as 256 by KVM which comes from
extioi irqchip.

Signed-off-by: Bibo Mao 
---
  arch/loongarch/include/asm/kvm_host.h | 26 
  arch/loongarch/include/asm/kvm_vcpu.h |  1 +
  arch/loongarch/kvm/vcpu.c | 93 ++-
  arch/loongarch/kvm/vm.c   | 11 
  4 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/arch/loongarch/include/asm/kvm_host.h 
b/arch/loongarch/include/asm/kvm_host.h
index 2d62f7b0d377..3ba16ef1fe69 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -64,6 +64,30 @@ struct kvm_world_switch {

  #define MAX_PGTABLE_LEVELS 4

+/*
+ * Physical cpu id is used for interrupt routing, there are different
+ * definitions about physical cpuid on different hardwares.
+ *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
+ *  For IPI HW, max dest CPUID size 1024
+ *  For extioi interrupt controller, max dest CPUID size is 256
+ *  For MSI interrupt controller, max supported CPUID size is 65536
+ *
+ * Currently max CPUID is defined as 256 for KVM hypervisor, in future
+ * it will be expanded to 4096, including 16 packages at most. And every
+ * package supports at most 256 vcpus
+ */
+#define KVM_MAX_PHYID  256
+
+struct kvm_phyid_info {
+   struct kvm_vcpu *vcpu;
+   boolenabled;
+};
+
+struct kvm_phyid_map {
+   int max_phyid;
+   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
+};
+
  struct kvm_arch {
 /* Guest physical mm */
 kvm_pte_t *pgd;
@@ -71,6 +95,8 @@ struct kvm_arch {
 unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
 unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
 unsigned int  root_level;
+   spinlock_tphyid_map_lock;
+   struct kvm_phyid_map  *phyid_map;

 s64 time_offset;
 struct kvm_context __percpu *vmcs;
diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
b/arch/loongarch/include/asm/kvm_vcpu.h
index 0cb4fdb8a9b5..9f53950959da 100644
--- a/arch/loongarch/include/asm/kvm_vcpu.h
+++ b/arch/loongarch/include/asm/kvm_vcpu.h
@@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
  void kvm_restore_timer(struct kvm_vcpu *vcpu);

  int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt 
*irq);
+struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);

  /*
   * Loongarch KVM guest interrupt handling
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 3a8779065f73..b633fd28b8db 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int 
id, u64 *val)
 return 0;
  }

+static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
+{
+   int cpuid;
+   struct loongarch_csrs *csr = vcpu->arch.csr;
+   struct kvm_phyid_map  *map;
+
+   if (val >= KVM_MAX_PHYID)
+   return -EINVAL;
+
+   cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT);
+   map = vcpu->kvm->arch.phyid_map;
+   spin_lock(>kvm->arch.phyid_map_lock);
+   if (map->phys_map[cpuid].enabled) {
+   /*
+* Cpuid is already set before
+* Forbid changing different cpuid at runtime
+*/
+   if (cpuid != val) {
+   /*
+* Cpuid 0 is initial value for vcpu, maybe invalid
+* unset value for vcpu
+*/
+   if (cpuid) {
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return -EINVAL;
+   }
+   } else {
+/* Discard duplicated cpuid set */
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return 0;
+   }
+   }

I have changed the logic and comments when I apply, you can double
check whether it is correct.
I checkout the latest version, the modification in function 
kvm_set_cpuid() is good for me.



+
+   if (map->phys_map[val].enabled) {
+   /*
+* New cpuid is already set with other vcpu
+* Forbid sharing the same cpuid between different vcpus
+   

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-05 Thread maobibo

Huacai,

Many thanks for reviewing pv ipi patchset.
And I reply inline.

On 2024/5/6 上午9:49, Huacai Chen wrote:

Hi, Bibo,

On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:


Physical cpuid is used for interrupt routing for irqchips such as
ipi/msi/extioi interrupt controller. And physical cpuid is stored
at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
is created and physical cpuid of two vcpus cannot be the same.

Different irqchips have different size declaration about physical cpuid,
max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
for MSI irqchip.

The smallest value from all interrupt controllers is selected now,
and the max cpuid size is defines as 256 by KVM which comes from
extioi irqchip.

Signed-off-by: Bibo Mao 
---
  arch/loongarch/include/asm/kvm_host.h | 26 
  arch/loongarch/include/asm/kvm_vcpu.h |  1 +
  arch/loongarch/kvm/vcpu.c | 93 ++-
  arch/loongarch/kvm/vm.c   | 11 
  4 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/arch/loongarch/include/asm/kvm_host.h 
b/arch/loongarch/include/asm/kvm_host.h
index 2d62f7b0d377..3ba16ef1fe69 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -64,6 +64,30 @@ struct kvm_world_switch {

  #define MAX_PGTABLE_LEVELS 4

+/*
+ * Physical cpu id is used for interrupt routing, there are different
+ * definitions about physical cpuid on different hardwares.
+ *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
+ *  For IPI HW, max dest CPUID size 1024
+ *  For extioi interrupt controller, max dest CPUID size is 256
+ *  For MSI interrupt controller, max supported CPUID size is 65536
+ *
+ * Currently max CPUID is defined as 256 for KVM hypervisor, in future
+ * it will be expanded to 4096, including 16 packages at most. And every
+ * package supports at most 256 vcpus
+ */
+#define KVM_MAX_PHYID  256
+
+struct kvm_phyid_info {
+   struct kvm_vcpu *vcpu;
+   boolenabled;
+};
+
+struct kvm_phyid_map {
+   int max_phyid;
+   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
+};
+
  struct kvm_arch {
 /* Guest physical mm */
 kvm_pte_t *pgd;
@@ -71,6 +95,8 @@ struct kvm_arch {
 unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
 unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
 unsigned int  root_level;
+   spinlock_tphyid_map_lock;
+   struct kvm_phyid_map  *phyid_map;

 s64 time_offset;
 struct kvm_context __percpu *vmcs;
diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
b/arch/loongarch/include/asm/kvm_vcpu.h
index 0cb4fdb8a9b5..9f53950959da 100644
--- a/arch/loongarch/include/asm/kvm_vcpu.h
+++ b/arch/loongarch/include/asm/kvm_vcpu.h
@@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
  void kvm_restore_timer(struct kvm_vcpu *vcpu);

  int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt 
*irq);
+struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);

  /*
   * Loongarch KVM guest interrupt handling
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 3a8779065f73..b633fd28b8db 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int 
id, u64 *val)
 return 0;
  }

+static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
+{
+   int cpuid;
+   struct loongarch_csrs *csr = vcpu->arch.csr;
+   struct kvm_phyid_map  *map;
+
+   if (val >= KVM_MAX_PHYID)
+   return -EINVAL;
+
+   cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT);
+   map = vcpu->kvm->arch.phyid_map;
+   spin_lock(>kvm->arch.phyid_map_lock);
+   if (map->phys_map[cpuid].enabled) {
+   /*
+* Cpuid is already set before
+* Forbid changing different cpuid at runtime
+*/
+   if (cpuid != val) {
+   /*
+* Cpuid 0 is initial value for vcpu, maybe invalid
+* unset value for vcpu
+*/
+   if (cpuid) {
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return -EINVAL;
+   }
+   } else {
+/* Discard duplicated cpuid set */
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return 0;
+   }
+   }

I have changed the logic and comments when I apply, you can double
check whether it is correct.

Will do.




+
+   if (map->phys_map[val].enabled) {
+   /*
+* New cpuid is already set with other vcpu
+* Forbid sharing the same cpuid between different vcpus
+*/
+   

Re: [PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-05-05 Thread Huacai Chen
Hi, Bibo,

On Sun, Apr 28, 2024 at 6:05 PM Bibo Mao  wrote:
>
> Physical cpuid is used for interrupt routing for irqchips such as
> ipi/msi/extioi interrupt controller. And physical cpuid is stored
> at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
> is created and physical cpuid of two vcpus cannot be the same.
>
> Different irqchips have different size declaration about physical cpuid,
> max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
> supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
> for MSI irqchip.
>
> The smallest value from all interrupt controllers is selected now,
> and the max cpuid size is defines as 256 by KVM which comes from
> extioi irqchip.
>
> Signed-off-by: Bibo Mao 
> ---
>  arch/loongarch/include/asm/kvm_host.h | 26 
>  arch/loongarch/include/asm/kvm_vcpu.h |  1 +
>  arch/loongarch/kvm/vcpu.c | 93 ++-
>  arch/loongarch/kvm/vm.c   | 11 
>  4 files changed, 130 insertions(+), 1 deletion(-)
>
> diff --git a/arch/loongarch/include/asm/kvm_host.h 
> b/arch/loongarch/include/asm/kvm_host.h
> index 2d62f7b0d377..3ba16ef1fe69 100644
> --- a/arch/loongarch/include/asm/kvm_host.h
> +++ b/arch/loongarch/include/asm/kvm_host.h
> @@ -64,6 +64,30 @@ struct kvm_world_switch {
>
>  #define MAX_PGTABLE_LEVELS 4
>
> +/*
> + * Physical cpu id is used for interrupt routing, there are different
> + * definitions about physical cpuid on different hardwares.
> + *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
> + *  For IPI HW, max dest CPUID size 1024
> + *  For extioi interrupt controller, max dest CPUID size is 256
> + *  For MSI interrupt controller, max supported CPUID size is 65536
> + *
> + * Currently max CPUID is defined as 256 for KVM hypervisor, in future
> + * it will be expanded to 4096, including 16 packages at most. And every
> + * package supports at most 256 vcpus
> + */
> +#define KVM_MAX_PHYID  256
> +
> +struct kvm_phyid_info {
> +   struct kvm_vcpu *vcpu;
> +   boolenabled;
> +};
> +
> +struct kvm_phyid_map {
> +   int max_phyid;
> +   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
> +};
> +
>  struct kvm_arch {
> /* Guest physical mm */
> kvm_pte_t *pgd;
> @@ -71,6 +95,8 @@ struct kvm_arch {
> unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
> unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
> unsigned int  root_level;
> +   spinlock_tphyid_map_lock;
> +   struct kvm_phyid_map  *phyid_map;
>
> s64 time_offset;
> struct kvm_context __percpu *vmcs;
> diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
> b/arch/loongarch/include/asm/kvm_vcpu.h
> index 0cb4fdb8a9b5..9f53950959da 100644
> --- a/arch/loongarch/include/asm/kvm_vcpu.h
> +++ b/arch/loongarch/include/asm/kvm_vcpu.h
> @@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
>  void kvm_restore_timer(struct kvm_vcpu *vcpu);
>
>  int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt 
> *irq);
> +struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);
>
>  /*
>   * Loongarch KVM guest interrupt handling
> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
> index 3a8779065f73..b633fd28b8db 100644
> --- a/arch/loongarch/kvm/vcpu.c
> +++ b/arch/loongarch/kvm/vcpu.c
> @@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned 
> int id, u64 *val)
> return 0;
>  }
>
> +static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
> +{
> +   int cpuid;
> +   struct loongarch_csrs *csr = vcpu->arch.csr;
> +   struct kvm_phyid_map  *map;
> +
> +   if (val >= KVM_MAX_PHYID)
> +   return -EINVAL;
> +
> +   cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT);
> +   map = vcpu->kvm->arch.phyid_map;
> +   spin_lock(>kvm->arch.phyid_map_lock);
> +   if (map->phys_map[cpuid].enabled) {
> +   /*
> +* Cpuid is already set before
> +* Forbid changing different cpuid at runtime
> +*/
> +   if (cpuid != val) {
> +   /*
> +* Cpuid 0 is initial value for vcpu, maybe invalid
> +* unset value for vcpu
> +*/
> +   if (cpuid) {
> +   spin_unlock(>kvm->arch.phyid_map_lock);
> +   return -EINVAL;
> +   }
> +   } else {
> +/* Discard duplicated cpuid set */
> +   spin_unlock(>kvm->arch.phyid_map_lock);
> +   return 0;
> +   }
> +   }
I have changed the logic and comments when I apply, you can double
check whether it is correct.

> +
> +   if (map->phys_map[val].enabled) {
> +   /*
> +* New cpuid is already set with other vcpu
> 

[PATCH v8 4/6] LoongArch: KVM: Add vcpu search support from physical cpuid

2024-04-28 Thread Bibo Mao
Physical cpuid is used for interrupt routing for irqchips such as
ipi/msi/extioi interrupt controller. And physical cpuid is stored
at CSR register LOONGARCH_CSR_CPUID, it can not be changed once vcpu
is created and physical cpuid of two vcpus cannot be the same.

Different irqchips have different size declaration about physical cpuid,
max cpuid value for CSR LOONGARCH_CSR_CPUID on 3A5000 is 512, max cpuid
supported by IPI hardware is 1024, 256 for extioi irqchip, and 65536
for MSI irqchip.

The smallest value from all interrupt controllers is selected now,
and the max cpuid size is defines as 256 by KVM which comes from
extioi irqchip.

Signed-off-by: Bibo Mao 
---
 arch/loongarch/include/asm/kvm_host.h | 26 
 arch/loongarch/include/asm/kvm_vcpu.h |  1 +
 arch/loongarch/kvm/vcpu.c | 93 ++-
 arch/loongarch/kvm/vm.c   | 11 
 4 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/arch/loongarch/include/asm/kvm_host.h 
b/arch/loongarch/include/asm/kvm_host.h
index 2d62f7b0d377..3ba16ef1fe69 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -64,6 +64,30 @@ struct kvm_world_switch {
 
 #define MAX_PGTABLE_LEVELS 4
 
+/*
+ * Physical cpu id is used for interrupt routing, there are different
+ * definitions about physical cpuid on different hardwares.
+ *  For LOONGARCH_CSR_CPUID register, max cpuid size if 512
+ *  For IPI HW, max dest CPUID size 1024
+ *  For extioi interrupt controller, max dest CPUID size is 256
+ *  For MSI interrupt controller, max supported CPUID size is 65536
+ *
+ * Currently max CPUID is defined as 256 for KVM hypervisor, in future
+ * it will be expanded to 4096, including 16 packages at most. And every
+ * package supports at most 256 vcpus
+ */
+#define KVM_MAX_PHYID  256
+
+struct kvm_phyid_info {
+   struct kvm_vcpu *vcpu;
+   boolenabled;
+};
+
+struct kvm_phyid_map {
+   int max_phyid;
+   struct kvm_phyid_info phys_map[KVM_MAX_PHYID];
+};
+
 struct kvm_arch {
/* Guest physical mm */
kvm_pte_t *pgd;
@@ -71,6 +95,8 @@ struct kvm_arch {
unsigned long invalid_ptes[MAX_PGTABLE_LEVELS];
unsigned int  pte_shifts[MAX_PGTABLE_LEVELS];
unsigned int  root_level;
+   spinlock_tphyid_map_lock;
+   struct kvm_phyid_map  *phyid_map;
 
s64 time_offset;
struct kvm_context __percpu *vmcs;
diff --git a/arch/loongarch/include/asm/kvm_vcpu.h 
b/arch/loongarch/include/asm/kvm_vcpu.h
index 0cb4fdb8a9b5..9f53950959da 100644
--- a/arch/loongarch/include/asm/kvm_vcpu.h
+++ b/arch/loongarch/include/asm/kvm_vcpu.h
@@ -81,6 +81,7 @@ void kvm_save_timer(struct kvm_vcpu *vcpu);
 void kvm_restore_timer(struct kvm_vcpu *vcpu);
 
 int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq);
+struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid);
 
 /*
  * Loongarch KVM guest interrupt handling
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 3a8779065f73..b633fd28b8db 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -274,6 +274,95 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int 
id, u64 *val)
return 0;
 }
 
+static inline int kvm_set_cpuid(struct kvm_vcpu *vcpu, u64 val)
+{
+   int cpuid;
+   struct loongarch_csrs *csr = vcpu->arch.csr;
+   struct kvm_phyid_map  *map;
+
+   if (val >= KVM_MAX_PHYID)
+   return -EINVAL;
+
+   cpuid = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT);
+   map = vcpu->kvm->arch.phyid_map;
+   spin_lock(>kvm->arch.phyid_map_lock);
+   if (map->phys_map[cpuid].enabled) {
+   /*
+* Cpuid is already set before
+* Forbid changing different cpuid at runtime
+*/
+   if (cpuid != val) {
+   /*
+* Cpuid 0 is initial value for vcpu, maybe invalid
+* unset value for vcpu
+*/
+   if (cpuid) {
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return -EINVAL;
+   }
+   } else {
+/* Discard duplicated cpuid set */
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return 0;
+   }
+   }
+
+   if (map->phys_map[val].enabled) {
+   /*
+* New cpuid is already set with other vcpu
+* Forbid sharing the same cpuid between different vcpus
+*/
+   if (map->phys_map[val].vcpu != vcpu) {
+   spin_unlock(>kvm->arch.phyid_map_lock);
+   return -EINVAL;
+   }
+
+   /* Discard duplicated cpuid set operation*/
+   spin_unlock(>kvm->arch.phyid_map_lock);
+