From: Sean Christopherson <seanjc@google.com>
To: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
x86@kernel.org, Paolo Bonzini <pbonzini@redhat.com>,
David Hildenbrand <david@redhat.com>,
Andrea Arcangeli <aarcange@redhat.com>,
Josh Poimboeuf <jpoimboe@redhat.com>,
"H . Peter Anvin" <hpa@zytor.com>,
Dave Hansen <dave.hansen@intel.com>,
Tony Luck <tony.luck@intel.com>,
Dan Williams <dan.j.williams@intel.com>,
Andi Kleen <ak@linux.intel.com>,
Kirill Shutemov <kirill.shutemov@linux.intel.com>,
Kuppuswamy Sathyanarayanan <knsathya@kernel.org>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v7 09/10] x86/tdx: Handle in-kernel MMIO
Date: Fri, 5 Nov 2021 22:41:16 +0000 [thread overview]
Message-ID: <YYWzDKkH3ZDS1b2J@google.com> (raw)
In-Reply-To: <20211005204136.1812078-10-sathyanarayanan.kuppuswamy@linux.intel.com>
On Tue, Oct 05, 2021, Kuppuswamy Sathyanarayanan wrote:
> @@ -207,6 +210,103 @@ static void tdx_handle_io(struct pt_regs *regs, u32 exit_qual)
> }
> }
>
> +static unsigned long tdx_mmio(int size, bool write, unsigned long addr,
> + unsigned long *val)
> +{
> + struct tdx_hypercall_output out = {0};
> + u64 err;
> +
> + err = _tdx_hypercall(EXIT_REASON_EPT_VIOLATION, size, write,
> + addr, *val, &out);
> + *val = out.r11;
Val should not be written on error, and writing it for "write" is also weird.
> + return err;
> +}
> +
> +static int tdx_handle_mmio(struct pt_regs *regs, struct ve_info *ve)
> +{
> + char buffer[MAX_INSN_SIZE];
> + unsigned long *reg, val;
> + struct insn insn = {};
> + enum mmio_type mmio;
> + int size, ret;
> + u8 sign_byte;
> +
> + if (user_mode(regs)) {
> + ret = insn_fetch_from_user(regs, buffer);
> + if (!ret)
> + return -EFAULT;
> + if (!insn_decode_from_regs(&insn, regs, buffer, ret))
> + return -EFAULT;
> + } else {
> + ret = copy_from_kernel_nofault(buffer, (void *)regs->ip,
> + MAX_INSN_SIZE);
> + if (ret)
> + return -EFAULT;
> + insn_init(&insn, buffer, MAX_INSN_SIZE, 1);
> + insn_get_length(&insn);
> + }
> +
> + mmio = insn_decode_mmio(&insn, &size);
> + if (mmio == MMIO_DECODE_FAILED)
> + return -EFAULT;
> +
> + if (mmio != MMIO_WRITE_IMM && mmio != MMIO_MOVS) {
> + reg = insn_get_modrm_reg_ptr(&insn, regs);
> + if (!reg)
> + return -EFAULT;
> + }
> +
> + switch (mmio) {
> + case MMIO_WRITE:
> + memcpy(&val, reg, size);
> + ret = tdx_mmio(size, true, ve->gpa, &val);
> + break;
> + case MMIO_WRITE_IMM:
> + val = insn.immediate.value;
> + ret = tdx_mmio(size, true, ve->gpa, &val);
> + break;
> + case MMIO_READ:
> + ret = tdx_mmio(size, false, ve->gpa, &val);
val is never set, i.e. this is leaking stack data to the untrusted VMM.
> + if (ret)
> + break;
> + /* Zero-extend for 32-bit operation */
> + if (size == 4)
> + *reg = 0;
> + memcpy(reg, &val, size);
> + break;
> + case MMIO_READ_ZERO_EXTEND:
> + ret = tdx_mmio(size, false, ve->gpa, &val);
And here.
> + if (ret)
> + break;
> +
> + /* Zero extend based on operand size */
> + memset(reg, 0, insn.opnd_bytes);
> + memcpy(reg, &val, size);
> + break;
> + case MMIO_READ_SIGN_EXTEND:
> + ret = tdx_mmio(size, false, ve->gpa, &val);
And here.
> + if (ret)
> + break;
> +
> + if (size == 1)
> + sign_byte = (val & 0x80) ? 0xff : 0x00;
> + else
> + sign_byte = (val & 0x8000) ? 0xff : 0x00;
> +
> + /* Sign extend based on operand size */
> + memset(reg, sign_byte, insn.opnd_bytes);
> + memcpy(reg, &val, size);
> + break;
> + case MMIO_MOVS:
> + case MMIO_DECODE_FAILED:
> + return -EFAULT;
> + }
> +
> + if (ret)
> + return -EFAULT;
> + return insn.length;
> +}
> +
> unsigned long tdx_get_ve_info(struct ve_info *ve)
> {
> struct tdx_module_output out = {0};
> @@ -256,6 +356,14 @@ int tdx_handle_virtualization_exception(struct pt_regs *regs,
> case EXIT_REASON_IO_INSTRUCTION:
> tdx_handle_io(regs, ve->exit_qual);
> break;
> + case EXIT_REASON_EPT_VIOLATION:
> + /* Currently only MMIO triggers EPT violation */
> + ve->instr_len = tdx_handle_mmio(regs, ve);
> + if (ve->instr_len < 0) {
> + pr_warn_once("MMIO failed\n");
That's not remotely helpful. Why not?
if (WARN_ON_ONCE(ve->instr_len < 0))
return -EFAULT;
> + return -EFAULT;
> + }
> + break;
> default:
> pr_warn("Unexpected #VE: %lld\n", ve->exit_reason);
> return -EFAULT;
> --
> 2.25.1
>
next prev parent reply other threads:[~2021-11-05 22:41 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-05 20:41 [PATCH v7 00/10] Add TDX Guest Support (#VE handler support) Kuppuswamy Sathyanarayanan
2021-10-05 20:41 ` [PATCH v7 01/10] x86/io: Allow to override inX() and outX() implementation Kuppuswamy Sathyanarayanan
2021-10-17 19:27 ` Thomas Gleixner
2021-10-17 20:17 ` Sathyanarayanan Kuppuswamy
2021-10-05 20:41 ` [PATCH v7 02/10] x86/tdx: Add early_is_tdx_guest() interface Kuppuswamy Sathyanarayanan
2021-10-17 19:28 ` Thomas Gleixner
2021-10-05 20:41 ` [PATCH v7 03/10] x86/tdx: Handle port I/O in decompression code Kuppuswamy Sathyanarayanan
2021-10-05 20:41 ` [PATCH v7 04/10] x86/tdx: Handle early IO operations Kuppuswamy Sathyanarayanan
2021-11-05 21:12 ` Sean Christopherson
2021-11-05 23:08 ` Sathyanarayanan Kuppuswamy
2021-10-05 20:41 ` [PATCH v7 05/10] x86/tdx: Handle port I/O Kuppuswamy Sathyanarayanan
2021-10-17 19:58 ` Thomas Gleixner
2021-10-17 20:35 ` Sathyanarayanan Kuppuswamy
2021-10-18 13:52 ` Tom Lendacky
2021-10-18 18:42 ` Sathyanarayanan Kuppuswamy
2021-11-05 21:23 ` Sean Christopherson
2021-10-05 20:41 ` [PATCH v7 06/10] x86/insn-eval: Introduce insn_get_modrm_reg_ptr() Kuppuswamy Sathyanarayanan
2021-10-05 20:41 ` [PATCH v7 07/10] x86/insn-eval: Introduce insn_decode_mmio() Kuppuswamy Sathyanarayanan
2021-10-05 20:41 ` [PATCH v7 08/10] x86/sev-es: Use insn_decode_mmio() for MMIO implementation Kuppuswamy Sathyanarayanan
2021-10-05 20:41 ` [PATCH v7 09/10] x86/tdx: Handle in-kernel MMIO Kuppuswamy Sathyanarayanan
2021-11-05 22:41 ` Sean Christopherson [this message]
2021-10-05 20:41 ` [PATCH v7 10/10] x86/tdx: Handle MWAIT and MONITOR Kuppuswamy Sathyanarayanan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YYWzDKkH3ZDS1b2J@google.com \
--to=seanjc@google.com \
--cc=aarcange@redhat.com \
--cc=ak@linux.intel.com \
--cc=bp@alien8.de \
--cc=dan.j.williams@intel.com \
--cc=dave.hansen@intel.com \
--cc=david@redhat.com \
--cc=hpa@zytor.com \
--cc=jpoimboe@redhat.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=knsathya@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=sathyanarayanan.kuppuswamy@linux.intel.com \
--cc=tglx@linutronix.de \
--cc=tony.luck@intel.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.