[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 9/9] x86/spec-ctrl: Mitigate the Zen1 DIV leakge


  • To: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Mon, 18 Sep 2023 13:15:26 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=We2/Sm4p1Sy8kvdJTxK9/X8195fSmiib0HSmoY9alFw=; b=CKmlD/s9HEMng+XkmINk1KnkkIsJAE1OCDbztCPeJiH5stbLPesGta7EZNJnZajksjwB1ALUGRS5aj7y7g4CdRR3kQ/asrvbyhOEQC/m0VhOvoZiCkCG+uzfACZeHUuYD82byrwJTRaOYpR32ohZh5PlGPGtgCxmQ7/GM73/nbRW2WxTRsnfQVRfeojSENWNo3mA1uIP9AiZ9ZeLqdzyPIRJ3Rm4GKQ+RH6BkKl1+hNcf/uEHEKTx7RwMxs+dJv3I5wO1Xrflf6Ujm7q7xwAQte76LTApgo/VWuza0+HewYa3M3lmVWCOZD3NZO+bUqCcZwQI6Z4KS5byw2pmaHWBw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=nx4nAWDXsDB1XEZJFzCQQ5YQpw77/ta8NzyMggHSBrCsxVPWYFeebvbETdCGpdT2vLnM4C6BRRB83lNFoMJKriKOFd68mxrhPN/umupHrMy14uyy1ASuaq4J5geQWPy12IVSOErdmNvvN06bHuAVJOoUNYTGi2xBwc3vRI6mCVuVpTfoepczC56BwPyDEYDKSll/LZdOHTQHE3u5WuB/usGyG4za7Sy3Z4MR7daKIO3L7OpFigzA6gs03rAJvzNESXilEO80cPmwIrM6Bh61nt/B+/ZH4SBISW6wrz9x1ixO++WgE6BxBd9/5HvuGQtLHkjiwWRMaYRN9yPYcZ/gmw==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: Roger Pau Monné <roger.pau@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • Delivery-date: Mon, 18 Sep 2023 11:15:41 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 15.09.2023 17:00, Andrew Cooper wrote:
> In the Zen1 microarchitecure, there is one divider in the pipeline which
> services uops from both threads.  In the case of #DE, the latched result from
> the previous DIV to execute will be forwarded speculatively.
> 
> This is an interesting covert channel that allows two threads to communicate
> without any system calls.  In also allows userspace to obtain the result of
> the most recent DIV instruction executed (even speculatively) in the core,
> which can be from a higher privilege context.
> 
> Scrub the result from the divider by executing a non-faulting divide.  This
> needs performing on the exit-to-guest paths, and ist_exit-to-Xen.
> 
> This is XSA-439 / CVE-2023-20588.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>

Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>

Nevertheless I would have hoped you add at least a sentence on the alternatives
patching of the IST path. Hitting #MC while patching is possible, after all
(yes, you will tell me that #MC is almost certainly fatal to the system anyway,
but still).

> @@ -955,6 +960,46 @@ static void __init srso_calculations(bool hw_smt_enabled)
>          setup_force_cpu_cap(X86_FEATURE_SRSO_NO);
>  }
>  
> +/*
> + * The Div leakage issue is specific to the AMD Zen1 microarchitecure.
> + *
> + * However, there's no $FOO_NO bit defined, so if we're virtualised we have 
> no
> + * hope of spotting the case where we might move to vulnerable hardware.  We
> + * also can't make any useful conclusion about SMT-ness.
> + *
> + * Don't check the hypervisor bit, so at least we do the safe thing when
> + * booting on something that looks like a Zen1 CPU.
> + */
> +static bool __init has_div_vuln(void)
> +{
> +    if ( !(boot_cpu_data.x86_vendor &
> +           (X86_VENDOR_AMD | X86_VENDOR_HYGON)) )
> +        return false;
> +
> +    if ( (boot_cpu_data.x86 != 0x17 && boot_cpu_data.x86 != 0x18) ||
> +         !is_zen1_uarch() )
> +        return false;
> +
> +    return true;
> +}

Just to mention it - personally I consider

    ...
    if ( ... )
        return true;

    return false;
}

a minor anti-pattern, as a sole return imo makes more clear what's going on.
In a case like this, where you intentionally split return paths anyway, I'd
then go with

static bool __init has_div_vuln(void)
{
    if ( !(boot_cpu_data.x86_vendor &
           (X86_VENDOR_AMD | X86_VENDOR_HYGON)) )
        return false;

    if ( boot_cpu_data.x86 != 0x17 && boot_cpu_data.x86 != 0x18 )
        return false;

    return is_zen1_uarch();
}

Jan



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.