[PATCH] x86: vmx: Enable INVPCID if reported via CPUID

9 views
Skip to first unread message

Jan Kiszka

unread,
Jul 8, 2016, 1:25:41 PM7/8/16
to Jailhouse
Linux kernel 4.6 and later make use of this instruction and crash if we
do not allow it. It flushes TLB mappings, but only on the caller's
logical CPU.

Signed-off-by: Jan Kiszka <jan.k...@siemens.com>
---

Grmbl, just wanted to quickly test an "all fresh" box...

hypervisor/arch/x86/include/asm/processor.h | 1 +
hypervisor/arch/x86/include/asm/vmx.h | 1 +
hypervisor/arch/x86/vmx.c | 17 +++++++++--------
3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/hypervisor/arch/x86/include/asm/processor.h b/hypervisor/arch/x86/include/asm/processor.h
index 85e41b3..6c50d27 100644
--- a/hypervisor/arch/x86/include/asm/processor.h
+++ b/hypervisor/arch/x86/include/asm/processor.h
@@ -28,6 +28,7 @@
#define X86_FEATURE_HYPERVISOR (1 << 31)

/* leaf 0x07, subleaf 0, EBX */
+#define X86_FEATURE_INVPCID (1 << 10)
#define X86_FEATURE_CAT (1 << 15)

/* leaf 0x80000001, ECX */
diff --git a/hypervisor/arch/x86/include/asm/vmx.h b/hypervisor/arch/x86/include/asm/vmx.h
index 775ef3f..66795c1 100644
--- a/hypervisor/arch/x86/include/asm/vmx.h
+++ b/hypervisor/arch/x86/include/asm/vmx.h
@@ -226,6 +226,7 @@ enum vmx_state { VMXOFF = 0, VMXON, VMCS_READY };
#define SECONDARY_EXEC_ENABLE_EPT (1UL << 1)
#define SECONDARY_EXEC_RDTSCP (1UL << 3)
#define SECONDARY_EXEC_UNRESTRICTED_GUEST (1UL << 7)
+#define SECONDARY_EXEC_INVPCID (1UL << 12)

#define VM_EXIT_HOST_ADDR_SPACE_SIZE (1UL << 9)
#define VM_EXIT_SAVE_IA32_PAT (1UL << 18)
diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c
index f5cd8ca..3fe6e1d 100644
--- a/hypervisor/arch/x86/vmx.c
+++ b/hypervisor/arch/x86/vmx.c
@@ -80,7 +80,7 @@ static u8 __attribute__((aligned(PAGE_SIZE))) msr_bitmap[][0x2000/8] = {
};
static u8 __attribute__((aligned(PAGE_SIZE))) apic_access_page[PAGE_SIZE];
static struct paging ept_paging[EPT_PAGE_DIR_LEVELS];
-static u32 enable_rdtscp;
+static u32 secondary_exec_addon;
static unsigned long cr_maybe1[2], cr_required1[2];

static bool vmxon(struct per_cpu *cpu_data)
@@ -233,12 +233,13 @@ static int vmx_check_features(void)
!(vmx_proc_ctrl2 & SECONDARY_EXEC_UNRESTRICTED_GUEST))
return trace_error(-EIO);

- /* require RDTSCP if present in CPUID */
- if (cpuid_edx(0x80000001, 0) & X86_FEATURE_RDTSCP) {
- enable_rdtscp = SECONDARY_EXEC_RDTSCP;
- if (!(vmx_proc_ctrl2 & SECONDARY_EXEC_RDTSCP))
- return trace_error(-EIO);
- }
+ /* require RDTSCP and INVPCID if present in CPUID */
+ if (cpuid_edx(0x80000001, 0) & X86_FEATURE_RDTSCP)
+ secondary_exec_addon |= SECONDARY_EXEC_RDTSCP;
+ if (cpuid_ebx(0x07, 0) & X86_FEATURE_INVPCID)
+ secondary_exec_addon |= SECONDARY_EXEC_INVPCID;
+ if ((vmx_proc_ctrl2 & secondary_exec_addon) != secondary_exec_addon)
+ return trace_error(-EIO);

/* require PAT and EFER save/restore */
vmx_entry_ctrl = read_msr(MSR_IA32_VMX_ENTRY_CTLS) >> 32;
@@ -565,7 +566,7 @@ static bool vmcs_setup(struct per_cpu *cpu_data)
val = read_msr(MSR_IA32_VMX_PROCBASED_CTLS2);
val |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
SECONDARY_EXEC_ENABLE_EPT | SECONDARY_EXEC_UNRESTRICTED_GUEST |
- enable_rdtscp;
+ secondary_exec_addon;
ok &= vmcs_write32(SECONDARY_VM_EXEC_CONTROL, val);

ok &= vmcs_write64(APIC_ACCESS_ADDR,
--
2.1.4

Valentine Sinitsyn

unread,
Jul 8, 2016, 1:33:08 PM7/8/16
to Jan Kiszka, Jailhouse
Hi Jan,

On 08.07.2016 22:25, Jan Kiszka wrote:
> Linux kernel 4.6 and later make use of this instruction and crash if we
> do not allow it. It flushes TLB mappings, but only on the caller's
> logical CPU.
Is it Intel-only?

Valentine
С уважением,
Синицын Валентин

Jan Kiszka

unread,
Jul 8, 2016, 1:35:49 PM7/8/16
to Valentine Sinitsyn, Jailhouse
On 2016-07-08 19:33, Valentine Sinitsyn wrote:
> Hi Jan,
>
> On 08.07.2016 22:25, Jan Kiszka wrote:
>> Linux kernel 4.6 and later make use of this instruction and crash if we
>> do not allow it. It flushes TLB mappings, but only on the caller's
>> logical CPU.
> Is it Intel-only?

Yes, I find no traces of this in AMD manuals, and the VMX exec control
is inherently Intel-specific.

Jan

--
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux

Henning Schild

unread,
Jul 13, 2016, 12:24:33 PM7/13/16
to Jan Kiszka, Jailhouse
On Fri, 8 Jul 2016 19:25:39 +0200
Jan Kiszka <jan.k...@siemens.com> wrote:

> Linux kernel 4.6 and later make use of this instruction and crash if
> we do not allow it. It flushes TLB mappings, but only on the caller's
> logical CPU.

Process context IDs are not exactly a recent Intel CPU feature, long
overdue that Linux makes use of them. But looking at the discussion on
the mailinglist the impact for Linux does not seem to be too big, maybe
that is why nobody really bothered.

http://thread.gmane.org/gmane.linux.kernel.mm/144186

Henning
Reply all
Reply to author
Forward
0 new messages