qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3] i386: Introduce ARAT CPU feature
@ 2015-05-25 14:47 Jan Kiszka
  2015-05-31 18:12 ` Michael S. Tsirkin
  0 siblings, 1 reply; 2+ messages in thread
From: Jan Kiszka @ 2015-05-25 14:47 UTC (permalink / raw)
  To: Paolo Bonzini, Eduardo Habkost; +Cc: qemu-devel, kvm

[-- Attachment #1: Type: text/plain, Size: 8339 bytes --]

From: Jan Kiszka <jan.kiszka@siemens.com>

ARAT signals that the APIC timer does not stop in power saving states.
As our APICs are emulated, it's fine to expose this feature to guests,
at least when asking for KVM host features or with CPU types that
include the flag. The exact model number that introduced the feature is
not known, but reports can be found that it's at least available since
Sandy Bridge.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---

Changes in v3 (too quick...):
 - fix typo in cpu model name
 - also cover q35

 hw/i386/pc_piix.c | 10 ++++++++++
 hw/i386/pc_q35.c  | 10 ++++++++++
 target-i386/cpu.c | 33 ++++++++++++++++++++++++++++++++-
 target-i386/cpu.h |  3 +++
 target-i386/kvm.c |  2 ++
 5 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 212e263..8a29af1 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -312,6 +312,16 @@ static void pc_init_pci(MachineState *machine)
 
 static void pc_compat_2_3(MachineState *machine)
 {
+    x86_cpu_compat_set_features("Westmere", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
+    x86_cpu_compat_set_features("SandyBridge", FEAT_6_EAX, 0,
+                                CPUID_6_EAX_ARAT);
+    x86_cpu_compat_set_features("IvyBridge", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
+    x86_cpu_compat_set_features("Haswell-noTSX", FEAT_6_EAX, 0,
+                                CPUID_6_EAX_ARAT);
+    x86_cpu_compat_set_features("Haswell", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
+    x86_cpu_compat_set_features("Broadwell-noTSX", FEAT_6_EAX, 0,
+                                CPUID_6_EAX_ARAT);
+    x86_cpu_compat_set_features("Broadwell", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
 }
 
 static void pc_compat_2_2(MachineState *machine)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index e67f2de..ca736d4 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -291,6 +291,16 @@ static void pc_q35_init(MachineState *machine)
 
 static void pc_compat_2_3(MachineState *machine)
 {
+    x86_cpu_compat_set_features("Westmere", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
+    x86_cpu_compat_set_features("SandyBridge", FEAT_6_EAX, 0,
+                                CPUID_6_EAX_ARAT);
+    x86_cpu_compat_set_features("IvyBridge", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
+    x86_cpu_compat_set_features("Haswell-noTSX", FEAT_6_EAX, 0,
+                                CPUID_6_EAX_ARAT);
+    x86_cpu_compat_set_features("Haswell", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
+    x86_cpu_compat_set_features("Broadwell-noTSX", FEAT_6_EAX, 0,
+                                CPUID_6_EAX_ARAT);
+    x86_cpu_compat_set_features("Broadwell", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
 }
 
 static void pc_compat_2_2(MachineState *machine)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 3305e09..e435a08 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -284,6 +284,17 @@ static const char *cpuid_xsave_feature_name[] = {
     NULL, NULL, NULL, NULL,
 };
 
+static const char *cpuid_6_feature_name[] = {
+    NULL, NULL, "arat", NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+};
+
 #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
 #define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
           CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
@@ -339,6 +350,7 @@ static const char *cpuid_xsave_feature_name[] = {
           CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
           CPUID_7_0_EBX_RDSEED */
 #define TCG_APM_FEATURES 0
+#define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
 
 
 typedef struct FeatureWordInfo {
@@ -408,6 +420,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
         .cpuid_reg = R_EAX,
         .tcg_features = 0,
     },
+    [FEAT_6_EAX] = {
+        .feat_names = cpuid_6_feature_name,
+        .cpuid_eax = 6, .cpuid_reg = R_EAX,
+        .tcg_features = TCG_6_EAX_FEATURES,
+    },
 };
 
 typedef struct X86RegisterInfo32 {
@@ -1001,6 +1018,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
         .features[FEAT_8000_0001_ECX] =
             CPUID_EXT3_LAHF_LM,
+        .features[FEAT_6_EAX] =
+            CPUID_6_EAX_ARAT,
         .xlevel = 0x8000000A,
         .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
     },
@@ -1030,6 +1049,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_EXT3_LAHF_LM,
         .features[FEAT_XSAVE] =
             CPUID_XSAVE_XSAVEOPT,
+        .features[FEAT_6_EAX] =
+            CPUID_6_EAX_ARAT,
         .xlevel = 0x8000000A,
         .model_id = "Intel Xeon E312xx (Sandy Bridge)",
     },
@@ -1062,6 +1083,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_EXT3_LAHF_LM,
         .features[FEAT_XSAVE] =
             CPUID_XSAVE_XSAVEOPT,
+        .features[FEAT_6_EAX] =
+            CPUID_6_EAX_ARAT,
         .xlevel = 0x8000000A,
         .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)",
     },
@@ -1096,6 +1119,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
         .features[FEAT_XSAVE] =
             CPUID_XSAVE_XSAVEOPT,
+        .features[FEAT_6_EAX] =
+            CPUID_6_EAX_ARAT,
         .xlevel = 0x8000000A,
         .model_id = "Intel Core Processor (Haswell, no TSX)",
     },    {
@@ -1130,6 +1155,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_7_0_EBX_RTM,
         .features[FEAT_XSAVE] =
             CPUID_XSAVE_XSAVEOPT,
+        .features[FEAT_6_EAX] =
+            CPUID_6_EAX_ARAT,
         .xlevel = 0x8000000A,
         .model_id = "Intel Core Processor (Haswell)",
     },
@@ -1166,6 +1193,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_7_0_EBX_SMAP,
         .features[FEAT_XSAVE] =
             CPUID_XSAVE_XSAVEOPT,
+        .features[FEAT_6_EAX] =
+            CPUID_6_EAX_ARAT,
         .xlevel = 0x8000000A,
         .model_id = "Intel Core Processor (Broadwell, no TSX)",
     },
@@ -1202,6 +1231,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_7_0_EBX_SMAP,
         .features[FEAT_XSAVE] =
             CPUID_XSAVE_XSAVEOPT,
+        .features[FEAT_6_EAX] =
+            CPUID_6_EAX_ARAT,
         .xlevel = 0x8000000A,
         .model_id = "Intel Core Processor (Broadwell)",
     },
@@ -2358,7 +2389,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         break;
     case 6:
         /* Thermal and Power Leaf */
-        *eax = 0;
+        *eax = env->features[FEAT_6_EAX];
         *ebx = 0;
         *ecx = 0;
         *edx = 0;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 4ee12ca..800158e 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -412,6 +412,7 @@ typedef enum FeatureWord {
     FEAT_KVM,           /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
     FEAT_SVM,           /* CPUID[8000_000A].EDX */
     FEAT_XSAVE,         /* CPUID[EAX=0xd,ECX=1].EAX */
+    FEAT_6_EAX,         /* CPUID[6].EAX */
     FEATURE_WORDS,
 } FeatureWord;
 
@@ -577,6 +578,8 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_XSAVE_XGETBV1    (1U << 2)
 #define CPUID_XSAVE_XSAVES     (1U << 3)
 
+#define CPUID_6_EAX_ARAT       (1U << 2)
+
 /* CPUID[0x80000007].EDX flags: */
 #define CPUID_APM_INVTSC       (1U << 8)
 
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index a26d25a..b786359 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -233,6 +233,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
         if (!kvm_irqchip_in_kernel()) {
             ret &= ~CPUID_EXT_X2APIC;
         }
+    } else if (function == 6 && reg == R_EAX) {
+        ret |= CPUID_6_EAX_ARAT; /* safe to allow because of emulated APIC */
     } else if (function == 0x80000001 && reg == R_EDX) {
         /* On Intel, kvm returns cpuid according to the Intel spec,
          * so add missing bits according to the AMD spec:


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [Qemu-devel] [PATCH v3] i386: Introduce ARAT CPU feature
  2015-05-25 14:47 [Qemu-devel] [PATCH v3] i386: Introduce ARAT CPU feature Jan Kiszka
@ 2015-05-31 18:12 ` Michael S. Tsirkin
  0 siblings, 0 replies; 2+ messages in thread
From: Michael S. Tsirkin @ 2015-05-31 18:12 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Paolo Bonzini, Eduardo Habkost, kvm, qemu-devel

On Mon, May 25, 2015 at 04:47:49PM +0200, Jan Kiszka wrote:
> From: Jan Kiszka <jan.kiszka@siemens.com>
> 
> ARAT signals that the APIC timer does not stop in power saving states.
> As our APICs are emulated, it's fine to expose this feature to guests,
> at least when asking for KVM host features or with CPU types that
> include the flag. The exact model number that introduced the feature is
> not known, but reports can be found that it's at least available since
> Sandy Bridge.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>

For PC changes
Acked-by: Michael S. Tsirkin <mst@redhat.com>

but Eduardo needs to review this one.

> ---
> 
> Changes in v3 (too quick...):
>  - fix typo in cpu model name
>  - also cover q35
> 
>  hw/i386/pc_piix.c | 10 ++++++++++
>  hw/i386/pc_q35.c  | 10 ++++++++++
>  target-i386/cpu.c | 33 ++++++++++++++++++++++++++++++++-
>  target-i386/cpu.h |  3 +++
>  target-i386/kvm.c |  2 ++
>  5 files changed, 57 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> index 212e263..8a29af1 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -312,6 +312,16 @@ static void pc_init_pci(MachineState *machine)
>  
>  static void pc_compat_2_3(MachineState *machine)
>  {
> +    x86_cpu_compat_set_features("Westmere", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
> +    x86_cpu_compat_set_features("SandyBridge", FEAT_6_EAX, 0,
> +                                CPUID_6_EAX_ARAT);
> +    x86_cpu_compat_set_features("IvyBridge", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
> +    x86_cpu_compat_set_features("Haswell-noTSX", FEAT_6_EAX, 0,
> +                                CPUID_6_EAX_ARAT);
> +    x86_cpu_compat_set_features("Haswell", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
> +    x86_cpu_compat_set_features("Broadwell-noTSX", FEAT_6_EAX, 0,
> +                                CPUID_6_EAX_ARAT);
> +    x86_cpu_compat_set_features("Broadwell", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
>  }
>  
>  static void pc_compat_2_2(MachineState *machine)
> diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> index e67f2de..ca736d4 100644
> --- a/hw/i386/pc_q35.c
> +++ b/hw/i386/pc_q35.c
> @@ -291,6 +291,16 @@ static void pc_q35_init(MachineState *machine)
>  
>  static void pc_compat_2_3(MachineState *machine)
>  {
> +    x86_cpu_compat_set_features("Westmere", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
> +    x86_cpu_compat_set_features("SandyBridge", FEAT_6_EAX, 0,
> +                                CPUID_6_EAX_ARAT);
> +    x86_cpu_compat_set_features("IvyBridge", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
> +    x86_cpu_compat_set_features("Haswell-noTSX", FEAT_6_EAX, 0,
> +                                CPUID_6_EAX_ARAT);
> +    x86_cpu_compat_set_features("Haswell", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
> +    x86_cpu_compat_set_features("Broadwell-noTSX", FEAT_6_EAX, 0,
> +                                CPUID_6_EAX_ARAT);
> +    x86_cpu_compat_set_features("Broadwell", FEAT_6_EAX, 0, CPUID_6_EAX_ARAT);
>  }
>  
>  static void pc_compat_2_2(MachineState *machine)
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 3305e09..e435a08 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -284,6 +284,17 @@ static const char *cpuid_xsave_feature_name[] = {
>      NULL, NULL, NULL, NULL,
>  };
>  
> +static const char *cpuid_6_feature_name[] = {
> +    NULL, NULL, "arat", NULL,
> +    NULL, NULL, NULL, NULL,
> +    NULL, NULL, NULL, NULL,
> +    NULL, NULL, NULL, NULL,
> +    NULL, NULL, NULL, NULL,
> +    NULL, NULL, NULL, NULL,
> +    NULL, NULL, NULL, NULL,
> +    NULL, NULL, NULL, NULL,
> +};
> +
>  #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
>  #define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
>            CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
> @@ -339,6 +350,7 @@ static const char *cpuid_xsave_feature_name[] = {
>            CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
>            CPUID_7_0_EBX_RDSEED */
>  #define TCG_APM_FEATURES 0
> +#define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
>  
>  
>  typedef struct FeatureWordInfo {
> @@ -408,6 +420,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
>          .cpuid_reg = R_EAX,
>          .tcg_features = 0,
>      },
> +    [FEAT_6_EAX] = {
> +        .feat_names = cpuid_6_feature_name,
> +        .cpuid_eax = 6, .cpuid_reg = R_EAX,
> +        .tcg_features = TCG_6_EAX_FEATURES,
> +    },
>  };
>  
>  typedef struct X86RegisterInfo32 {
> @@ -1001,6 +1018,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
>              CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
>          .features[FEAT_8000_0001_ECX] =
>              CPUID_EXT3_LAHF_LM,
> +        .features[FEAT_6_EAX] =
> +            CPUID_6_EAX_ARAT,
>          .xlevel = 0x8000000A,
>          .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
>      },
> @@ -1030,6 +1049,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
>              CPUID_EXT3_LAHF_LM,
>          .features[FEAT_XSAVE] =
>              CPUID_XSAVE_XSAVEOPT,
> +        .features[FEAT_6_EAX] =
> +            CPUID_6_EAX_ARAT,
>          .xlevel = 0x8000000A,
>          .model_id = "Intel Xeon E312xx (Sandy Bridge)",
>      },
> @@ -1062,6 +1083,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
>              CPUID_EXT3_LAHF_LM,
>          .features[FEAT_XSAVE] =
>              CPUID_XSAVE_XSAVEOPT,
> +        .features[FEAT_6_EAX] =
> +            CPUID_6_EAX_ARAT,
>          .xlevel = 0x8000000A,
>          .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)",
>      },
> @@ -1096,6 +1119,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
>              CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
>          .features[FEAT_XSAVE] =
>              CPUID_XSAVE_XSAVEOPT,
> +        .features[FEAT_6_EAX] =
> +            CPUID_6_EAX_ARAT,
>          .xlevel = 0x8000000A,
>          .model_id = "Intel Core Processor (Haswell, no TSX)",
>      },    {
> @@ -1130,6 +1155,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
>              CPUID_7_0_EBX_RTM,
>          .features[FEAT_XSAVE] =
>              CPUID_XSAVE_XSAVEOPT,
> +        .features[FEAT_6_EAX] =
> +            CPUID_6_EAX_ARAT,
>          .xlevel = 0x8000000A,
>          .model_id = "Intel Core Processor (Haswell)",
>      },
> @@ -1166,6 +1193,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
>              CPUID_7_0_EBX_SMAP,
>          .features[FEAT_XSAVE] =
>              CPUID_XSAVE_XSAVEOPT,
> +        .features[FEAT_6_EAX] =
> +            CPUID_6_EAX_ARAT,
>          .xlevel = 0x8000000A,
>          .model_id = "Intel Core Processor (Broadwell, no TSX)",
>      },
> @@ -1202,6 +1231,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
>              CPUID_7_0_EBX_SMAP,
>          .features[FEAT_XSAVE] =
>              CPUID_XSAVE_XSAVEOPT,
> +        .features[FEAT_6_EAX] =
> +            CPUID_6_EAX_ARAT,
>          .xlevel = 0x8000000A,
>          .model_id = "Intel Core Processor (Broadwell)",
>      },
> @@ -2358,7 +2389,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
>          break;
>      case 6:
>          /* Thermal and Power Leaf */
> -        *eax = 0;
> +        *eax = env->features[FEAT_6_EAX];
>          *ebx = 0;
>          *ecx = 0;
>          *edx = 0;
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index 4ee12ca..800158e 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -412,6 +412,7 @@ typedef enum FeatureWord {
>      FEAT_KVM,           /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
>      FEAT_SVM,           /* CPUID[8000_000A].EDX */
>      FEAT_XSAVE,         /* CPUID[EAX=0xd,ECX=1].EAX */
> +    FEAT_6_EAX,         /* CPUID[6].EAX */
>      FEATURE_WORDS,
>  } FeatureWord;
>  
> @@ -577,6 +578,8 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
>  #define CPUID_XSAVE_XGETBV1    (1U << 2)
>  #define CPUID_XSAVE_XSAVES     (1U << 3)
>  
> +#define CPUID_6_EAX_ARAT       (1U << 2)
> +
>  /* CPUID[0x80000007].EDX flags: */
>  #define CPUID_APM_INVTSC       (1U << 8)
>  
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index a26d25a..b786359 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -233,6 +233,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
>          if (!kvm_irqchip_in_kernel()) {
>              ret &= ~CPUID_EXT_X2APIC;
>          }
> +    } else if (function == 6 && reg == R_EAX) {
> +        ret |= CPUID_6_EAX_ARAT; /* safe to allow because of emulated APIC */
>      } else if (function == 0x80000001 && reg == R_EDX) {
>          /* On Intel, kvm returns cpuid according to the Intel spec,
>           * so add missing bits according to the AMD spec:
> 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-05-31 18:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-25 14:47 [Qemu-devel] [PATCH v3] i386: Introduce ARAT CPU feature Jan Kiszka
2015-05-31 18:12 ` Michael S. Tsirkin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).