[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <YofXjHpME0SwaHfV@google.com>
Date: Fri, 20 May 2022 18:01:48 +0000
From: Sean Christopherson <seanjc@...gle.com>
To: Dave Hansen <dave.hansen@...el.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@...ux.intel.com>,
tglx@...utronix.de, mingo@...hat.com, bp@...en8.de,
luto@...nel.org, peterz@...radead.org, ak@...ux.intel.com,
dan.j.williams@...el.com, david@...hat.com, hpa@...or.com,
linux-kernel@...r.kernel.org,
sathyanarayanan.kuppuswamy@...ux.intel.com,
thomas.lendacky@....com, x86@...nel.org
Subject: Re: [PATCHv2 2/3] x86/tdx: Clarify RIP adjustments in #VE handler
On Fri, May 20, 2022, Dave Hansen wrote:
> BTW, how do we know that all non-EPT_VIOLATION exits reasons are
> instruction execution?
The TDX module spec actually does a decent job of calling this out explicitly:
#VE may be injected by the Intel TDX module in several cases:
* Emulation of the architectural #VE injection on EPT violation, done by a
guest-side Intel TDX module flow that performs an EPT walk.
* As a result of guest TD execution of a disallowed instruction (see 10.4 above),
a disallowed MSR access (see 10.7 above), or CPUID virtualization (see 10.8 above).
* A notification to the guest TD about anomalous behavior (e.g., too many EPT
violations reported on the same TD VCPU instruction without making progress).
This kind of #VE is raised only if the guest TD enabled the specific notification
(using TDG.VM.WR to write the TDCS.NOTIFY_ENABLES field) and when a #VE can be
injected. See 16.3 for details.
The first one is (obviously) the EPT violation / MMIO case. The second is purely
instruction execution (the MSR and CPUID clauses are specific to RDMSR, WRMSR,
and CPUID)). The third I hadn't seen until now, but it's opt-in.
The main switch statement further guarantees the kernel is only going to handle
EPT violations and instruction exits at this time:
switch (ve->exit_reason) {
case EXIT_REASON_HLT:
return handle_halt();
case EXIT_REASON_MSR_READ:
return read_msr(regs);
case EXIT_REASON_MSR_WRITE:
return write_msr(regs);
case EXIT_REASON_CPUID:
return handle_cpuid(regs);
case EXIT_REASON_EPT_VIOLATION:
return handle_mmio(regs, ve);
case EXIT_REASON_IO_INSTRUCTION:
return handle_io(regs, ve->exit_qual);
default:
pr_warn("Unexpected #VE: %lld\n", ve->exit_reason);
return false;
}
Powered by blists - more mailing lists