Received: by 2002:ab2:6309:0:b0:1fb:d597:ff75 with SMTP id s9csp545583lqt; Thu, 6 Jun 2024 10:44:02 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWdCHHIyapnVHxU47s5gAaCkUZhxFLfSoHeRioBmuqcjA+mz+B92f9LNQ49YPWyOftzJQLCTGhQJQiFn8kSAa28s9hQeBc2/NHzA3bqhg== X-Google-Smtp-Source: AGHT+IEVVkvmFq4U/Nvvgf7zkTdzBg91GGYcYz93TENdYTNLFkWcTTPuF2+wESP40pKIvS39+mmf X-Received: by 2002:a2e:bc1f:0:b0:2e9:865e:4ab1 with SMTP id 38308e7fff4ca-2eadce1bb5dmr3398601fa.6.1717695842671; Thu, 06 Jun 2024 10:44:02 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1717695842; cv=pass; d=google.com; s=arc-20160816; b=SgGBvbSTh2WUqPPpxl+g0UYGz46gtMECn4kHAbTANP0qUzjl6PLBC7thQlB7ucUOrl dIDvMfP9EWhEHII+VTDveA5mNgykIzJ9n1rPxo9+LlZ8uxsEvA/Hzu431FWoba0jWDhJ q755r7graUsyOq10WeV/DWgQH2q0dDwuDLpvAabOK4Y4tUpFeumjxWwcNJFJ+Mb9NjIK wS0Zc7Dhy6iQOwUKGgXeJnoaOkJeSZcFBsgYEJ4UjxMi/7pdq5DEzLCQltB/+8XqtDSA Mc3E3FOOrhCdX/tTp3G4KlwnTJOs+rsH9Iuk/I0OhOvD9dNERZkb3qHlGb7hUuXTXj7w q5jg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:date:subject:cc:to :from:dkim-signature; bh=5fRUtst5aU8PDBveCDZ3lovPVAnecE53aQR2fQ2p3h8=; fh=39c7xHRXKGHRweehzLnY8wn6iHFCUfmQLOpmt3ijdwY=; b=Dytywv7JAAZ+EGKBrPb1r/kuDwar4+hGf9NfMEbTWs5o1WFrIcx2iw025p+K9RjNTD Gtwn3jidbAhLmco5MN/u1l7J6YAta7zKv0GusTbugP92KIcr0dk5oaelyjhJzfFuchmH mak1T50jDVB+XyNAndpEJkbmCbtbEAMnEVXw8V2jaDLZKCnUgzrcSHY2wdessX+rTDqz uUmEIGJPEWCjsCo6U4lsJLpOkakR6KY59agkfkqBK0o6xirK1LMTRpMmACseLSM+5+3A 7frmnM+lf/XvGLC2RllXw0bLVXwfwOudb1+1RjugLdtZR/+Twy+Dz1YoaGh5ea5ff/yr 9zvA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=cuJVpVUJ; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-204829-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-204829-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id 4fb4d7f45d1cf-57aae0c66e6si946515a12.114.2024.06.06.10.44.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Jun 2024 10:44:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-204829-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=cuJVpVUJ; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-204829-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-204829-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 29E391F247DC for ; Thu, 6 Jun 2024 17:42:55 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B7AE4199238; Thu, 6 Jun 2024 17:42:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="cuJVpVUJ" Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CC42E198A24; Thu, 6 Jun 2024 17:42:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.12 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717695755; cv=none; b=IZRP24UFuuv+D0eTtluaT4SOKUfCwb9Y4A2HEcGdKOWdicZnm/QG5HFvOIXiBH20Jv+HOXKakn20sCUCkNn8O3DMCSy5vVPGhcR14i6WGsS/zEDlVIqI0dedQYZi611E6SQktj3CF82VvVnFICYzSyVCaZYkDza7PdwkcJNwg1I= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717695755; c=relaxed/simple; bh=6l56j3Dvt1N8dQXMYBUEdlF6rPZWJsLotwy+UDT+myA=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version:Content-Type; b=CwzNHW9bU7iszVAA1yydpxCIsW6VN0Ay/dRtfC6UVLJo23V0oLV1MHg0aFyY8FhpZWFhBoqi/lZN2WsRwI776Zfnc+LQXIhu/FfdMKJ4ylyQu+nGLYSr+6H8eCw6g0vTt+hm8zqbYIJXfBYYAiLyUeV4Cii/DQyytRFMTX4I5lI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=cuJVpVUJ; arc=none smtp.client-ip=198.175.65.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1717695753; x=1749231753; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=6l56j3Dvt1N8dQXMYBUEdlF6rPZWJsLotwy+UDT+myA=; b=cuJVpVUJ3RO/fgM5J2Kcz1UDJDCoUvw3bwDofBMKliMyzvIovthX2TVj 30y6BeacsQP05oobPCSH+jBKqZCUxot09gp+TIn+qio3EN5cDmbXEb7OH Y4zbDJ1QZYi7626zFme0INcvst+qYOAFz29Z5iLafh/DE16mR5FTao1zD 9twXjyBxrJXFY5tMBHDZKCq4jAFCo3y1fiBOpSxbdb3fKWaQMikrt86HC XPTRInLcBJtQbxhin7vMU7qw0fWm/mxD1DDnNWT2MsrN/ifEfnyx0Ag64 6JM2XyOkOOYWKu+4kBCj2YByoM9CIbtceVtNr2QHyuAw7lVWbGl7fyHev A==; X-CSE-ConnectionGUID: CrJ9ssdMQ+qs7BxHFv/ztQ== X-CSE-MsgGUID: p+dV7ocZQi6gvSXOy51Bmg== X-IronPort-AV: E=McAfee;i="6600,9927,11095"; a="25792264" X-IronPort-AV: E=Sophos;i="6.08,219,1712646000"; d="scan'208";a="25792264" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Jun 2024 10:42:32 -0700 X-CSE-ConnectionGUID: T2a3NxmfQVuAOFK9caKDUw== X-CSE-MsgGUID: YlBPw27TR8G/oZ6sta1rDQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,219,1712646000"; d="scan'208";a="61254856" Received: from rchatre-ws.ostc.intel.com ([10.54.69.144]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Jun 2024 10:42:31 -0700 From: Reinette Chatre To: isaku.yamahata@intel.com, pbonzini@redhat.com, erdemaktas@google.com, vkuznets@redhat.com, seanjc@google.com, vannapurve@google.com, jmattson@google.com, mlevitsk@redhat.com, xiaoyao.li@intel.com, chao.gao@intel.com, rick.p.edgecombe@intel.com, yuan.yao@intel.com Cc: reinette.chatre@intel.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH V7 0/2] KVM: x86: Make bus clock frequency for vAPIC timer configurable Date: Thu, 6 Jun 2024 10:41:59 -0700 Message-Id: X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes from v6: - V6: https://lore.kernel.org/lkml/cover.1715017765.git.reinette.chatre@intel.com/ - KVM changes were merged into kvm-x86 misc and subsequently dropped from this submission. This submission only contains the selftest changes. https://lore.kernel.org/lkml/ZmBw9R_jkNLYXkJh@google.com/ - New patch to add udelay() utility to x86_64 KVM selftests. (Sean) - Many changes to APIC bus frequency selftest. Please refer to the patch for detailed changes. - Series applies cleanly to next branch of kvm-x86 with HEAD af0903ab52ee6d6f0f63af67fa73d5eb00f79b9a. Changes from v5: - v5: https://lore.kernel.org/lkml/cover.1714081725.git.reinette.chatre@intel.com/ - Rebased on latest of "next" branch of https://github.com/kvm-x86/linux.git - Added Xiaoyao Li and Yuan Yao's Reviewed-by tags. - Use the KVM selftest vm_create() wrapper instead of open coding it. (Zide) - Improve grammar of selftest description. (Zide) Changes from v4: - v4: https://lore.kernel.org/lkml/cover.1711035400.git.reinette.chatre@intel.com/ - Rename capability from KVM_CAP_X86_APIC_BUS_FREQUENCY to KVM_CAP_X86_APIC_BUS_CYCLES_NS. (Xiaoyao Li). - Include "Testing" section in cover letter. - Add Rick's Reviewed-by tags. - Rebased on latest of "next" branch of https://github.com/kvm-x86/linux.git Changes from v3: - v3: https://lore.kernel.org/all/cover.1702974319.git.isaku.yamahata@intel.com/ - Reworked all changelogs. - Regarding code changes: patches #1 and #2 are unchanged, patch #3 was reworked according to Sean's guidance, and patch #4 (the test) needed changes after rebase to kvm-x86/next and the implementation (patch #3) changes. - Added Reviewed-by tags to patches #1, #2, and #4, but removed Maxim's Reviewed-by tag from patch #3 because it changed so much. - Added a "Suggested-by" to patch #4 to reflect that it represents Sean's guidance. - Reworked cover to match customs (in subject line) and reflect feedback to patches: capability renamed to KVM_CAP_X86_APIC_BUS_FREQUENCY, clarify distinction between "core crystal clock" and "bus clock", and update pro/con list. - Please refer to individual patches for detailed changes. Changes from v2: - v2: https://lore.kernel.org/lkml/cover.1699936040.git.isaku.yamahata@intel.com/ - Removed APIC_BUS_FREQUENCY and apic_bus_frequency of struct kvm-arch. - Update the commit messages. - Added reviewed-by (Maxim Levitsky) - Use 1.5GHz instead of 1GHz as frequency for the test case. Changes from v1: - v1: https://lore.kernel.org/all/cover.1699383993.git.isaku.yamahata@intel.com/ - Added a test case - Fix a build error for i386 platform - Add check if vcpu isn't created. - Add check if lapic chip is in-kernel emulation. - Updated api.rst Summary ------- Add KVM_CAP_X86_APIC_BUS_CYCLES_NS capability to configure the APIC bus clock frequency for APIC timer emulation. Allow KVM_ENABLE_CAPABILITY(KVM_CAP_X86_APIC_BUS_CYCLES_NS) to set the frequency in nanoseconds. When using this capability, the user space VMM should configure CPUID leaf 0x15 to advertise the frequency. Description ----------- Vishal reported [1] that the TDX guest kernel expects a 25MHz APIC bus frequency but ends up getting interrupts at a significantly higher rate. The TDX architecture hard-codes the core crystal clock frequency to 25MHz and mandates exposing it via CPUID leaf 0x15. The TDX architecture does not allow the VMM to override the value. In addition, per Intel SDM: "The APIC timer frequency will be the processor’s bus clock or core crystal clock frequency (when TSC/core crystal clock ratio is enumerated in CPUID leaf 0x15) divided by the value specified in the divide configuration register." The resulting 25MHz APIC bus frequency conflicts with the KVM hardcoded APIC bus frequency of 1GHz. The KVM doesn't enumerate CPUID leaf 0x15 to the guest unless the user space VMM sets it using KVM_SET_CPUID. If the CPUID leaf 0x15 is enumerated, the guest kernel uses it as the APIC bus frequency. If not, the guest kernel measures the frequency based on other known timers like the ACPI timer or the legacy PIT. As reported in [1] the TDX guest kernel expects a 25MHz timer frequency but gets timer interrupt more frequently due to the 1GHz frequency used by KVM. To ensure that the guest doesn't have a conflicting view of the APIC bus frequency, allow the userspace to tell KVM to use the same frequency that TDX mandates instead of the default 1Ghz. There are several options to address this: 1. Make the KVM able to configure APIC bus frequency (this series). Pro: It resembles the existing hardware. The recent Intel CPUs adopts 25MHz. Con: Require the VMM to emulate the APIC timer at 25MHz. 2. Make the TDX architecture enumerate CPUID leaf 0x15 to configurable frequency or not enumerate it. Pro: Any APIC bus frequency is allowed. Con: Deviates from TDX architecture. 3. Make the TDX guest kernel use 1GHz when it's running on KVM. Con: The kernel ignores CPUID leaf 0x15. 4. Change CPUID leaf 0x15 under TDX to report the crystal clock frequency as 1 GHz. Pro: This has been the virtual APIC frequency for KVM guests for 13 years. Pro: This requires changing only one hard-coded constant in TDX. Con: It doesn't work with other VMMs as TDX isn't specific to KVM. Con: Core crystal clock frequency is also used to calculate TSC frequency. Con: If it is configured to value different from hardware, it will break the correctness of INTEL-PT Mini Time Count (MTC) packets in TDs. Testing ------- Tested on non-TDX host using included kselftest. Host running kernel with this series applied to "next" branch of https://github.com/kvm-x86/linux.git Tested on TDX host and TD using a modified version of x86/apic.c:test_apic_timer_one_shot() available from https://github.com/intel/kvm-unit-tests-tdx/blob/tdx/x86/apic.c. Host running TDX KVM development patches and QEMU with corresponding TDX changes. The test needed to be modified to (a) stop any lingering timers before the test starts, and (b) use CPUID 0x15 in TDX to accurately determine the TSC and APIC frequencies instead of making 1GHz assumption and use similar check as the kselftest test introduced in this series (while increasing the amount with which the frequency is allowed to deviate by 1%). The core changes made to x86/apic.c:test_apic_timer_one_shot() for this testing are shown below for reference. Work is in progress to upstream these modifications. @@ -477,11 +478,29 @@ static void lvtt_handler(isr_regs_t *regs) static void test_apic_timer_one_shot(void) { - uint64_t tsc1, tsc2; static const uint32_t interval = 0x10000; + uint64_t measured_apic_freq, tsc2, tsc1; + uint32_t tsc_freq = 0, apic_freq = 0; + struct cpuid cpuid_tsc = {}; #define APIC_LVT_TIMER_VECTOR (0xee) + /* + * CPUID 0x15 is not available in VMX, can use it to obtain + * TSC and APIC frequency for accurate testing + */ + if (is_tdx_guest()) { + cpuid_tsc = raw_cpuid(0x15, 0); + tsc_freq = cpuid_tsc.c * cpuid_tsc.b / cpuid_tsc.a; + apic_freq = cpuid_tsc.c; + } + /* + stop already fired local timer + the test case can be negative failure if the timer fired + after installed lvtt_handler but *before* + write to TIMICT again. + */ + apic_write(APIC_TMICT, 0); handle_irq(APIC_LVT_TIMER_VECTOR, lvtt_handler); /* One shot mode */ @@ -503,8 +522,16 @@ static void test_apic_timer_one_shot(void) * cases, the following should satisfy on all modern * processors. */ - report((lvtt_counter == 1) && (tsc2 - tsc1 >= interval), - "APIC LVT timer one shot"); + if (is_tdx_guest()) { + measured_apic_freq = interval * (tsc_freq / (tsc2 - tsc1)); + report((lvtt_counter == 1) && + (measured_apic_freq < apic_freq * 102 / 100) && + (measured_apic_freq > apic_freq * 98 / 100), + "APIC LVT timer one shot"); + } else { + report((lvtt_counter == 1) && (tsc2 - tsc1 >= interval), + "APIC LVT timer one shot"); + } } [1] https://lore.kernel.org/lkml/20231006011255.4163884-1-vannapurve@google.com/ Isaku Yamahata (1): KVM: selftests: Add test for configure of x86 APIC bus frequency Reinette Chatre (1): KVM: selftests: Add x86_64 guest udelay() utility tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/include/x86_64/apic.h | 8 + .../selftests/kvm/include/x86_64/processor.h | 15 ++ .../selftests/kvm/lib/x86_64/processor.c | 8 + .../kvm/x86_64/apic_bus_clock_test.c | 218 ++++++++++++++++++ 5 files changed, 250 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86_64/apic_bus_clock_test.c -- 2.34.1