mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
- Remove a transitional asm/cpuid.h header which was added only as
a fallback during cpuid helpers reorg - Initialize reserved fields in the SVSM page validation calls structure to zero in order to allow for future structure extensions - Have the sev-guest driver's buffers used in encryption operations be in linear mapping space as the encryption operation can be offloaded to an accelerator - Have a read-only MSR write when in an AMD SNP guest trap to the hypervisor as it is usually done. This makes the guest user experience better by simply raising a #GP instead of terminating said guest - Do not output AVX512 elapsed time for kernel threads because the data is wrong and fix a NULL pointer dereferencing in the process - Adjust the SRSO mitigation selection to the new attack vectors -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmihmPcACgkQEsHwGGHe VUr6Iw/+KKuQdicPRvdQ8Kv+710oHFHka1CY/LdHuADuuzWWE+Zj6RzwraM0aqIr 1E4resu05MPVJj3KAzt0rBS4Ch5bbNU0QHQqhuuxe+EZpbY8XNxx53f43E4wHTS8 bPaZI1GdLZSTh5BUGRj9N0udK5gnd6kbku80PAbP2fqi+aSOZSA8JCqmiUicSi0/ EbYye7n38q8u1Dh2y9t9CBuxAOZEyzCM6LXRELmK5lya1LGJkKOTGllyb8irzsiv HlLW1sN+weeVlvdUd1LvaYgTAetNhSVtiuh71cGMENnpoAyO6HAea+7X8Tg7UHHp zsYRVXKg2CENQpo4OsQ3q/O7fnPTets7NFm8DNwSKO0qoCqn3Yf4AD4IeCIqZdM3 B2an4b1SWN2xtW38YEEGFVKIBIZVLQFzjmwR3yu8wqjhycIW3rNRCiQuI4EvW+ej kx5ZXHXHKvThoLuxio/ILce1oWa4O9K+GzV9vEDHtYK283sCUU2XyUOVq3Ntpmoc /mzOaBWAjN9nMWJ01DoPRh0bs5nkbN/NQxIOHUiOtLmMkwJX9ls/ed2VagL/iMq1 Sj1RZqkLEUYSHgE+HOToK8LXhbuDp6QEv1FUL/29pu1fzXRn5cn0PJx56+EKjJWO f7b3NWMNGbbD/sIcYAtU73GVNnAOGzUkNA7AjDfmq+YoiC5G+LA= =zsPJ -----END PGP SIGNATURE----- Merge tag 'x86_urgent_for_v6.17_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull x86 fixes from Borislav Petkov: - Remove a transitional asm/cpuid.h header which was added only as a fallback during cpuid helpers reorg - Initialize reserved fields in the SVSM page validation calls structure to zero in order to allow for future structure extensions - Have the sev-guest driver's buffers used in encryption operations be in linear mapping space as the encryption operation can be offloaded to an accelerator - Have a read-only MSR write when in an AMD SNP guest trap to the hypervisor as it is usually done. This makes the guest user experience better by simply raising a #GP instead of terminating said guest - Do not output AVX512 elapsed time for kernel threads because the data is wrong and fix a NULL pointer dereferencing in the process - Adjust the SRSO mitigation selection to the new attack vectors * tag 'x86_urgent_for_v6.17_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/cpuid: Remove transitional <asm/cpuid.h> header x86/sev: Ensure SVSM reserved fields in a page validation entry are initialized to zero virt: sev-guest: Satisfy linear mapping requirement in get_derived_key() x86/sev: Improve handling of writes to intercepted TSC MSRs x86/fpu: Fix NULL dereference in avx512_status() x86/bugs: Select best SRSO mitigation
This commit is contained in:
commit
8d561baae5
|
|
@ -214,7 +214,7 @@ Spectre_v1 X
|
|||
Spectre_v2 X X
|
||||
Spectre_v2_user X X * (Note 1)
|
||||
SRBDS X X X X
|
||||
SRSO X X
|
||||
SRSO X X X X
|
||||
SSB (Note 4)
|
||||
TAA X X X X * (Note 2)
|
||||
TSA X X X X
|
||||
|
|
|
|||
|
|
@ -785,6 +785,7 @@ static void __head svsm_pval_4k_page(unsigned long paddr, bool validate)
|
|||
pc->entry[0].page_size = RMP_PG_SIZE_4K;
|
||||
pc->entry[0].action = validate;
|
||||
pc->entry[0].ignore_cf = 0;
|
||||
pc->entry[0].rsvd = 0;
|
||||
pc->entry[0].pfn = paddr >> PAGE_SHIFT;
|
||||
|
||||
/* Protocol 0, Call ID 1 */
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ static u64 svsm_build_ca_from_pfn_range(u64 pfn, u64 pfn_end, bool action,
|
|||
pe->page_size = RMP_PG_SIZE_4K;
|
||||
pe->action = action;
|
||||
pe->ignore_cf = 0;
|
||||
pe->rsvd = 0;
|
||||
pe->pfn = pfn;
|
||||
|
||||
pe++;
|
||||
|
|
@ -257,6 +258,7 @@ static int svsm_build_ca_from_psc_desc(struct snp_psc_desc *desc, unsigned int d
|
|||
pe->page_size = e->pagesize ? RMP_PG_SIZE_2M : RMP_PG_SIZE_4K;
|
||||
pe->action = e->operation == SNP_PAGE_STATE_PRIVATE;
|
||||
pe->ignore_cf = 0;
|
||||
pe->rsvd = 0;
|
||||
pe->pfn = e->gfn;
|
||||
|
||||
pe++;
|
||||
|
|
|
|||
|
|
@ -371,29 +371,30 @@ static enum es_result __vc_handle_msr_caa(struct pt_regs *regs, bool write)
|
|||
* executing with Secure TSC enabled, so special handling is required for
|
||||
* accesses of MSR_IA32_TSC and MSR_AMD64_GUEST_TSC_FREQ.
|
||||
*/
|
||||
static enum es_result __vc_handle_secure_tsc_msrs(struct pt_regs *regs, bool write)
|
||||
static enum es_result __vc_handle_secure_tsc_msrs(struct es_em_ctxt *ctxt, bool write)
|
||||
{
|
||||
struct pt_regs *regs = ctxt->regs;
|
||||
u64 tsc;
|
||||
|
||||
/*
|
||||
* GUEST_TSC_FREQ should not be intercepted when Secure TSC is enabled.
|
||||
* Terminate the SNP guest when the interception is enabled.
|
||||
* Writing to MSR_IA32_TSC can cause subsequent reads of the TSC to
|
||||
* return undefined values, and GUEST_TSC_FREQ is read-only. Generate
|
||||
* a #GP on all writes.
|
||||
*/
|
||||
if (write) {
|
||||
ctxt->fi.vector = X86_TRAP_GP;
|
||||
ctxt->fi.error_code = 0;
|
||||
return ES_EXCEPTION;
|
||||
}
|
||||
|
||||
/*
|
||||
* GUEST_TSC_FREQ read should not be intercepted when Secure TSC is
|
||||
* enabled. Terminate the guest if a read is attempted.
|
||||
*/
|
||||
if (regs->cx == MSR_AMD64_GUEST_TSC_FREQ)
|
||||
return ES_VMM_ERROR;
|
||||
|
||||
/*
|
||||
* Writes: Writing to MSR_IA32_TSC can cause subsequent reads of the TSC
|
||||
* to return undefined values, so ignore all writes.
|
||||
*
|
||||
* Reads: Reads of MSR_IA32_TSC should return the current TSC value, use
|
||||
* the value returned by rdtsc_ordered().
|
||||
*/
|
||||
if (write) {
|
||||
WARN_ONCE(1, "TSC MSR writes are verboten!\n");
|
||||
return ES_OK;
|
||||
}
|
||||
|
||||
/* Reads of MSR_IA32_TSC should return the current TSC value. */
|
||||
tsc = rdtsc_ordered();
|
||||
regs->ax = lower_32_bits(tsc);
|
||||
regs->dx = upper_32_bits(tsc);
|
||||
|
|
@ -416,7 +417,7 @@ static enum es_result vc_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
|
|||
case MSR_IA32_TSC:
|
||||
case MSR_AMD64_GUEST_TSC_FREQ:
|
||||
if (sev_status & MSR_AMD64_SNP_SECURE_TSC)
|
||||
return __vc_handle_secure_tsc_msrs(regs, write);
|
||||
return __vc_handle_secure_tsc_msrs(ctxt, write);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef _ASM_X86_CPUID_H
|
||||
#define _ASM_X86_CPUID_H
|
||||
|
||||
#include <asm/cpuid/api.h>
|
||||
|
||||
#endif /* _ASM_X86_CPUID_H */
|
||||
|
|
@ -386,7 +386,6 @@ static bool __init should_mitigate_vuln(unsigned int bug)
|
|||
|
||||
case X86_BUG_SPECTRE_V2:
|
||||
case X86_BUG_RETBLEED:
|
||||
case X86_BUG_SRSO:
|
||||
case X86_BUG_L1TF:
|
||||
case X86_BUG_ITS:
|
||||
return cpu_attack_vector_mitigated(CPU_MITIGATE_USER_KERNEL) ||
|
||||
|
|
@ -3184,8 +3183,18 @@ static void __init srso_select_mitigation(void)
|
|||
}
|
||||
|
||||
if (srso_mitigation == SRSO_MITIGATION_AUTO) {
|
||||
if (should_mitigate_vuln(X86_BUG_SRSO)) {
|
||||
/*
|
||||
* Use safe-RET if user->kernel or guest->host protection is
|
||||
* required. Otherwise the 'microcode' mitigation is sufficient
|
||||
* to protect the user->user and guest->guest vectors.
|
||||
*/
|
||||
if (cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_HOST) ||
|
||||
(cpu_attack_vector_mitigated(CPU_MITIGATE_USER_KERNEL) &&
|
||||
!boot_cpu_has(X86_FEATURE_SRSO_USER_KERNEL_NO))) {
|
||||
srso_mitigation = SRSO_MITIGATION_SAFE_RET;
|
||||
} else if (cpu_attack_vector_mitigated(CPU_MITIGATE_USER_USER) ||
|
||||
cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_GUEST)) {
|
||||
srso_mitigation = SRSO_MITIGATION_MICROCODE;
|
||||
} else {
|
||||
srso_mitigation = SRSO_MITIGATION_NONE;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1881,19 +1881,20 @@ long fpu_xstate_prctl(int option, unsigned long arg2)
|
|||
#ifdef CONFIG_PROC_PID_ARCH_STATUS
|
||||
/*
|
||||
* Report the amount of time elapsed in millisecond since last AVX512
|
||||
* use in the task.
|
||||
* use in the task. Report -1 if no AVX-512 usage.
|
||||
*/
|
||||
static void avx512_status(struct seq_file *m, struct task_struct *task)
|
||||
{
|
||||
unsigned long timestamp = READ_ONCE(x86_task_fpu(task)->avx512_timestamp);
|
||||
long delta;
|
||||
unsigned long timestamp;
|
||||
long delta = -1;
|
||||
|
||||
if (!timestamp) {
|
||||
/*
|
||||
* Report -1 if no AVX512 usage
|
||||
*/
|
||||
delta = -1;
|
||||
} else {
|
||||
/* AVX-512 usage is not tracked for kernel threads. Don't report anything. */
|
||||
if (task->flags & (PF_KTHREAD | PF_USER_WORKER))
|
||||
return;
|
||||
|
||||
timestamp = READ_ONCE(x86_task_fpu(task)->avx512_timestamp);
|
||||
|
||||
if (timestamp) {
|
||||
delta = (long)(jiffies - timestamp);
|
||||
/*
|
||||
* Cap to LONG_MAX if time difference > LONG_MAX
|
||||
|
|
|
|||
|
|
@ -116,13 +116,11 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io
|
|||
|
||||
static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
|
||||
{
|
||||
struct snp_derived_key_resp *derived_key_resp __free(kfree) = NULL;
|
||||
struct snp_derived_key_req *derived_key_req __free(kfree) = NULL;
|
||||
struct snp_derived_key_resp derived_key_resp = {0};
|
||||
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
|
||||
struct snp_guest_req req = {};
|
||||
int rc, resp_len;
|
||||
/* Response data is 64 bytes and max authsize for GCM is 16 bytes. */
|
||||
u8 buf[64 + 16];
|
||||
|
||||
if (!arg->req_data || !arg->resp_data)
|
||||
return -EINVAL;
|
||||
|
|
@ -132,8 +130,9 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque
|
|||
* response payload. Make sure that it has enough space to cover the
|
||||
* authtag.
|
||||
*/
|
||||
resp_len = sizeof(derived_key_resp.data) + mdesc->ctx->authsize;
|
||||
if (sizeof(buf) < resp_len)
|
||||
resp_len = sizeof(derived_key_resp->data) + mdesc->ctx->authsize;
|
||||
derived_key_resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT);
|
||||
if (!derived_key_resp)
|
||||
return -ENOMEM;
|
||||
|
||||
derived_key_req = kzalloc(sizeof(*derived_key_req), GFP_KERNEL_ACCOUNT);
|
||||
|
|
@ -149,23 +148,21 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque
|
|||
req.vmpck_id = mdesc->vmpck_id;
|
||||
req.req_buf = derived_key_req;
|
||||
req.req_sz = sizeof(*derived_key_req);
|
||||
req.resp_buf = buf;
|
||||
req.resp_buf = derived_key_resp;
|
||||
req.resp_sz = resp_len;
|
||||
req.exit_code = SVM_VMGEXIT_GUEST_REQUEST;
|
||||
|
||||
rc = snp_send_guest_request(mdesc, &req);
|
||||
arg->exitinfo2 = req.exitinfo2;
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
memcpy(derived_key_resp.data, buf, sizeof(derived_key_resp.data));
|
||||
if (copy_to_user((void __user *)arg->resp_data, &derived_key_resp,
|
||||
sizeof(derived_key_resp)))
|
||||
rc = -EFAULT;
|
||||
if (!rc) {
|
||||
if (copy_to_user((void __user *)arg->resp_data, derived_key_resp,
|
||||
sizeof(derived_key_resp->data)))
|
||||
rc = -EFAULT;
|
||||
}
|
||||
|
||||
/* The response buffer contains the sensitive data, explicitly clear it. */
|
||||
memzero_explicit(buf, sizeof(buf));
|
||||
memzero_explicit(&derived_key_resp, sizeof(derived_key_resp));
|
||||
memzero_explicit(derived_key_resp, sizeof(*derived_key_resp));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user