[libvirt PATCH 3/5] Config some capabilities for loongarch virt machine

xianglai li posted 5 patches 2 years, 1 month ago
There is a newer version of this series
[libvirt PATCH 3/5] Config some capabilities for loongarch virt machine
Posted by xianglai li 2 years, 1 month ago
From: lixianglai <lixianglai@loongson.cn>

Config some capabilities for loongarch virt machine such as
PCI multi bus.

Signed-off-by: lixianglai <lixianglai@loongson.cn>
---
 src/qemu/qemu_capabilities.c   |  5 ++++
 src/qemu/qemu_domain.c         | 28 +++++++++++++++++
 src/qemu/qemu_domain.h         |  1 +
 src/qemu/qemu_domain_address.c | 55 ++++++++++++++++++++++++++++++++++
 src/qemu/qemu_validate.c       |  2 +-
 5 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 118d3429c3..eb84c9da7d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2080,6 +2080,11 @@ bool virQEMUCapsHasPCIMultiBus(const virDomainDef *def)
         return true;
     }
 
+    /* loongarch64 support PCI-multibus on all machine types
+     * since forever */
+    if (ARCH_IS_LOONGARCH(def->os.arch))
+        return true;
+
     return false;
 }
 
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 00e38950b6..a8f04155a3 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5635,6 +5635,11 @@ qemuDomainControllerDefPostParse(virDomainControllerDef *cont,
                     cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
                 else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
                     cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
+            } else if (ARCH_IS_LOONGARCH(def->os.arch)) {
+                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
+                    cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
+                else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
+                    cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
             }
         }
         /* forbid usb model 'qusb1' and 'qusb2' in this kind of hyperviosr */
@@ -8924,6 +8929,22 @@ qemuDomainMachineIsPSeries(const char *machine,
 }
 
 
+static bool
+qemuDomainMachineIsLoongson(const char *machine,
+                            const virArch arch)
+{
+    if (!ARCH_IS_LOONGARCH(arch))
+        return false;
+
+    if (STREQ(machine, "virt") ||
+        STRPREFIX(machine, "virt-")) {
+        return true;
+    }
+
+    return false;
+}
+
+
 static bool
 qemuDomainMachineIsMipsMalta(const char *machine,
                              const virArch arch)
@@ -9017,6 +9038,13 @@ qemuDomainIsMipsMalta(const virDomainDef *def)
 }
 
 
+bool
+qemuDomainIsLoongson(const virDomainDef *def)
+{
+    return qemuDomainMachineIsLoongson(def->os.machine, def->os.arch);
+}
+
+
 bool
 qemuDomainHasPCIRoot(const virDomainDef *def)
 {
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 1e56e50672..1bdbb9c549 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -827,6 +827,7 @@ bool qemuDomainIsS390CCW(const virDomainDef *def);
 bool qemuDomainIsARMVirt(const virDomainDef *def);
 bool qemuDomainIsRISCVVirt(const virDomainDef *def);
 bool qemuDomainIsPSeries(const virDomainDef *def);
+bool qemuDomainIsLoongson(const virDomainDef *def);
 bool qemuDomainIsMipsMalta(const virDomainDef *def);
 bool qemuDomainHasPCIRoot(const virDomainDef *def);
 bool qemuDomainHasPCIeRoot(const virDomainDef *def);
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index 099778b2a8..2a37853d56 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -2079,6 +2079,56 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDef *def,
 }
 
 
+static int
+qemuDomainValidateDevicePCISlotsLoongson(virDomainDef *def,
+                                         virDomainPCIAddressSet *addrs)
+{
+    virPCIDeviceAddress tmp_addr;
+    g_autofree char *addrStr = NULL;
+    virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCI_DEVICE;
+
+    if (addrs->nbuses) {
+        memset(&tmp_addr, 0, sizeof(tmp_addr));
+        tmp_addr.slot = 1;
+        /* pci-ohci at 00:01.0 */
+        if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0)
+            return -1;
+    }
+
+    if (def->nvideos > 0 &&
+        def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_NONE &&
+        def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_RAMFB) {
+        /* reserve slot 2 for vga device */
+        virDomainVideoDef *primaryVideo = def->videos[0];
+
+        if (virDeviceInfoPCIAddressIsWanted(&primaryVideo->info)) {
+            memset(&tmp_addr, 0, sizeof(tmp_addr));
+            tmp_addr.slot = 2;
+
+            if (!(addrStr = virPCIDeviceAddressAsString(&tmp_addr)))
+                return -1;
+            if (!virDomainPCIAddressValidate(addrs, &tmp_addr,
+                                             addrStr, flags, true))
+                return -1;
+
+            if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
+                if (qemuDomainPCIAddressReserveNextAddr(addrs,
+                                                        &primaryVideo->info) < 0) {
+                    return -1;
+                }
+            } else {
+                if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0)
+                    return -1;
+                primaryVideo->info.addr.pci = tmp_addr;
+                primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+            }
+        }
+    }
+
+    return 0;
+}
+
+
 static int
 qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def,
                                          virDomainPCIAddressSet *addrs)
@@ -2093,6 +2143,11 @@ qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def,
         return -1;
     }
 
+    if (qemuDomainIsLoongson(def) &&
+        qemuDomainValidateDevicePCISlotsLoongson(def, addrs) < 0) {
+        return -1;
+    }
+
     return 0;
 }
 
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index e475ad035e..498e76b1e7 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -100,7 +100,7 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
         switch ((virDomainFeature) i) {
         case VIR_DOMAIN_FEATURE_IOAPIC:
             if (def->features[i] != VIR_DOMAIN_IOAPIC_NONE) {
-                if (!ARCH_IS_X86(def->os.arch)) {
+                if (!ARCH_IS_X86(def->os.arch) && !ARCH_IS_LOONGARCH(def->os.arch)) {
                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                    _("The '%1$s' feature is not supported for architecture '%2$s' or machine type '%3$s'"),
                                    featureName,
-- 
2.27.0
_______________________________________________
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-leave@lists.libvirt.org
Re: [libvirt PATCH 3/5] Config some capabilities for loongarch virt machine
Posted by Andrea Bolognani 2 years, 1 month ago
On Thu, Dec 14, 2023 at 02:08:47PM +0800, xianglai li wrote:
> +++ b/src/qemu/qemu_domain.c
> @@ -5635,6 +5635,11 @@ qemuDomainControllerDefPostParse(virDomainControllerDef *cont,
>                      cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
>                  else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
>                      cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
> +            } else if (ARCH_IS_LOONGARCH(def->os.arch)) {
> +                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
> +                    cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
> +                else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
> +                    cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
>              }

I don't think you need to take into account the nec-xhci model for
loongarch. aarch64 needs it because qemu-xhci didn't exist when that
architecture was introduced, but that's not the case here so we can
keep things simpler.

I'm surprised that this code doesn't have handling for riscv64. Not
your problem, but likely an oversight that should be addressed.

> +static bool
> +qemuDomainMachineIsLoongson(const char *machine,
> +                            const virArch arch)

The appropriate name for this function would be
qemuDomainMachineIsLoongArchVirt, to match the existing Arm and
RISC-V equivalents.

> +bool
> +qemuDomainIsLoongson(const virDomainDef *def)
> +{

Same here.

> +++ b/src/qemu/qemu_domain_address.c
> @@ -2093,6 +2143,11 @@ qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def,
>          return -1;
>      }
>
> +    if (qemuDomainIsLoongson(def) &&
> +        qemuDomainValidateDevicePCISlotsLoongson(def, addrs) < 0) {
> +        return -1;
> +    }

The existing qemuDomainValidateDevicePCISlots* functions are intended
to ensure that certain devices, that historically have been assigned
to specific PCI slots by QEMU, always show up at those addresses.

We haven't needed anything like that for non-x86 architectures so
far, and I believe that loongarch doesn't need it either.

> +++ b/src/qemu/qemu_validate.c
> @@ -100,7 +100,7 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
>          switch ((virDomainFeature) i) {
>          case VIR_DOMAIN_FEATURE_IOAPIC:
>              if (def->features[i] != VIR_DOMAIN_IOAPIC_NONE) {
> -                if (!ARCH_IS_X86(def->os.arch)) {
> +                if (!ARCH_IS_X86(def->os.arch) && !ARCH_IS_LOONGARCH(def->os.arch)) {
>                      virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
>                                     _("The '%1$s' feature is not supported for architecture '%2$s' or machine type '%3$s'"),
>                                     featureName,

So does loongarch actually have ioapic support? Just making sure. I'm
surprised because apparently no other non-x86 architecture supports
it...

-- 
Andrea Bolognani / Red Hat / Virtualization
_______________________________________________
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-leave@lists.libvirt.org
Re: [libvirt PATCH 3/5] Config some capabilities for loongarch virt machine
Posted by lixianglai 2 years, 1 month ago
Hi Andrea :
> On Thu, Dec 14, 2023 at 02:08:47PM +0800, xianglai li wrote:
>> +++ b/src/qemu/qemu_domain.c
>> @@ -5635,6 +5635,11 @@ 
>> qemuDomainControllerDefPostParse(virDomainControllerDef *cont,
>> cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
>> else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
>> cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
>> + } else if (ARCH_IS_LOONGARCH(def->os.arch)) {
>> + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
>> + cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
>> + else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
>> + cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
>> }
> I don't think you need to take into account the nec-xhci model for
> loongarch. aarch64 needs it because qemu-xhci didn't exist when that
> architecture was introduced, but that's not the case here so we can
> keep things simpler.
>
> I'm surprised that this code doesn't have handling for riscv64. Not
> your problem, but likely an oversight that should be addressed.


Ok, I'll remove nec-xhci in the next version.

>> +static bool
>> +qemuDomainMachineIsLoongson(const char *machine,
>> + const virArch arch)
> The appropriate name for this function would be
> qemuDomainMachineIsLoongArchVirt, to match the existing Arm and
> RISC-V equivalents.


Ok, I'll correct that in the next version.

>> +bool
>> +qemuDomainIsLoongson(const virDomainDef *def)
>> +{
> Same here.


Ok, I'll correct that in the next version.


>> +++ b/src/qemu/qemu_domain_address.c
>> @@ -2093,6 +2143,11 @@ 
>> qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def,
>> return -1;
>> }
>>
>> + if (qemuDomainIsLoongson(def) &&
>> + qemuDomainValidateDevicePCISlotsLoongson(def, addrs) < 0) {
>> + return -1;
>> + }
> The existing qemuDomainValidateDevicePCISlots* functions are intended
> to ensure that certain devices, that historically have been assigned
> to specific PCI slots by QEMU, always show up at those addresses.
>
> We haven't needed anything like that for non-x86 architectures so
> far, and I believe that loongarch doesn't need it either.


Ok, I'll correct that in the next version.



>> +++ b/src/qemu/qemu_validate.c
>> @@ -100,7 +100,7 @@ qemuValidateDomainDefFeatures(const virDomainDef 
>> *def,
>> switch ((virDomainFeature) i) {
>> case VIR_DOMAIN_FEATURE_IOAPIC:
>> if (def->features[i] != VIR_DOMAIN_IOAPIC_NONE) {
>> - if (!ARCH_IS_X86(def->os.arch)) {
>> + if (!ARCH_IS_X86(def->os.arch) && !ARCH_IS_LOONGARCH(def->os.arch)) {
>> virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
>> _("The '%1$s' feature is not supported for architecture '%2$s' or 
>> machine type '%3$s'"),
>> featureName,
> So does loongarch actually have ioapic support? Just making sure. I'm
> surprised because apparently no other non-x86 architecture supports
> it...


Yes, loongarch does have IOAPIC, but this feature has no effect on 
loongarch at this stage, I will cut it first to simplify the committed code.

In addition, I have a question, if I understand correctly, the IOAPIC 
here should be the device interrupt controller, which is located in the 
bridge chip,

it is called IOAPIC under x86, PCH_PIC under loongarch, and GIC under arm.

The kernel_irqchip attribute of the machine parameter in qemu 
corresponding to the function VIR_DOMAIN_FEATURE_IOAPIC determines

whether the device interrupt controller is simulated in qemu or kvm. So 
arm also has such a need, but why doesn't arm add?


Thanks,

Xianglai.


>
_______________________________________________
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-leave@lists.libvirt.org
Re: [libvirt PATCH 3/5] Config some capabilities for loongarch virt machine
Posted by lixianglai 2 years, 1 month ago
Hi Andrea :
> On Thu, Dec 14, 2023 at 02:08:47PM +0800, xianglai li wrote:
>> +++ b/src/qemu/qemu_domain.c
>> @@ -5635,6 +5635,11 @@ qemuDomainControllerDefPostParse(virDomainControllerDef *cont,
>>                       cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
>>                   else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
>>                       cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
>> +            } else if (ARCH_IS_LOONGARCH(def->os.arch)) {
>> +                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
>> +                    cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
>> +                else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
>> +                    cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
>>               }
> I don't think you need to take into account the nec-xhci model for
> loongarch. aarch64 needs it because qemu-xhci didn't exist when that
> architecture was introduced, but that's not the case here so we can
> keep things simpler.
>
> I'm surprised that this code doesn't have handling for riscv64. Not
> your problem, but likely an oversight that should be addressed.


Ok, I'll remove nec-xhci in the next version.

>> +static bool
>> +qemuDomainMachineIsLoongson(const char *machine,
>> +                            const virArch arch)
> The appropriate name for this function would be
> qemuDomainMachineIsLoongArchVirt, to match the existing Arm and
> RISC-V equivalents.


Ok, I'll correct that in the next version.

>> +bool
>> +qemuDomainIsLoongson(const virDomainDef *def)
>> +{
> Same here.


Ok, I'll correct that in the next version.


>> +++ b/src/qemu/qemu_domain_address.c
>> @@ -2093,6 +2143,11 @@ qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def,
>>           return -1;
>>       }
>>
>> +    if (qemuDomainIsLoongson(def) &&
>> +        qemuDomainValidateDevicePCISlotsLoongson(def, addrs) < 0) {
>> +        return -1;
>> +    }
> The existing qemuDomainValidateDevicePCISlots* functions are intended
> to ensure that certain devices, that historically have been assigned
> to specific PCI slots by QEMU, always show up at those addresses.
>
> We haven't needed anything like that for non-x86 architectures so
> far, and I believe that loongarch doesn't need it either.


Ok, I'll correct that in the next version.



>> +++ b/src/qemu/qemu_validate.c
>> @@ -100,7 +100,7 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
>>           switch ((virDomainFeature) i) {
>>           case VIR_DOMAIN_FEATURE_IOAPIC:
>>               if (def->features[i] != VIR_DOMAIN_IOAPIC_NONE) {
>> -                if (!ARCH_IS_X86(def->os.arch)) {
>> +                if (!ARCH_IS_X86(def->os.arch) && !ARCH_IS_LOONGARCH(def->os.arch)) {
>>                       virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
>>                                      _("The '%1$s' feature is not supported for architecture '%2$s' or machine type '%3$s'"),
>>                                      featureName,
> So does loongarch actually have ioapic support? Just making sure. I'm
> surprised because apparently no other non-x86 architecture supports
> it...


Yes, loongarch does have IOAPIC, but this feature has no effect on 
loongarch at this stage, I will cut it first to simplify the committed code.

In addition, I have a question, if I understand correctly, the IOAPIC 
here should be the device interrupt controller, which is located in the 
bridge chip,

it is called IOAPIC under x86, PCH_PIC under loongarch, and GIC under arm.

The kernel_irqchip attribute of the machine parameter in qemu 
corresponding to the function VIR_DOMAIN_FEATURE_IOAPIC determines

whether the device interrupt controller is simulated in qemu or kvm. So 
arm also has such a need, but why doesn't arm add?


>
_______________________________________________
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-leave@lists.libvirt.org
Re: Re: [libvirt PATCH 3/5] Config some capabilities for loongarch virt machine
Posted by Andrea Bolognani 2 years, 1 month ago
On Tue, Dec 19, 2023 at 11:52:03AM +0800, lixianglai wrote:
> > So does loongarch actually have ioapic support? Just making sure. I'm
> > surprised because apparently no other non-x86 architecture supports
> > it...
>
> Yes, loongarch does have IOAPIC, but this feature has no effect on loongarch
> at this stage, I will cut it first to simplify the committed code.
>
> In addition, I have a question, if I understand correctly, the IOAPIC here
> should be the device interrupt controller, which is located in the bridge
> chip,
>
> it is called IOAPIC under x86, PCH_PIC under loongarch, and GIC under arm.
>
> The kernel_irqchip attribute of the machine parameter in qemu corresponding
> to the function VIR_DOMAIN_FEATURE_IOAPIC determines
>
> whether the device interrupt controller is simulated in qemu or kvm. So arm
> also has such a need, but why doesn't arm add?

Okay, so x86's IOAPIC is controlled by the <ioapic> element, while
Arm's GIC uses the <gic> element. By that logic, loongarch should
probably introduce a <phc-pic> element.

It's a bit silly that we need a separate element per architecture,
especially considering that most of the time we just want to control
the kernel_irqchip flag. Case in point, as you noticed Arm doesn't
expose the ability to configure that at the moment.

On the other hand, additional arch-features might show up in the
future, at which point the separate element would start making sense.
See GIC for an example.

Overall, if you don't have a pressing need to expose the ability to
control the kernel_irqchip flag I would just avoid doing anything
about it now and leave the decision for another day and, possibly,
person :)

-- 
Andrea Bolognani / Red Hat / Virtualization
_______________________________________________
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-leave@lists.libvirt.org
Re: [libvirt PATCH 3/5] Config some capabilities for loongarch virt machine
Posted by lixianglai 2 years, 1 month ago
Hi  Andrea:

> On Tue, Dec 19, 2023 at 11:52:03AM +0800, lixianglai wrote:
>>> So does loongarch actually have ioapic support? Just making sure. I'm
>>> surprised because apparently no other non-x86 architecture supports
>>> it...
>> Yes, loongarch does have IOAPIC, but this feature has no effect on loongarch
>> at this stage, I will cut it first to simplify the committed code.
>>
>> In addition, I have a question, if I understand correctly, the IOAPIC here
>> should be the device interrupt controller, which is located in the bridge
>> chip,
>>
>> it is called IOAPIC under x86, PCH_PIC under loongarch, and GIC under arm.
>>
>> The kernel_irqchip attribute of the machine parameter in qemu corresponding
>> to the function VIR_DOMAIN_FEATURE_IOAPIC determines
>>
>> whether the device interrupt controller is simulated in qemu or kvm. So arm
>> also has such a need, but why doesn't arm add?
> Okay, so x86's IOAPIC is controlled by the <ioapic> element, while
> Arm's GIC uses the <gic> element. By that logic, loongarch should
> probably introduce a <phc-pic> element.
>
> It's a bit silly that we need a separate element per architecture,
> especially considering that most of the time we just want to control
> the kernel_irqchip flag. Case in point, as you noticed Arm doesn't
> expose the ability to configure that at the moment.
>
> On the other hand, additional arch-features might show up in the
> future, at which point the separate element would start making sense.
> See GIC for an example.
>
> Overall, if you don't have a pressing need to expose the ability to
> control the kernel_irqchip flag I would just avoid doing anything
> about it now and leave the decision for another day and, possibly,
> person :)

Ok, I see. Thank you very much!


Thanks,

Xianglai.

_______________________________________________
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-leave@lists.libvirt.org