From patchwork Sat Feb 15 01:30:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 13975881 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 123777DA7F for ; Sat, 15 Feb 2025 01:30:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739583024; cv=none; b=cE/8SDASEQ24JGrf77rycYFMwMEJY1iC7SybLr8PxwuSrPpWvFEHhjjvKHACMzhJpkmGFAjXV5fokrRQNvTa+Yz0Wl2EuL5KMp2TaNIRK1xZkxhS46wLzfkQyvQ9lGq7O4YGtMI/1dMC7e7lvG2e0WFgsiMgMQgZpcCKFMN0b5I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739583024; c=relaxed/simple; bh=RJ9S8m5S/5htwo+Mqn9g29LCmRU5ZxB1OpLhbILNGBs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hObHuOUKyTXRYGvhQ79eeRxMOiqjfn3qobTX9oCyldHmjVhIt9sMbiPXI+Nj8Q0BHZdnw8RxgEi4NA7tH3xJJi9c1fabQQtw65oUoK7OqmygorFJMu81mMGqfmD88IMUPlfzTDUQ6HYOvsHYycT9mOBwi6VusxbUrstEcPKrD7A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=jjVaYD2l; arc=none smtp.client-ip=209.85.216.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="jjVaYD2l" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-2fc1a4c150bso5372530a91.2 for ; Fri, 14 Feb 2025 17:30:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1739583022; x=1740187822; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=qfmMC3DUpUVFcoYmpv/vzMrZU9gxNkqownIWIDSwEvc=; b=jjVaYD2lngCRzBJUkqhrX1tpaPwOSDOMt9b2RoDrpnQLM/ZlOd3fuBvOfaGFl9BQM7 RC1LWJtR30BNSaSxguMwkUDOAnAVx6zfudNZY926/dBk+29Bzqj46dJkXNm8i+1057Ct qsSUvB1R6bypQTN1lJDOk9vCY8nrldSm8E7YyPYzPhxyPLuKDLURT3jA6+LRiJzpO89/ CvinPUqi+PBecCQ5l2cUoLU1wLVSETG34iyvtv991EAl9tySXyMFwG5xLM4yBLzSxxkU vyr7dBEzbPL3/8nwtmQM5gjiBjjUyDKCIxB2vLRf5KWfdLAQVIYWlvgonQazLTz/j7vU TXQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739583022; x=1740187822; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=qfmMC3DUpUVFcoYmpv/vzMrZU9gxNkqownIWIDSwEvc=; b=QGi1iCngP8caYVJpUNhF33fmLD1GmOLmT6xdtH8Xg6E9O3IsgCy87f87gYgoT7n5Um 24S8lRksU/CK9tf77BOjXtPAt6urw73lQYU1eKQfXPp0Isa9V/JClmC71wtniBz1ljo+ Ei4PK3dSr5FFJg7lBGBQnaDD8EEgdc9d6CqMjKFyGe6TdgVLtwZIB3odB8/WYYF8CpbI BchXLQ6xwXFDHlpi1LKIAoRs3QAfqAVFqLU6s2rIK3CC+IWMK5HStoKFW2pO+WyFMmox v5YVvZkAuHfXs4MyP7iN+9AcuySs9FLQm5WSawNw4l0akcz63GnJR/HG/aEUCMeudUr9 sQfQ== X-Gm-Message-State: AOJu0YyQdNPh+rn9kkIy5DPVVHAsTI+xuD+KUFIfjcjfVtVRdOBDCaF2 e8WK+nHVZXBtuiOeCEQ73Wn7ZSuKuEk7lZcKPmBuPeorYq7U3RS6nPL9KJrEHYSMlD96xFT5ivW Cpw== X-Google-Smtp-Source: AGHT+IFcd+R/fXqORFeTyTE33uFWiAfbQ4ZKNPMt28u8hsrTCZHRMfjMe9BhrCJMr4MeVC784Yr1sbvLu8w= X-Received: from pjbqa9.prod.google.com ([2002:a17:90b:4fc9:b0:2ef:d136:17fc]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3812:b0:2ee:ead6:6213 with SMTP id 98e67ed59e1d1-2fc40f22e0dmr1739559a91.19.1739583022283; Fri, 14 Feb 2025 17:30:22 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 14 Feb 2025 17:30:13 -0800 In-Reply-To: <20250215013018.1210432-1-seanjc@google.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250215013018.1210432-1-seanjc@google.com> X-Mailer: git-send-email 2.48.1.601.g30ceb7b040-goog Message-ID: <20250215013018.1210432-2-seanjc@google.com> Subject: [kvm-unit-tests PATCH v2 1/6] x86: Add _safe() and _fep_safe() variants to segment base load instructions From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Maxim Levitsky , Sean Christopherson From: Maxim Levitsky Add _safe() and _fep_safe() helpers for segment/base instructions; the helpers will be used to validate various ways of setting the segment bases and GDT/LDT bases. Signed-off-by: Maxim Levitsky Link: https://lore.kernel.org/r/20240907005440.500075-2-mlevitsk@redhat.com Signed-off-by: Sean Christopherson --- lib/x86/desc.h | 4 ++-- lib/x86/processor.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/lib/x86/desc.h b/lib/x86/desc.h index 92c45a48..5349ea57 100644 --- a/lib/x86/desc.h +++ b/lib/x86/desc.h @@ -286,8 +286,8 @@ extern unsigned long get_gdt_entry_limit(gdt_entry_t *entry); #define asm_safe(insn, inputs...) \ __asm_safe("", insn, inputs) -#define asm_fep_safe(insn, output, inputs...) \ - __asm_safe_out1(KVM_FEP, insn, output, inputs) +#define asm_fep_safe(insn, inputs...) \ + __asm_safe_out1(KVM_FEP, insn,, inputs) #define __asm_safe_out1(fep, insn, output, inputs...) \ ({ \ diff --git a/lib/x86/processor.h b/lib/x86/processor.h index da1ed662..9248a06b 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -468,6 +468,11 @@ static inline int rdmsr_safe(u32 index, uint64_t *val) return rdreg64_safe("rdmsr", index, val); } +static inline int rdmsr_fep_safe(u32 index, uint64_t *val) +{ + return __rdreg64_safe(KVM_FEP, "rdmsr", index, val); +} + static inline int wrmsr_safe(u32 index, u64 val) { return wrreg64_safe("wrmsr", index, val); @@ -597,6 +602,16 @@ static inline void lgdt(const struct descriptor_table_ptr *ptr) asm volatile ("lgdt %0" : : "m"(*ptr)); } +static inline int lgdt_safe(const struct descriptor_table_ptr *ptr) +{ + return asm_safe("lgdt %0", "m"(*ptr)); +} + +static inline int lgdt_fep_safe(const struct descriptor_table_ptr *ptr) +{ + return asm_fep_safe("lgdt %0", "m"(*ptr)); +} + static inline void sgdt(struct descriptor_table_ptr *ptr) { asm volatile ("sgdt %0" : "=m"(*ptr)); @@ -607,6 +622,16 @@ static inline void lidt(const struct descriptor_table_ptr *ptr) asm volatile ("lidt %0" : : "m"(*ptr)); } +static inline int lidt_safe(const struct descriptor_table_ptr *ptr) +{ + return asm_safe("lidt %0", "m"(*ptr)); +} + +static inline int lidt_fep_safe(const struct descriptor_table_ptr *ptr) +{ + return asm_fep_safe("lidt %0", "m"(*ptr)); +} + static inline void sidt(struct descriptor_table_ptr *ptr) { asm volatile ("sidt %0" : "=m"(*ptr)); @@ -617,6 +642,16 @@ static inline void lldt(u16 val) asm volatile ("lldt %0" : : "rm"(val)); } +static inline int lldt_safe(u16 val) +{ + return asm_safe("lldt %0", "rm"(val)); +} + +static inline int lldt_fep_safe(u16 val) +{ + return asm_safe("lldt %0", "rm"(val)); +} + static inline u16 sldt(void) { u16 val; @@ -629,6 +664,16 @@ static inline void ltr(u16 val) asm volatile ("ltr %0" : : "rm"(val)); } +static inline int ltr_safe(u16 val) +{ + return asm_safe("ltr %0", "rm"(val)); +} + +static inline int ltr_fep_safe(u16 val) +{ + return asm_safe("ltr %0", "rm"(val)); +} + static inline u16 str(void) { u16 val; From patchwork Sat Feb 15 01:30:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 13975882 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE79013FD72 for ; Sat, 15 Feb 2025 01:30:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739583026; cv=none; b=NO70tDDxkyAM9BCDq4CxKmV1iuNmIOTR80qT68NtiYYQUbi5y3Z2GmpXERv6rdIC6iQWHn1UVZobQEUkSwWXhvgCQXfy/QxsiBZ8/w9/gjaBsLi4vu+FGSK+mNm062gk5NvXrRlLk/Osl5sd6VRWaUt2YGrXgN3E8DW+lxEiQQI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739583026; c=relaxed/simple; bh=DHIuIRI+ndOnIUw/E1wdY2QcqzXJN92i2bk9NrSFkak=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=qeV+V7BywnJBWTzKZshaFJSX0AS3oXKjZ6sKt5bNjgu/gQOSjm3eGrbncSZNJ6IHW8wgJ0B21NdKZ9FBl2kFq4RKBn/njT6qWDiL78jBzwc9PvRKw9isna2/PeLKfe1dDAV1EdyhpssTiM4C71DIzCa9QXz6GMmrSXahwqeT+kU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=VJG7mAQA; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="VJG7mAQA" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-2fc1c3b3dc7so4433033a91.2 for ; Fri, 14 Feb 2025 17:30:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1739583024; x=1740187824; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=nozmXbxSIKpXqMg01+BWyfff9AU705l9LcnoqO5/Xco=; b=VJG7mAQAlu9CUygG+w3Gx8B62n5IGIr5WEnVj3xgQoEFYoJ7titAYaSd2ffKmPZ3D2 oNON6lOD3ulV0HG4VEhGvLX5vtNvoix33gWd5kJankt69bz2nnZSJShe65CA1vBJQqEm 9+aDaiuD7wqqdjifK3acGAtks8BnYFeKDtWs+G5GkuELm+jM3K/mzdNRABQX/EDH0Avd aZvd9b7jmO+sxiUk/G7KFe36+xfEeq3aOIviRvYXR4ZTaifiGfgPzc7QBRxqpvKjeQLW c3gpjUTZo0HpjqLqn87t689+smRBd+Ym9QHsWd8MQ1Aswf21pipj21xsmIytQrm1yMJX jmSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739583024; x=1740187824; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=nozmXbxSIKpXqMg01+BWyfff9AU705l9LcnoqO5/Xco=; b=BKBTj8rBlh/81glmBBa6GdhdJ9TDRdosQnF91s46kl1WV2Ty66hvsmaOucqkZSOHj2 e89Jn8K/fxc5IglCwOkX4ptgtZeUwd/CD6+uHhzfF1305+NLEs7BKqhwM2SF9WwH7D6o TYHXf+ql+c/dl+8bhQ7d08P6+U+8KjWKpBRQckdUt66Bvn72nbheLunE4jf3JHOfG/ey bZ4ak0LGr6l9SMCH8uebELTS2OnadBg9DIfXIZNhh+MP+FtWgHNKfuxm6xWRvbErDDld g3E6g1q+QCTqdTUPnbJRd3H5A0t6QrBLPnYexx7IREXYbskZXhAdd7MArCebZow3O/5o 0EpQ== X-Gm-Message-State: AOJu0Yxgn8iaV3Veq4SdEvjOcBEvfQ5+c7ZNajg2W4mvv1kzdGjzEoKC TwlsLP4F3KnnpGJB/Rzj9Pyjx1vBqgCLpHn5lLGfbYXeaqgySSDE4ieHV1fTbmJxyjFzQLdNdqv H4Q== X-Google-Smtp-Source: AGHT+IHdTPrucKczM4E1WKm8Q2HUHogK4sU3LcaivRQ2CnoUdgGgrs013nwBUJiXrLRCOmU750ocFsur+Tg= X-Received: from pjbmf13.prod.google.com ([2002:a17:90b:184d:b0:2fa:26f0:c221]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:1b4b:b0:2f2:3efd:96da with SMTP id 98e67ed59e1d1-2fc41045e35mr2132033a91.24.1739583023983; Fri, 14 Feb 2025 17:30:23 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 14 Feb 2025 17:30:14 -0800 In-Reply-To: <20250215013018.1210432-1-seanjc@google.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250215013018.1210432-1-seanjc@google.com> X-Mailer: git-send-email 2.48.1.601.g30ceb7b040-goog Message-ID: <20250215013018.1210432-3-seanjc@google.com> Subject: [kvm-unit-tests PATCH v2 2/6] x86: Add a few functions for gdt manipulation From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Maxim Levitsky , Sean Christopherson From: Maxim Levitsky Add a few functions that will be used to manipulate various segment bases that are loaded via GDT. Signed-off-by: Maxim Levitsky Link: https://lore.kernel.org/r/20240907005440.500075-3-mlevitsk@redhat.com Signed-off-by: Sean Christopherson --- lib/x86/desc.c | 38 +++++++++++++++++++++++++++++++------- lib/x86/desc.h | 5 +++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/lib/x86/desc.c b/lib/x86/desc.c index d054899c..acfada26 100644 --- a/lib/x86/desc.c +++ b/lib/x86/desc.c @@ -338,7 +338,7 @@ bool exception_rflags_rf(void) static char intr_alt_stack[4096]; -void set_gdt_entry(int sel, unsigned long base, u32 limit, u8 type, u8 flags) +void set_gdt_entry_base(int sel, unsigned long base) { gdt_entry_t *entry = &gdt[sel >> 3]; @@ -347,10 +347,6 @@ void set_gdt_entry(int sel, unsigned long base, u32 limit, u8 type, u8 flags) entry->base2 = (base >> 16) & 0xFF; entry->base3 = (base >> 24) & 0xFF; - /* Setup the descriptor limits, type and flags */ - entry->limit1 = (limit & 0xFFFF); - entry->type_limit_flags = ((limit & 0xF0000) >> 8) | ((flags & 0xF0) << 8) | type; - #ifdef __x86_64__ if (!entry->s) { struct system_desc64 *entry16 = (struct system_desc64 *)entry; @@ -360,6 +356,24 @@ void set_gdt_entry(int sel, unsigned long base, u32 limit, u8 type, u8 flags) #endif } +void set_gdt_entry(int sel, unsigned long base, u32 limit, u8 type, u8 flags) +{ + gdt_entry_t *entry = &gdt[sel >> 3]; + + /* Setup the descriptor limits, type and flags */ + entry->limit1 = (limit & 0xFFFF); + entry->type_limit_flags = ((limit & 0xF0000) >> 8) | ((flags & 0xF0) << 8) | type; + set_gdt_entry_base(sel, base); +} + +void clear_tss_busy(int sel) +{ + gdt_entry_t *entry = &gdt[sel >> 3]; + + entry->type_limit_flags &= ~0xFF; + entry->type_limit_flags |= 0x89; +} + void load_gdt_tss(size_t tss_offset) { lgdt(&gdt_descr); @@ -483,14 +497,24 @@ void __set_exception_jmpbuf(jmp_buf *addr) exception_jmpbuf = addr; } -gdt_entry_t *get_tss_descr(void) +gdt_entry_t *get_gdt_entry(u16 sel) { struct descriptor_table_ptr gdt_ptr; gdt_entry_t *gdt; sgdt(&gdt_ptr); gdt = (gdt_entry_t *)gdt_ptr.base; - return &gdt[str() / 8]; + return &gdt[sel / 8]; +} + +gdt_entry_t *get_tss_descr(void) +{ + return get_gdt_entry(str()); +} + +gdt_entry_t *get_ldt_descr(void) +{ + return get_gdt_entry(sldt()); } unsigned long get_gdt_entry_base(gdt_entry_t *entry) diff --git a/lib/x86/desc.h b/lib/x86/desc.h index 5349ea57..a50c8f61 100644 --- a/lib/x86/desc.h +++ b/lib/x86/desc.h @@ -246,6 +246,8 @@ void set_idt_entry(int vec, void *addr, int dpl); void set_idt_sel(int vec, u16 sel); void set_idt_dpl(int vec, u16 dpl); void set_gdt_entry(int sel, unsigned long base, u32 limit, u8 access, u8 gran); +void set_gdt_entry_base(int sel, unsigned long base); +void clear_tss_busy(int sel); void load_gdt_tss(size_t tss_offset); void set_intr_alt_stack(int e, void *fn); void print_current_tss_info(void); @@ -268,7 +270,10 @@ static inline void *get_idt_addr(idt_entry_t *entry) return (void *)addr; } +extern gdt_entry_t *get_gdt_entry(u16 sel); extern gdt_entry_t *get_tss_descr(void); +gdt_entry_t *get_ldt_descr(void); + extern unsigned long get_gdt_entry_base(gdt_entry_t *entry); extern unsigned long get_gdt_entry_limit(gdt_entry_t *entry); From patchwork Sat Feb 15 01:30:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 13975883 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5AE767DA62 for ; Sat, 15 Feb 2025 01:30:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739583027; cv=none; b=oMF1Z8uUpiMxFj/VDoqjhVjAf3DdXe5Ir0sLcSR1TBKubCFp6C48qh42jtddj+zGWe69s3mJgHw5Lx7zAzKY3z4V/sLhBkFRrn3n4RmbYr9wY+2sWFrWYPc0w7RrRtUmtMhx6eQZuBAyn3K6EkBCeFs4CcVgEiZ99nbfi8TT384= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739583027; c=relaxed/simple; bh=c1AIaGnuJeM1AeYU4D16fG2sEhaecw/3jBmKDGCdMD4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=KbSnm9wpytSRWQu9NT41BjMnH3dgGjHn7DTXdc/dgPn64oOOyVDQr2f77yFylFyQ4I2XJwxulCAPsMhx5m3jfVNqCQ3pjL2wk/s4tozi7MVbb3wlIv9/6GTyYA+7jaMrzHHhXRgrlfkmhDbCaG2DUwq1o/4Wk50zdFKeN1xo0+g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Bw5Xy1Se; arc=none smtp.client-ip=209.85.216.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Bw5Xy1Se" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-2fa57c42965so5609939a91.1 for ; Fri, 14 Feb 2025 17:30:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1739583026; x=1740187826; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=x4s7pFI0aY9o6O21bKm5JYyoqQO0/jilZnXQOfrGt04=; b=Bw5Xy1SexwJ5fneDyzJramMt4I85W/B8dyh45GBc18842Droam7x827F5Ego322q/r w2zJ/hToLv9fHpRQaIJqnUagty2FJX8+f4Us9L0fu+3y42+6SPXTE85SCWiGWwoptUE7 V6jDg89pJmvHXJZB/unFwRI8X9pxsZKfEI4CQjGYLYMjRB145inSYPw3fPpW8DvNKdHY Jg+ipQNC9C5+ES03h6DcWYXHRc4Ec7t2ZETFGzJ8Mc6dPBDgTMylgC1SbyT22VblfLRN MMPfu8kEnf9dHHOmRwSFxG+/PTJW2jr0nviG3cnxOp+uKh/1Z/MC3w9LngpePwBzR8WS FegA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739583026; x=1740187826; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=x4s7pFI0aY9o6O21bKm5JYyoqQO0/jilZnXQOfrGt04=; b=Ap7QK8M5whixx3vS9HFUwYi9HXntf5MsYAJLzEKOMU4hOfSZt9ZWha0kWdNz1Gp6sh 3KddaoqMiGKq9798WFKh4zxB6kwZZQO91DJMF8BGv3E/JUpPINXEGdmPCY3t+qFit3dA QV0XKB2byvClsXRkCKpisqG5QHFtkxDtBkymn24MvhXJ/VYjlSgGKv4oLoomtu/LoWoo gDtpGL1V+LoJ6u05tOO3AxxBnnuJiPjM8s60diwP7p6w7Y37V3/jkloBTWpTARiCzvWJ HSrGrNPHfFjieCed6wC58sirVIehEbaE16yIgnfFQ6tDKEzPf+fTM0FoswyPJ4ZCdy/u Mhkg== X-Gm-Message-State: AOJu0YyT8zqqs4m26xeMpMNLhmCVwHRyEd6eY9YtdqwHqlLWByQ4ulJM /4nEVGoHAeAQe1n9sCmRVYatXvszSiFl5VThJNHXIgBOdbD5EToJpf7YLaPcqCf/+1WTvIx+HTT idA== X-Google-Smtp-Source: AGHT+IEAFDp4Wh/lvhwQ7icQNdKaeJpkXkkSi2JKZ1n58yZhBJ9hX8TXrSnvFutznkk40EXIA+hTKHBv9iU= X-Received: from pfbbd15.prod.google.com ([2002:a05:6a00:278f:b0:730:89cf:cf2e]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:4f95:b0:730:8768:76d7 with SMTP id d2e1a72fcca58-732618c29a9mr2122216b3a.17.1739583025757; Fri, 14 Feb 2025 17:30:25 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 14 Feb 2025 17:30:15 -0800 In-Reply-To: <20250215013018.1210432-1-seanjc@google.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250215013018.1210432-1-seanjc@google.com> X-Mailer: git-send-email 2.48.1.601.g30ceb7b040-goog Message-ID: <20250215013018.1210432-4-seanjc@google.com> Subject: [kvm-unit-tests PATCH v2 3/6] x86: Move struct invpcid_desc descriptor to processor.h From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Maxim Levitsky , Sean Christopherson From: Maxim Levitsky Move struct invpcid_desc descriptor to processor.h so that it can be used in tests that are external to pcid.c. Signed-off-by: Maxim Levitsky Link: https://lore.kernel.org/r/20240907005440.500075-4-mlevitsk@redhat.com Signed-off-by: Sean Christopherson --- lib/x86/processor.h | 7 ++++++- x86/pcid.c | 6 ------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/x86/processor.h b/lib/x86/processor.h index 9248a06b..bb54ec61 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -836,8 +836,13 @@ static inline void invlpg(volatile void *va) asm volatile("invlpg (%0)" ::"r" (va) : "memory"); } +struct invpcid_desc { + u64 pcid : 12; + u64 rsv : 52; + u64 addr : 64; +}; -static inline int invpcid_safe(unsigned long type, void *desc) +static inline int invpcid_safe(unsigned long type, struct invpcid_desc *desc) { /* invpcid (%rax), %rbx */ return asm_safe(".byte 0x66,0x0f,0x38,0x82,0x18", "a" (desc), "b" (type)); diff --git a/x86/pcid.c b/x86/pcid.c index c503efb8..7425e0fe 100644 --- a/x86/pcid.c +++ b/x86/pcid.c @@ -4,12 +4,6 @@ #include "processor.h" #include "desc.h" -struct invpcid_desc { - u64 pcid : 12; - u64 rsv : 52; - u64 addr : 64; -}; - static void test_pcid_enabled(void) { int passed = 0; From patchwork Sat Feb 15 01:30:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 13975884 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1F4ED151985 for ; Sat, 15 Feb 2025 01:30:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739583029; cv=none; b=b/2uMUSORSDhj0xbdKijwwJYM084Kp27a1qWwlVIvu5/GNCnappUWxsOK/EHYlarIHT9dGPSaOPJowOYg5w2zbT05Rvl+6rhcPfHEXtiVhbsdUEwTZJ5a70CNoOoOVJ3oSamvHUr4zOB4/EVQgWqlughYkKzSuU3fAY1vkZ/BWU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739583029; c=relaxed/simple; bh=V0fJ4VH6oNplMlatOTJIZHaORH/sgyQ8OkXwtWJst7U=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=p5o+Bqxaa87o3o2JMfEF/rw5QDtL4OgDQvnRgL37e8Kppvkiphy8MZbbN9x7nN7N7IG3Zigcd/s4z+dJ6yZGT8Aj1OgDwZfE71q80pWtbhntD255lYlNl4LF8zolJzhxJj320MFNd2ocTA8gWlzVAkDT09afSRnfSwfO0snrdNU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=3BkvRe6s; arc=none smtp.client-ip=209.85.214.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="3BkvRe6s" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-21a7cbe3b56so43725625ad.0 for ; Fri, 14 Feb 2025 17:30:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1739583027; x=1740187827; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=ETGgC6G+yyJ54bJkFbhvWzGmT5jKr731rfTGJSUN2mc=; b=3BkvRe6sxES8ZQCl/nPJRaV97mGDEeR9Ji4krkMLPHD2TQOIJFT0vQAptGVWc13229 DGnAXTIOPQR1YdHoszsrHV68ugrPNKh6Ika1vyYy1Sc6wupcI6Qt7T+RgbrQM89I2FHY Y7LNSefmCRJoiewYBnaF5qH9qHX+zZvY4ScCJbjbblY57v9FYKuOAivv5ITm6UqhNnQ4 +TXmfn+t3gPJ93yu4Bst8UnEq2FOuscuIzYKSrgCIBFaW4U9kOrLXmr6tXUXfvFz6lAc I75EHz//5kttWfNKFb07boRDlvUC+xdZKykezTLN2xnjmwuXYWSOICM2/2cGq9LCvKFT BJ7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739583027; x=1740187827; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=ETGgC6G+yyJ54bJkFbhvWzGmT5jKr731rfTGJSUN2mc=; b=aJPoCap6o80NBvp62/c/5/OcU7QOadbKHjOs9c1rAgYEeLH1IvUfj0bvdTwVjAmhAp /u8bR88x5IqvZlq5v1Rh9zKTyhIr/k92Av5MAuq57NmO6HosIj2EiX7vE+TjD06t9rca KMPpmMs6ugX7teZEno0287hNBXp3Qkn9bbsDCbIGOtDWFq2u6ZoqtQGihyCttcgmltSJ DEIyLmZMwO+0eiO7xJVXmJxYfmdJPmUGhpBEdGABDomdLkIYWo8dYmWxPHABB9UUlzzb VNFSoESL1cyRareyUJxtsednbxmLWGYoLuDq9oNr/pfJxsJj7UReNgWxpeNaq2G1Gs7X JhMQ== X-Gm-Message-State: AOJu0YzkEQiAkfXv0pZLk+ORayDoyHaJnEriZ1N4Yf7Wg4+AA7jy7dWC WkzEMTq2Z2M/rNpT15XQWrue2wmkissUdwUozIslGm7cokOt+4pfB/jmGr2R8VY0NJEh3QDa8iM Y9g== X-Google-Smtp-Source: AGHT+IHmiEjUY8dAY3gFQhXlG29+x9LoGTSVS5YYDna26w7Vw6FRskQKrm6q6Kqg8v2Z5TpwfdpWV8cipaU= X-Received: from pjbhl3.prod.google.com ([2002:a17:90b:1343:b0:2fc:15bf:92f6]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:41c8:b0:216:3466:7414 with SMTP id d9443c01a7336-221040bcc46mr25577295ad.44.1739583027400; Fri, 14 Feb 2025 17:30:27 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 14 Feb 2025 17:30:16 -0800 In-Reply-To: <20250215013018.1210432-1-seanjc@google.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250215013018.1210432-1-seanjc@google.com> X-Mailer: git-send-email 2.48.1.601.g30ceb7b040-goog Message-ID: <20250215013018.1210432-5-seanjc@google.com> Subject: [kvm-unit-tests PATCH v2 4/6] x86: Expand LA57 test to 64-bit mode (to prep for canonical testing) From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Maxim Levitsky , Sean Christopherson Expand the LA57 test to also validate that attempting to toggle LA57 while in 64-bit mode fails. The extra test coverage isn't terribly interesting, but it's still useful, and extending the LA57 test to 64-bit configs will allow extending it further with LA57-specific canonical tests. Signed-off-by: Sean Christopherson --- x86/Makefile.common | 3 ++- x86/Makefile.i386 | 2 +- x86/la57.c | 9 ++++++--- x86/unittests.cfg | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/x86/Makefile.common b/x86/Makefile.common index 4ae9a557..0b7f35c8 100644 --- a/x86/Makefile.common +++ b/x86/Makefile.common @@ -96,7 +96,8 @@ tests-common = $(TEST_DIR)/vmexit.$(exe) $(TEST_DIR)/tsc.$(exe) \ # use absolute addresses in their inline assembly code, which cannot compile # with the '-fPIC' flag ifneq ($(CONFIG_EFI),y) -tests-common += $(TEST_DIR)/realmode.$(exe) +tests-common += $(TEST_DIR)/realmode.$(exe) \ + $(TEST_DIR)/la57.$(exe) endif test_cases: $(tests-common) $(tests) diff --git a/x86/Makefile.i386 b/x86/Makefile.i386 index 0a845e65..a1ea1c2d 100644 --- a/x86/Makefile.i386 +++ b/x86/Makefile.i386 @@ -9,6 +9,6 @@ arch_LDFLAGS = -m elf_i386 cflatobjs += lib/x86/setjmp32.o lib/ldiv32.o tests = $(TEST_DIR)/taskswitch.$(exe) $(TEST_DIR)/taskswitch2.$(exe) \ - $(TEST_DIR)/cmpxchg8b.$(exe) $(TEST_DIR)/la57.$(exe) + $(TEST_DIR)/cmpxchg8b.$(exe) include $(SRCDIR)/$(TEST_DIR)/Makefile.common diff --git a/x86/la57.c b/x86/la57.c index 1f11412c..aff35ead 100644 --- a/x86/la57.c +++ b/x86/la57.c @@ -5,9 +5,12 @@ int main(int ac, char **av) { int vector = write_cr4_safe(read_cr4() | X86_CR4_LA57); - int expected = this_cpu_has(X86_FEATURE_LA57) ? 0 : 13; + bool is_64bit = rdmsr(MSR_EFER) & EFER_LMA; + int expected = !is_64bit && this_cpu_has(X86_FEATURE_LA57) ? 0 : GP_VECTOR; + + report(vector == expected, "%s when CR4.LA57 %ssupported (in %u-bit mode)", + expected ? "#GP" : "No fault", + this_cpu_has(X86_FEATURE_LA57) ? "un" : "", is_64bit ? 64 : 32); - report(vector == expected, "%s when CR4.LA57 %ssupported", - expected ? "#GP" : "No fault", expected ? "un" : ""); return report_summary(); } diff --git a/x86/unittests.cfg b/x86/unittests.cfg index 7c1691a9..665f3d4c 100644 --- a/x86/unittests.cfg +++ b/x86/unittests.cfg @@ -316,7 +316,7 @@ extra_params = -cpu qemu64,+umip [la57] file = la57.flat -arch = i386 +extra_params = -cpu max,host-phys-bits [vmx] file = vmx.flat From patchwork Sat Feb 15 01:30:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 13975885 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5314B5103F for ; Sat, 15 Feb 2025 01:30:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739583031; cv=none; b=bTU6ql8D7NC5R0fAeDbkD2q4yvnfH0Mlj5iPXNFwVKyTWUbsYaJJNOP2KRIzQETHWkTBDNw2EE1rF96xAiHS3DlTKJpmWsocGAI6CikgoMlUm/qc0oajhl9sp/mZ+NcNatW+2/k6IL/p054rBJnGYBdUYPTcKJE0pU4xIzcrfpE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739583031; c=relaxed/simple; bh=mwz5QcwW9jgOSBKmmQD/+HauyGrfkwfJrF+CkxGAzws=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=B6iZmX2kEu+5UgyEhWneKV8YIRGGyhlzXD9PQkyDNdWohB6Xz03K7R7e8FH68Samanqg+r6brKsu3ctVafpp3Ad+WCk/Hvd+DlPDFta+cY9NGuBa7R6OHqKXAyBX9enZHmzNkVR2YiFX1pYdql4O6qxp7NkthPHz1kag+bn/UhE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=fI9Z1DOb; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="fI9Z1DOb" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-2fc404aaed5so1019202a91.3 for ; Fri, 14 Feb 2025 17:30:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1739583029; x=1740187829; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=y2g/OmxUsvKV+8oequFLjqUZQ69y0ZK14wwkZI8Rs1I=; b=fI9Z1DObP5kUB8RjRQDMOpeOwk4v2hvcmw1eax6FloEDy1nE+zoRXbFfoJKvwntVV5 cmrTInwky7CU+UBMh76qX3yaYUxvWYM5o7Tt/Bb+H9R5J38ueU6u6ioHSzZMTpNxCSAw 3/FJ4VffmyymYm13lZCkMbc+a7cWXCr5WYCiuTLdnqPewUCJEemWk9jQq8wtsHBejPQK n6xg7aNsUx23eNq2ADtmzr8JWeYQeKPLJhZCceLDZsK2iqfy3THvCr7/ZY6YATi9Fd6S xDtu870nUMfJOqrMI1jKAV2zEZmfQrBSTcIACaOh6gj+2IHv1klzpQzbmAUosYMUa6xx xs1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739583029; x=1740187829; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=y2g/OmxUsvKV+8oequFLjqUZQ69y0ZK14wwkZI8Rs1I=; b=cguUhf8azuajO2DK0sz8f91WGLIZvuwuPAiVywcIeqc0RrE/7j19ZMJVENPLnMB0KX 7rPoAtW7USt1CQGMlQE41vPKZa1zpY0Klja9VJDREi/4yl6RpB44hX/zEik8wzsOFFxj cFCYPer+TVoTE4f6boFUxQYU3p3c704ADQGZN2b+4CT+qsWhEohuhqnHpM3JfjZ9xxEQ GnXfvTMnQzU6lbSlkUjvBDcaV+ETibmVJOPOGnP7cb0m4+IDqe0FhzL7Xakq+NFhkScU Chct6vH4oNg5J+0kAEprJbmOIAHa8BAu6VVC5fjvI6jvKDVMFhV1PhVwzD78JOKNodw2 wD5w== X-Gm-Message-State: AOJu0YwZRdYh63mpO6GwMwWT0yrD8msTp8AdrcazuHSr+9tkq4YtHe6u oYsIT0LU0vSROttbEQcHGP8j0igecmg1F3KXUXG22JHaHpVRZGQLrW9dAEeJdJsoS7tJhjxIgDy YcA== X-Google-Smtp-Source: AGHT+IHtTpfJ5lNbMPEiZ87Cpm67I2edlxTJj8FnJXgUKzpzCIACvJ0/ZAdo93zuN81ZbJG7MwmiLa3tdfM= X-Received: from pjf15.prod.google.com ([2002:a17:90b:3f0f:b0:2f4:465d:5c61]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3ec5:b0:2f6:be57:49d2 with SMTP id 98e67ed59e1d1-2fc40f22cefmr2309354a91.17.1739583028892; Fri, 14 Feb 2025 17:30:28 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 14 Feb 2025 17:30:17 -0800 In-Reply-To: <20250215013018.1210432-1-seanjc@google.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250215013018.1210432-1-seanjc@google.com> X-Mailer: git-send-email 2.48.1.601.g30ceb7b040-goog Message-ID: <20250215013018.1210432-6-seanjc@google.com> Subject: [kvm-unit-tests PATCH v2 5/6] x86: Add testcases for writing (non)canonical LA57 values to MSRs and bases From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Maxim Levitsky , Sean Christopherson From: Maxim Levitsky Extend the LA57 test to thoroughly validate the canonical checks that are done when setting various MSRs and CPU registers. CPUs that support LA57 have convoluted behavior when it comes to canonical checks. Writes to MSRs, descriptor table bases, and for TLB invalidation instructions, don't consult CR4.LA57, and so a value that is 57-bit canonical but not 48-bit canonical is allowed irrespective of CR4.LA57 if the CPU supports 5-level paging. Signed-off-by: Maxim Levitsky Link: https://lore.kernel.org/r/20240907005440.500075-5-mlevitsk@redhat.com Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson --- lib/x86/msr.h | 42 ++++++ lib/x86/processor.h | 6 +- x86/la57.c | 333 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 379 insertions(+), 2 deletions(-) diff --git a/lib/x86/msr.h b/lib/x86/msr.h index 8abccf86..658d237f 100644 --- a/lib/x86/msr.h +++ b/lib/x86/msr.h @@ -131,6 +131,48 @@ #define MSR_P6_EVNTSEL0 0x00000186 #define MSR_P6_EVNTSEL1 0x00000187 +#define MSR_IA32_RTIT_CTL 0x00000570 +#define RTIT_CTL_TRACEEN BIT(0) +#define RTIT_CTL_CYCLEACC BIT(1) +#define RTIT_CTL_OS BIT(2) +#define RTIT_CTL_USR BIT(3) +#define RTIT_CTL_PWR_EVT_EN BIT(4) +#define RTIT_CTL_FUP_ON_PTW BIT(5) +#define RTIT_CTL_FABRIC_EN BIT(6) +#define RTIT_CTL_CR3EN BIT(7) +#define RTIT_CTL_TOPA BIT(8) +#define RTIT_CTL_MTC_EN BIT(9) +#define RTIT_CTL_TSC_EN BIT(10) +#define RTIT_CTL_DISRETC BIT(11) +#define RTIT_CTL_PTW_EN BIT(12) +#define RTIT_CTL_BRANCH_EN BIT(13) +#define RTIT_CTL_EVENT_EN BIT(31) +#define RTIT_CTL_NOTNT BIT_ULL(55) +#define RTIT_CTL_MTC_RANGE_OFFSET 14 +#define RTIT_CTL_MTC_RANGE (0x0full << RTIT_CTL_MTC_RANGE_OFFSET) +#define RTIT_CTL_CYC_THRESH_OFFSET 19 +#define RTIT_CTL_CYC_THRESH (0x0full << RTIT_CTL_CYC_THRESH_OFFSET) +#define RTIT_CTL_PSB_FREQ_OFFSET 24 +#define RTIT_CTL_PSB_FREQ (0x0full << RTIT_CTL_PSB_FREQ_OFFSET) +#define RTIT_CTL_ADDR0_OFFSET 32 +#define RTIT_CTL_ADDR0 (0x0full << RTIT_CTL_ADDR0_OFFSET) +#define RTIT_CTL_ADDR1_OFFSET 36 +#define RTIT_CTL_ADDR1 (0x0full << RTIT_CTL_ADDR1_OFFSET) +#define RTIT_CTL_ADDR2_OFFSET 40 +#define RTIT_CTL_ADDR2 (0x0full << RTIT_CTL_ADDR2_OFFSET) +#define RTIT_CTL_ADDR3_OFFSET 44 +#define RTIT_CTL_ADDR3 (0x0full << RTIT_CTL_ADDR3_OFFSET) + + +#define MSR_IA32_RTIT_ADDR0_A 0x00000580 +#define MSR_IA32_RTIT_ADDR0_B 0x00000581 +#define MSR_IA32_RTIT_ADDR1_A 0x00000582 +#define MSR_IA32_RTIT_ADDR1_B 0x00000583 +#define MSR_IA32_RTIT_ADDR2_A 0x00000584 +#define MSR_IA32_RTIT_ADDR2_B 0x00000585 +#define MSR_IA32_RTIT_ADDR3_A 0x00000586 +#define MSR_IA32_RTIT_ADDR3_B 0x00000587 + /* AMD64 MSRs. Not complete. See the architecture manual for a more complete list. */ diff --git a/lib/x86/processor.h b/lib/x86/processor.h index bb54ec61..f05175af 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -7,7 +7,9 @@ #include #include -#define NONCANONICAL 0xaaaaaaaaaaaaaaaaull +#define CANONICAL_48_VAL 0xffffaaaaaaaaaaaaull +#define CANONICAL_57_VAL 0xffaaaaaaaaaaaaaaull +#define NONCANONICAL 0xaaaaaaaaaaaaaaaaull #ifdef __x86_64__ # define R "r" @@ -241,6 +243,7 @@ static inline bool is_intel(void) #define X86_FEATURE_MCE (CPUID(0x1, 0, EDX, 7)) #define X86_FEATURE_APIC (CPUID(0x1, 0, EDX, 9)) #define X86_FEATURE_CLFLUSH (CPUID(0x1, 0, EDX, 19)) +#define X86_FEATURE_DS (CPUID(0x1, 0, EDX, 21)) #define X86_FEATURE_XMM (CPUID(0x1, 0, EDX, 25)) #define X86_FEATURE_XMM2 (CPUID(0x1, 0, EDX, 26)) #define X86_FEATURE_TSC_ADJUST (CPUID(0x7, 0, EBX, 1)) @@ -252,6 +255,7 @@ static inline bool is_intel(void) #define X86_FEATURE_PCOMMIT (CPUID(0x7, 0, EBX, 22)) #define X86_FEATURE_CLFLUSHOPT (CPUID(0x7, 0, EBX, 23)) #define X86_FEATURE_CLWB (CPUID(0x7, 0, EBX, 24)) +#define X86_FEATURE_INTEL_PT (CPUID(0x7, 0, EBX, 25)) #define X86_FEATURE_UMIP (CPUID(0x7, 0, ECX, 2)) #define X86_FEATURE_PKU (CPUID(0x7, 0, ECX, 3)) #define X86_FEATURE_LA57 (CPUID(0x7, 0, ECX, 16)) diff --git a/x86/la57.c b/x86/la57.c index aff35ead..41764110 100644 --- a/x86/la57.c +++ b/x86/la57.c @@ -1,6 +1,324 @@ #include "libcflat.h" +#include "apic.h" #include "processor.h" -#include "desc.h" +#include "msr.h" +#include "x86/vm.h" +#include "asm/setup.h" + +#ifdef __x86_64__ +enum TEST_REGISTER { + TEST_REGISTER_GDTR_BASE, + TEST_REGISTER_IDTR_BASE, + TEST_REGISTER_TR_BASE, + TEST_REGISTER_LDT_BASE, + TEST_REGISTER_MSR /* upper 32 bits = msr address */ +}; + +static u64 get_test_register_value(u64 test_register) +{ + struct descriptor_table_ptr dt_ptr; + u32 msr = test_register >> 32; + + /* + * Note: value for LDT and TSS base might not reflect the actual base + * that the CPU currently uses, because the (hidden) base value can't be + * directly read. + */ + switch ((u32)test_register) { + case TEST_REGISTER_GDTR_BASE: + sgdt(&dt_ptr); + return dt_ptr.base; + case TEST_REGISTER_IDTR_BASE: + sidt(&dt_ptr); + return dt_ptr.base; + case TEST_REGISTER_TR_BASE: + return get_gdt_entry_base(get_tss_descr()); + case TEST_REGISTER_LDT_BASE: + return get_gdt_entry_base(get_ldt_descr()); + case TEST_REGISTER_MSR: + return rdmsr(msr); + default: + assert(0); + return 0; + } +} + +enum SET_REGISTER_MODE { + SET_REGISTER_MODE_UNSAFE, + SET_REGISTER_MODE_SAFE, + SET_REGISTER_MODE_FEP, +}; + +static bool set_test_register_value(u64 test_register, int test_mode, u64 value) +{ + struct descriptor_table_ptr dt_ptr; + u32 msr = test_register >> 32; + u16 sel; + + switch ((u32)test_register) { + case TEST_REGISTER_GDTR_BASE: + sgdt(&dt_ptr); + dt_ptr.base = value; + + switch (test_mode) { + case SET_REGISTER_MODE_UNSAFE: + lgdt(&dt_ptr); + return true; + case SET_REGISTER_MODE_SAFE: + return lgdt_safe(&dt_ptr) == 0; + case SET_REGISTER_MODE_FEP: + return lgdt_fep_safe(&dt_ptr) == 0; + } + case TEST_REGISTER_IDTR_BASE: + sidt(&dt_ptr); + dt_ptr.base = value; + + switch (test_mode) { + case SET_REGISTER_MODE_UNSAFE: + lidt(&dt_ptr); + return true; + case SET_REGISTER_MODE_SAFE: + return lidt_safe(&dt_ptr) == 0; + case SET_REGISTER_MODE_FEP: + return lidt_fep_safe(&dt_ptr) == 0; + } + case TEST_REGISTER_TR_BASE: + sel = str(); + set_gdt_entry_base(sel, value); + clear_tss_busy(sel); + + switch (test_mode) { + case SET_REGISTER_MODE_UNSAFE: + ltr(sel); + return true; + case SET_REGISTER_MODE_SAFE: + return ltr_safe(sel) == 0; + case SET_REGISTER_MODE_FEP: + return ltr_fep_safe(sel) == 0; + } + + case TEST_REGISTER_LDT_BASE: + sel = sldt(); + set_gdt_entry_base(sel, value); + + switch (test_mode) { + case SET_REGISTER_MODE_UNSAFE: + lldt(sel); + return true; + case SET_REGISTER_MODE_SAFE: + return lldt_safe(sel) == 0; + case SET_REGISTER_MODE_FEP: + return lldt_fep_safe(sel) == 0; + } + case TEST_REGISTER_MSR: + switch (test_mode) { + case SET_REGISTER_MODE_UNSAFE: + wrmsr(msr, value); + return true; + case SET_REGISTER_MODE_SAFE: + return wrmsr_safe(msr, value) == 0; + case SET_REGISTER_MODE_FEP: + return wrmsr_fep_safe(msr, value) == 0; + } + default: + assert(false); + return 0; + } +} + +static void test_register_write(const char *register_name, u64 test_register, + bool force_emulation, u64 test_value, + bool expect_success) +{ + int test_mode = (force_emulation ? SET_REGISTER_MODE_FEP : SET_REGISTER_MODE_SAFE); + u64 old_value, expected_value; + bool success; + + old_value = get_test_register_value(test_register); + expected_value = expect_success ? test_value : old_value; + + /* + * TODO: A successful write to the MSR_GS_BASE corrupts it, and that + * breaks the wrmsr_safe macro (it uses GS for per-CPU data). + */ + if ((test_register >> 32) == MSR_GS_BASE && expect_success) + test_mode = SET_REGISTER_MODE_UNSAFE; + + /* Write the test value*/ + success = set_test_register_value(test_register, test_mode, test_value); + report(success == expect_success, + "Write to %s with value %lx did %s%s as expected", + register_name, test_value, + success == expect_success ? "" : "NOT ", + (expect_success ? "succeed" : "fail")); + + /* + * Check that the value was really written. Don't test TR and LDTR, + * because it's not possible to read them directly. + */ + if (success == expect_success && + test_register != TEST_REGISTER_TR_BASE && + test_register != TEST_REGISTER_LDT_BASE) { + u64 new_value = get_test_register_value(test_register); + + report(new_value == expected_value, + "%s set to %lx as expected (actual value %lx)", + register_name, expected_value, new_value); + } + + + /* + * Restore the old value directly without safety wrapper, to avoid test + * crashes related to temporary clobbered GDT/IDT/etc bases. + */ + set_test_register_value(test_register, SET_REGISTER_MODE_UNSAFE, old_value); +} + +static void test_register(const char *register_name, u64 test_register, + bool force_emulation) +{ + /* Canonical 48 bit value should always succeed */ + test_register_write(register_name, test_register, force_emulation, + CANONICAL_48_VAL, true); + + /* 57-canonical value will work on CPUs that *support* LA57 */ + test_register_write(register_name, test_register, force_emulation, + CANONICAL_57_VAL, this_cpu_has(X86_FEATURE_LA57)); + + /* Non 57 canonical value should never work */ + test_register_write(register_name, test_register, force_emulation, + NONCANONICAL, false); +} + + +#define TEST_REGISTER(name, force_emulation) \ + test_register(#name, TEST_REGISTER_ ##name, force_emulation) + +#define __TEST_MSR(msr_name, address, force_emulation) \ + test_register(msr_name, ((u64)TEST_REGISTER_MSR | \ + ((u64)(address) << 32)), force_emulation) + +#define TEST_MSR(msr_name, force_emulation) \ + __TEST_MSR(#msr_name, msr_name, force_emulation) + +static void __test_invpcid(u64 test_value, bool expect_success) +{ + struct invpcid_desc desc; + + memset(&desc, 0, sizeof(desc)); + bool success; + + desc.addr = test_value; + desc.pcid = 10; /* Arbitrary number*/ + + success = invpcid_safe(0, &desc) == 0; + + report(success == expect_success, + "Tested invpcid type 0 with 0x%lx value - %s", + test_value, success ? "success" : "failure"); +} + +static void test_invpcid(void) +{ + /* + * Note that this test tests the kvm's behavior only when ept=0. + * Otherwise invpcid is not intercepted. + * + * Also KVM's x86 emulator doesn't support invpcid, thus testing invpcid + * with FEP is pointless. + */ + assert(write_cr4_safe(read_cr4() | X86_CR4_PCIDE) == 0); + + __test_invpcid(CANONICAL_48_VAL, true); + __test_invpcid(CANONICAL_57_VAL, this_cpu_has(X86_FEATURE_LA57)); + __test_invpcid(NONCANONICAL, false); +} + +static void __test_canonical_checks(bool force_emulation) +{ + printf("\nRunning canonical test %s forced emulation:\n", + force_emulation ? "with" : "without"); + + /* Direct DT addresses */ + TEST_REGISTER(GDTR_BASE, force_emulation); + TEST_REGISTER(IDTR_BASE, force_emulation); + + /* Indirect DT addresses */ + TEST_REGISTER(TR_BASE, force_emulation); + TEST_REGISTER(LDT_BASE, force_emulation); + + /* x86_64 extended segment bases */ + TEST_MSR(MSR_FS_BASE, force_emulation); + TEST_MSR(MSR_GS_BASE, force_emulation); + TEST_MSR(MSR_KERNEL_GS_BASE, force_emulation); + + /* + * SYSENTER ESP/EIP MSRs have canonical checks only on Intel, because + * only on Intel these instructions were extended to 64 bit. + * + * KVM emulation however ignores canonical checks for these MSRs, even + * on Intel, to support cross-vendor migration. This includes nested + * virtualization. + * + * Thus, the checks only work when run on bare metal, without forced + * emulation. Unfortunately, there is no foolproof way to detect bare + * metal from within this test. E.g. checking HYPERVISOR in CPUID is + * useless because that only detects if _this_ code is running in a VM, + * it doesn't detect if the "host" is itself a VM. + * + * TODO: Enable testing of SYSENTER MSRs on bare metal. + */ + if (false && is_intel() && !force_emulation) { + TEST_MSR(MSR_IA32_SYSENTER_ESP, force_emulation); + TEST_MSR(MSR_IA32_SYSENTER_EIP, force_emulation); + } else { + report_skip("skipping MSR_IA32_SYSENTER_ESP/MSR_IA32_SYSENTER_EIP %s", + (is_intel() ? "due to known errata in KVM" : "due to AMD host")); + } + + /* SYSCALL target MSRs */ + TEST_MSR(MSR_CSTAR, force_emulation); + TEST_MSR(MSR_LSTAR, force_emulation); + + /* PEBS DS area */ + if (this_cpu_has(X86_FEATURE_DS)) + TEST_MSR(MSR_IA32_DS_AREA, force_emulation); + else + report_skip("Skipping MSR_IA32_DS_AREA - PEBS not supported"); + + /* PT filter ranges */ + if (this_cpu_has(X86_FEATURE_INTEL_PT)) { + int n_ranges = cpuid_indexed(0x14, 0x1).a & 0x7; + int i; + + for (i = 0 ; i < n_ranges ; i++) { + wrmsr(MSR_IA32_RTIT_CTL, (1ull << (RTIT_CTL_ADDR0_OFFSET+i*4))); + __TEST_MSR("MSR_IA32_RTIT_ADDR_A", + MSR_IA32_RTIT_ADDR0_A + i*2, force_emulation); + __TEST_MSR("MSR_IA32_RTIT_ADDR_B", + MSR_IA32_RTIT_ADDR0_B + i*2, force_emulation); + } + } else { + report_skip("Skipping MSR_IA32_RTIT_ADDR* - Intel PT is not supported"); + } + + /* Test that INVPCID type 0 #GPs correctly */ + if (this_cpu_has(X86_FEATURE_INVPCID)) + test_invpcid(); + else + report_skip("Skipping INVPCID - not supported"); +} + +static void test_canonical_checks(void) +{ + __test_canonical_checks(false); + + if (is_fep_available()) + __test_canonical_checks(true); + else + report_skip("Force emulation prefix not enabled"); +} +#endif int main(int ac, char **av) { @@ -12,5 +330,18 @@ int main(int ac, char **av) expected ? "#GP" : "No fault", this_cpu_has(X86_FEATURE_LA57) ? "un" : "", is_64bit ? 64 : 32); +#ifdef __x86_64__ + /* set dummy LDTR pointer */ + set_gdt_entry(FIRST_SPARE_SEL, 0xffaabb, 0xffff, 0x82, 0); + lldt(FIRST_SPARE_SEL); + + test_canonical_checks(); + + if (is_64bit && this_cpu_has(X86_FEATURE_LA57)) { + printf("Switching to 5 level paging mode and rerunning canonical tests.\n"); + setup_5level_page_table(); + } +#endif + return report_summary(); } From patchwork Sat Feb 15 01:30:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 13975886 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 581F2151985 for ; Sat, 15 Feb 2025 01:30:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739583032; cv=none; b=ZcyznAtUid6NBn3LCN+ESHsbfsRMqNgJRGYHpywIuv8KHXkR+sNH2Vs7aPfqJ1EbwiygDrt3K/wsCu84zgMq4SO8HyyzaapjTaETy3rIW1IpTva2BPFfFa3o2UWl4DHLoUZRQpk0rHhvooS2Rs71V2XlZY1cUEEcCBBflwtFMKw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739583032; c=relaxed/simple; bh=tuhGABPm7VtLbrad1GqHFCF4cq/RQ1jRy8bcAfPZkS8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Lhweej7gLJQlJtc7Ibk2u74qDGxpljklfeyEN3nn3XRdRsFED5BEnsuZ9gamExRAu79+LCMoW8pF87pbBvqNvOn97vkHe9K1H6O1D1DJhFQXOVFmgtzWWdYqlFtgZPHNpOD5wLINB8sDBjJRl+Sd7L+Gw2mps38RViveAonC0OU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=3GPe21Il; arc=none smtp.client-ip=209.85.216.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="3GPe21Il" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-2fc1a4c150bso5372764a91.2 for ; Fri, 14 Feb 2025 17:30:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1739583030; x=1740187830; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=WYeAkqtk80nvZ8OWOyCMTgMj5r0POJdH1xD2gcl0+QU=; b=3GPe21IlMnV8q7grNhg03uSnm99Jc8npI58a9GmdTrYMmygmRnppyC4qsiHpzEroBQ HCaXw6sjy1jxMw0KHxvQ09M3g60/xfJ5ETl93bjK1U3mOAZq0Y29c4o4VTh19rSuwosr kkmSs3onnqANxlhd65aLqg5z0MbPLPqFOMns0nuNh+oAQGT86tD+sx1/+BUGUcGVfyIx jv30j07svg5qr1faFnhKIVYoUgGLXCwsTjDgWwRbbR1gcfc3yzbyGl/BbLOiWmYQBH3l ESCOzr0gTzsyEAxGKNVvXniX1EMue33bjMCGiqkEUZ4YAl/LmfwEQKvPYfHKGA07LQ3a pUAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739583030; x=1740187830; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=WYeAkqtk80nvZ8OWOyCMTgMj5r0POJdH1xD2gcl0+QU=; b=Cz3DBegXGje6StaYHWOzVval1Eb9rVnt1HTDdGZXMO7C3uj1/soJj8NtWMG5oSyXV/ tW/KAGaaMugcinp01uhD0MR6Y975i7wm+k1JUB0PKt/92syy4F1lFmlfKmhgzDNQGQsR cqT+nxk8egUs8Ps62oBCMDLo98Go1G07ftk5UOtBznywEkxvuIFnnuq3EgUebxC4m93L 3aVN/CCGItU3z1jjp6m51ueUwrcSCs3xFASxQpsM4ly9q4tnXfrZDAwmVrkvrBUAOndv SwSa4YJBWqDAST/ae3gORHr55XYmdF7qjhJLnS7m1OCFX9j0II5O8AGd7pTK1PgCBA2H Rxdw== X-Gm-Message-State: AOJu0YwmwyFUi3iZPRIuKki+fOws8k7xYXpKcOuuLPJExw1jcJfxcAGK RMzjjp7W83pCYSme1hLKSO3DuDpFTtWrUvMtBxWCAIGHIlQnAwBKMsFVFY3MGnRiSAM119WJLJW qpw== X-Google-Smtp-Source: AGHT+IEIu2e5eN41nnBgprJR6+VxA5+J0XkX2HhVT/apooQ+SWt4g2IXBOjDQ3ARnQmBgSH4qdQsEKjZ16Y= X-Received: from pjh12.prod.google.com ([2002:a17:90b:3f8c:b0:2ea:aa56:49c]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2248:b0:2f7:7680:51a6 with SMTP id 98e67ed59e1d1-2fc40d12e63mr1846074a91.6.1739583030563; Fri, 14 Feb 2025 17:30:30 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 14 Feb 2025 17:30:18 -0800 In-Reply-To: <20250215013018.1210432-1-seanjc@google.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250215013018.1210432-1-seanjc@google.com> X-Mailer: git-send-email 2.48.1.601.g30ceb7b040-goog Message-ID: <20250215013018.1210432-7-seanjc@google.com> Subject: [kvm-unit-tests PATCH v2 6/6] nVMX: add a test for canonical checks of various host state vmcs12 fields. From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Maxim Levitsky , Sean Christopherson From: Maxim Levitsky This test tests canonical VM entry checks of various host state fields (mostly segment bases) in vmcs12. Signed-off-by: Maxim Levitsky Link: https://lore.kernel.org/r/20240907005440.500075-6-mlevitsk@redhat.com [sean: print expected vs. actual in reports, use descriptive value names] Signed-off-by: Sean Christopherson --- x86/vmx_tests.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index ffe7064c..d9058b8c 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -10754,6 +10754,172 @@ static void vmx_exception_test(void) test_set_guest_finished(); } +/* + * Arbitrary canonical values for validating direct writes in the host, e.g. to + * an MSR, and for indirect writes via loads from VMCS fields on VM-Exit. + */ +#define TEST_DIRECT_VALUE 0xff45454545000000 +#define TEST_VMCS_VALUE 0xff55555555000000 + +static void vmx_canonical_test_guest(void) +{ + while (true) + vmcall(); +} + +static int get_host_value(u64 vmcs_field, u64 *value) +{ + struct descriptor_table_ptr dt_ptr; + + switch (vmcs_field) { + case HOST_SYSENTER_ESP: + *value = rdmsr(MSR_IA32_SYSENTER_ESP); + break; + case HOST_SYSENTER_EIP: + *value = rdmsr(MSR_IA32_SYSENTER_EIP); + break; + case HOST_BASE_FS: + *value = rdmsr(MSR_FS_BASE); + break; + case HOST_BASE_GS: + *value = rdmsr(MSR_GS_BASE); + break; + case HOST_BASE_GDTR: + sgdt(&dt_ptr); + *value = dt_ptr.base; + break; + case HOST_BASE_IDTR: + sidt(&dt_ptr); + *value = dt_ptr.base; + break; + case HOST_BASE_TR: + *value = get_gdt_entry_base(get_tss_descr()); + /* value might not reflect the actual base if changed by VMX */ + return 1; + default: + assert(0); + return 1; + } + return 0; +} + +static int set_host_value(u64 vmcs_field, u64 value) +{ + struct descriptor_table_ptr dt_ptr; + + switch (vmcs_field) { + case HOST_SYSENTER_ESP: + return wrmsr_safe(MSR_IA32_SYSENTER_ESP, value); + case HOST_SYSENTER_EIP: + return wrmsr_safe(MSR_IA32_SYSENTER_EIP, value); + case HOST_BASE_FS: + return wrmsr_safe(MSR_FS_BASE, value); + case HOST_BASE_GS: + /* TODO: _safe variants assume per-cpu gs base*/ + wrmsr(MSR_GS_BASE, value); + return 0; + case HOST_BASE_GDTR: + sgdt(&dt_ptr); + dt_ptr.base = value; + lgdt(&dt_ptr); + return lgdt_fep_safe(&dt_ptr); + case HOST_BASE_IDTR: + sidt(&dt_ptr); + dt_ptr.base = value; + return lidt_fep_safe(&dt_ptr); + case HOST_BASE_TR: + /* Set the base and clear the busy bit */ + set_gdt_entry(FIRST_SPARE_SEL, value, 0x200, 0x89, 0); + return ltr_safe(FIRST_SPARE_SEL); + default: + assert(0); + } +} + +static void test_host_value_direct(const char *field_name, u64 vmcs_field) +{ + u64 value = 0; + int vector; + + /* + * Set the directly register via host ISA (e.g lgdt) and check that we + * got no exception. + */ + vector = set_host_value(vmcs_field, TEST_DIRECT_VALUE); + if (vector) { + report_fail("Exception %d when setting %s to 0x%lx via direct write", + vector, field_name, TEST_DIRECT_VALUE); + return; + } + + /* + * Now check that the host value matches what we expect for fields + * that can be read back (these that we can't we assume that are correct) + */ + report(get_host_value(vmcs_field, &value) || value == TEST_DIRECT_VALUE, + "%s: HOST value set to 0x%lx (wanted 0x%lx) via direct write", + field_name, value, TEST_DIRECT_VALUE); +} + +static void test_host_value_vmcs(const char *field_name, u64 vmcs_field) +{ + u64 value = 0; + + /* Set host state field in the vmcs and do the VM entry + * Success of VM entry already shows that L0 accepted the value + */ + vmcs_write(vmcs_field, TEST_VMCS_VALUE); + enter_guest(); + skip_exit_vmcall(); + + /* + * Now check that the host value matches what we expect for fields + * that can be read back (these that we can't we assume that are correct) + */ + report(get_host_value(vmcs_field, &value) || value == TEST_VMCS_VALUE, + "%s: HOST value set to 0x%lx (wanted 0x%lx) via VMLAUNCH/VMRESUME", + field_name, value, TEST_VMCS_VALUE); +} + +static void do_vmx_canonical_test_one_field(const char *field_name, u64 field) +{ + u64 host_org_value, field_org_value; + + /* Backup the current host value and vmcs field value values */ + get_host_value(field, &host_org_value); + field_org_value = vmcs_read(field); + + test_host_value_direct(field_name, field); + test_host_value_vmcs(field_name, field); + + /* Restore original values */ + vmcs_write(field, field_org_value); + set_host_value(field, host_org_value); +} + +#define vmx_canonical_test_one_field(field) \ + do_vmx_canonical_test_one_field(#field, field) + +static void vmx_canonical_test(void) +{ + report(!(read_cr4() & X86_CR4_LA57), "4 level paging"); + + if (!this_cpu_has(X86_FEATURE_LA57)) + test_skip("5 level paging not supported"); + + test_set_guest(vmx_canonical_test_guest); + + vmx_canonical_test_one_field(HOST_SYSENTER_ESP); + vmx_canonical_test_one_field(HOST_SYSENTER_EIP); + vmx_canonical_test_one_field(HOST_BASE_FS); + vmx_canonical_test_one_field(HOST_BASE_GS); + vmx_canonical_test_one_field(HOST_BASE_GDTR); + vmx_canonical_test_one_field(HOST_BASE_IDTR); + vmx_canonical_test_one_field(HOST_BASE_TR); + + test_set_guest_finished(); +} + enum Vid_op { VID_OP_SET_ISR, VID_OP_NOP, @@ -11262,5 +11428,6 @@ struct vmx_test vmx_tests[] = { TEST(vmx_pf_invvpid_test), TEST(vmx_pf_vpid_test), TEST(vmx_exception_test), + TEST(vmx_canonical_test), { NULL, NULL, NULL, NULL, NULL, {0} }, };