To combat the absence of mitigating microcode, arrange to hide RDRAND by
default on IvyBridge hardware.

Adjust the default feature derivation to hide RDRAND on IvyBridge client
parts, unless `cpuid=rdrand` is explicitly provided.

Adjust the restore path in xc_cpuid_apply_policy() to not hide RDRAND from VMs
which migrated from pre-4.14.

In all cases, individual guests can continue using RDRAND if explicitly
enabled in their config files.

Signed-off-by: Andrew Cooper <andrew.coop...@citrix.com>
---
CC: Ian Jackson <ian.jack...@citrix.com>
CC: Wei Liu <w...@xen.org>
CC: Jan Beulich <jbeul...@suse.com>
CC: Wei Liu <w...@xen.org>
CC: Roger Pau Monné <roger....@citrix.com>
CC: Paul Durrant <p...@xen.org>
---
 docs/misc/xen-command-line.pandoc           | 20 +++++++++++++++-----
 tools/libxc/xc_cpuid_x86.c                  |  3 +++
 xen/arch/x86/cpuid.c                        | 21 +++++++++++++++++++++
 xen/include/public/arch-x86/cpufeatureset.h |  2 +-
 4 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/docs/misc/xen-command-line.pandoc 
b/docs/misc/xen-command-line.pandoc
index fde749c669..c8ebfaf813 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -512,11 +512,21 @@ The Speculation Control hardware features `srbds-ctrl`, 
`md-clear`, `ibrsb`,
 `stibp`, `ibpb`, `l1d-flush` and `ssbd` are used by default if available and
 applicable.  They can all be ignored.
 
-`rdrand` and `rdseed` can be ignored, as a mitigation to XSA-320 /
-CVE-2020-0543.  The RDRAND feature is disabled by default on certain AMD
-systems, due to possible malfunctions after ACPI S3 suspend/resume.  `rdrand`
-may be used in its positive form to override Xen's default behaviour on these
-systems, and make the feature fully usable.
+`rdrand` and `rdseed` have multiple interactions.
+
+*   For Special Register Buffer Data Sampling (SRBDS, XSA-320, CVE-2020-0543),
+    RDRAND and RDSEED can be ignored.
+
+    Due to the absence microcode to address SRBDS on IvyBridge hardware, the
+    RDRAND feature is hidden by default for guests, unless `rdrand` is used in
+    its positive form.  Irrespective of the default setting here, VMs can use
+    RDRAND if explicitly enabled in guest config file, and VMs already using
+    RDRAND can migrate in.
+
+*   The RDRAND feature is disabled by default on AMD Fam15/16 systems, due to
+    possible malfunctions after ACPI S3 suspend/resume.  `rdrand` may be used
+    in its positive form to override Xen's default behaviour on these systems,
+    and make the feature fully usable.
 
 ### cpuid_mask_cpu
 > `= fam_0f_rev_[cdefg] | fam_10_rev_[bc] | fam_11_rev_b`
diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index 5649913e69..877a5601f3 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -503,6 +503,9 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t 
domid, bool restore,
      */
     if ( restore )
     {
+        if ( test_bit(X86_FEATURE_RDRAND, host_featureset) && !p->basic.rdrand 
)
+            p->basic.rdrand = true;
+
         if ( di.hvm )
         {
             p->feat.mpx = test_bit(X86_FEATURE_MPX, host_featureset);
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index f2fc0aa895..6a4a787b68 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -340,6 +340,25 @@ static void __init calculate_host_policy(void)
     }
 }
 
+static void __init guest_common_default_feature_adjustments(uint32_t *fs)
+{
+    /*
+     * IvyBridge client parts suffer from leakage of RDRAND data due to SRBDS
+     * (XSA-320 / CVE-2020-0543), and won't be receiving microcode to
+     * compensate.
+     *
+     * Mitigate by hiding RDRAND from guests by default, unless explicitly
+     * overridden on the Xen command line (cpuid=rdrand).  Irrespective of the
+     * default setting, guests can use RDRAND if explicitly enabled
+     * (cpuid="host,rdrand=1") in the VM's config file, and VMs which were
+     * previously using RDRAND can migrate in.
+     */
+    if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+         boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 0x3a &&
+         cpu_has_rdrand && !is_forced_cpu_cap(X86_FEATURE_RDRAND) )
+        __clear_bit(X86_FEATURE_RDRAND, fs);
+}
+
 static void __init guest_common_feature_adjustments(uint32_t *fs)
 {
     /* Unconditionally claim to be able to set the hypervisor bit. */
@@ -403,6 +422,7 @@ static void __init calculate_pv_def_policy(void)
         pv_featureset[i] &= pv_def_featuremask[i];
 
     guest_common_feature_adjustments(pv_featureset);
+    guest_common_default_feature_adjustments(pv_featureset);
 
     sanitise_featureset(pv_featureset);
     cpuid_featureset_to_policy(pv_featureset, p);
@@ -485,6 +505,7 @@ static void __init calculate_hvm_def_policy(void)
         hvm_featureset[i] &= hvm_featuremask[i];
 
     guest_common_feature_adjustments(hvm_featureset);
+    guest_common_default_feature_adjustments(hvm_featureset);
 
     sanitise_featureset(hvm_featureset);
     cpuid_featureset_to_policy(hvm_featureset, p);
diff --git a/xen/include/public/arch-x86/cpufeatureset.h 
b/xen/include/public/arch-x86/cpufeatureset.h
index af1b8a96a6..fe7492a225 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -149,7 +149,7 @@ XEN_CPUFEATURE(XSAVE,         1*32+26) /*A  
XSAVE/XRSTOR/XSETBV/XGETBV */
 XEN_CPUFEATURE(OSXSAVE,       1*32+27) /*!  OSXSAVE */
 XEN_CPUFEATURE(AVX,           1*32+28) /*A  Advanced Vector Extensions */
 XEN_CPUFEATURE(F16C,          1*32+29) /*A  Half-precision convert instruction 
*/
-XEN_CPUFEATURE(RDRAND,        1*32+30) /*A  Digital Random Number Generator */
+XEN_CPUFEATURE(RDRAND,        1*32+30) /*!A Digital Random Number Generator */
 XEN_CPUFEATURE(HYPERVISOR,    1*32+31) /*!A Running under some hypervisor */
 
 /* AMD-defined CPU features, CPUID level 0x80000001.edx, word 2 */
-- 
2.11.0


Reply via email to