Commit 3c5d19a3 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-x86-guest-6.18' of https://github.com/kvm-x86/linux into HEAD

x86/kvm guest side changes for 6.18

 - For the legacy PCI hole (memory between TOLUD and 4GiB) to UC when
   overriding guest MTRR for TDX/SNP to fix an issue where ACPI auto-mapping
   could map devices as WB and prevent the device drivers from mapping their
   devices with UC/UC-.

 - Make kvm_async_pf_task_wake() a local static helper and remove its
   export.

 - Use native qspinlocks when running in a VM with dedicated vCPU=>pCPU
   bindings even when PV_UNHALT is unsupported.
parents 473badf5 96055050
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -124,7 +124,6 @@ bool kvm_para_available(void);
unsigned int kvm_arch_para_features(void);
unsigned int kvm_arch_para_hints(void);
void kvm_async_pf_task_wait_schedule(u32 token);
void kvm_async_pf_task_wake(u32 token);
u32 kvm_read_and_reset_apf_flags(void);
bool __kvm_handle_async_pf(struct pt_regs *regs, u32 token);

@@ -148,7 +147,6 @@ static inline void kvm_spinlock_init(void)

#else /* CONFIG_KVM_GUEST */
#define kvm_async_pf_task_wait_schedule(T) do {} while(0)
#define kvm_async_pf_task_wake(T) do {} while(0)

static inline bool kvm_para_available(void)
{
+30 −14
Original line number Diff line number Diff line
@@ -190,7 +190,7 @@ static void apf_task_wake_all(void)
	}
}

void kvm_async_pf_task_wake(u32 token)
static void kvm_async_pf_task_wake(u32 token)
{
	u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS);
	struct kvm_task_sleep_head *b = &async_pf_sleepers[key];
@@ -241,7 +241,6 @@ void kvm_async_pf_task_wake(u32 token)
	/* A dummy token might be allocated and ultimately not used.  */
	kfree(dummy);
}
EXPORT_SYMBOL_GPL(kvm_async_pf_task_wake);

noinstr u32 kvm_read_and_reset_apf_flags(void)
{
@@ -933,6 +932,19 @@ static void kvm_sev_hc_page_enc_status(unsigned long pfn, int npages, bool enc)

static void __init kvm_init_platform(void)
{
	u64 tolud = PFN_PHYS(e820__end_of_low_ram_pfn());
	/*
	 * Note, hardware requires variable MTRR ranges to be power-of-2 sized
	 * and naturally aligned.  But when forcing guest MTRR state, Linux
	 * doesn't program the forced ranges into hardware.  Don't bother doing
	 * the math to generate a technically-legal range.
	 */
	struct mtrr_var_range pci_hole = {
		.base_lo = tolud | X86_MEMTYPE_UC,
		.mask_lo = (u32)(~(SZ_4G - tolud - 1)) | MTRR_PHYSMASK_V,
		.mask_hi = (BIT_ULL(boot_cpu_data.x86_phys_bits) - 1) >> 32,
	};

	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT) &&
	    kvm_para_has_feature(KVM_FEATURE_MIGRATION_CONTROL)) {
		unsigned long nr_pages;
@@ -982,8 +994,12 @@ static void __init kvm_init_platform(void)
	kvmclock_init();
	x86_platform.apic_post_init = kvm_apic_init;

	/* Set WB as the default cache mode for SEV-SNP and TDX */
	guest_force_mtrr_state(NULL, 0, MTRR_TYPE_WRBACK);
	/*
	 * Set WB as the default cache mode for SEV-SNP and TDX, with a single
	 * UC range for the legacy PCI hole, e.g. so that devices that expect
	 * to get UC/WC mappings don't get surprised with WB.
	 */
	guest_force_mtrr_state(&pci_hole, 1, MTRR_TYPE_WRBACK);
}

#if defined(CONFIG_AMD_MEM_ENCRYPT)
@@ -1072,16 +1088,6 @@ static void kvm_wait(u8 *ptr, u8 val)
 */
void __init kvm_spinlock_init(void)
{
	/*
	 * In case host doesn't support KVM_FEATURE_PV_UNHALT there is still an
	 * advantage of keeping virt_spin_lock_key enabled: virt_spin_lock() is
	 * preferred over native qspinlock when vCPU is preempted.
	 */
	if (!kvm_para_has_feature(KVM_FEATURE_PV_UNHALT)) {
		pr_info("PV spinlocks disabled, no host support\n");
		return;
	}

	/*
	 * Disable PV spinlocks and use native qspinlock when dedicated pCPUs
	 * are available.
@@ -1101,6 +1107,16 @@ void __init kvm_spinlock_init(void)
		goto out;
	}

	/*
	 * In case host doesn't support KVM_FEATURE_PV_UNHALT there is still an
	 * advantage of keeping virt_spin_lock_key enabled: virt_spin_lock() is
	 * preferred over native qspinlock when vCPU is preempted.
	 */
	if (!kvm_para_has_feature(KVM_FEATURE_PV_UNHALT)) {
		pr_info("PV spinlocks disabled, no host support\n");
		return;
	}

	pr_info("PV spinlocks enabled\n");

	__pv_init_lock_hash();