Unverified Commit 771dc636 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!13372 [OLK-6.6] Support Intel Sierra Forest CPU MAXPHYSADDR and fix KVM_STATS_TYPE_MAX

Merge Pull Request from: @x56Jason 
 
# Description
This PR contains 2 parts:
- Intel Sierra Forest doesn't support 5-level EPT but has 52-bit physical address (MAXPHYADDR), this can cause KVM infinite loop when guest BIOS puts RAM memory or 64-bit PCI BAR in high physical address.
- Commit 06f89a27 ("kvm: debugfs: Export vcpu stat via debugfs") forgot to update KVM_STATS_TYPE_MAX in include/uapi/linux/kvm.h, and forgot to update header file in tools/ folder. This causes kernel KVM selftests failure.

# Issue
[#IB5K00: \[OLK-6.6\] Support Sierra Forrest MAXPHYADDR](https://gitee.com/openeuler/intel-kernel/issues/IB5K00)
#IB5TKJ

# Test
- Kernel KVM selftest KVM all PASS.
- On SRF platform launch VM by passing-through NIC with 64-bit bar successfully.
- On EMR platform launch VM successfully.
 
 
Link:https://gitee.com/openeuler/kernel/pulls/13372

 

Reviewed-by: default avatarAichun Shi <aichun.shi@intel.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents 2b05c5bb 797abd4e
Loading
Loading
Loading
Loading
+25 −3
Original line number Diff line number Diff line
@@ -1212,8 +1212,22 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
		entry->eax = entry->ebx = entry->ecx = 0;
		break;
	case 0x80000008: {
		/*
		 * GuestPhysAddrSize (EAX[23:16]) is intended for software
		 * use.
		 *
		 * KVM's ABI is to report the effective MAXPHYADDR for the
		 * guest in PhysAddrSize (phys_as), and the maximum
		 * *addressable* GPA in GuestPhysAddrSize (g_phys_as).
		 *
		 * GuestPhysAddrSize is valid if and only if TDP is enabled,
		 * in which case the max GPA that can be addressed by KVM may
		 * be less than the max GPA that can be legally generated by
		 * the guest, e.g. if MAXPHYADDR>48 but the CPU doesn't
		 * support 5-level TDP.
		 */
		unsigned int virt_as = max((entry->eax >> 8) & 0xff, 48U);
		unsigned int phys_as;
		unsigned int phys_as, g_phys_as;

		/*
		 * If TDP (NPT) is disabled use the adjusted host MAXPHYADDR as
@@ -1222,15 +1236,23 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
		 * paging, too.
		 *
		 * If TDP is enabled, use the raw bare metal MAXPHYADDR as
		 * reductions to the HPAs do not affect GPAs.
		 * reductions to the HPAs do not affect GPAs.  The max
		 * addressable GPA is the same as the max effective GPA, except
		 * that it's capped at 48 bits if 5-level TDP isn't supported
		 * (hardware processes bits 51:48 only when walking the fifth
		 * level page table).
		 */
		if (!tdp_enabled) {
			phys_as = boot_cpu_data.x86_phys_bits;
			g_phys_as = 0;
		} else {
			phys_as = entry->eax & 0xff;
			g_phys_as = phys_as;
			if (kvm_mmu_get_max_tdp_level() < 5)
				g_phys_as = min(g_phys_as, 48);
		}

		entry->eax = phys_as | (virt_as << 8);
		entry->eax = phys_as | (virt_as << 8) | (g_phys_as << 16);
		entry->ecx &= ~(GENMASK(31, 16) | GENMASK(11, 8));
		entry->edx = 0;
		cpuid_entry_override(entry, CPUID_8000_0008_EBX);
+2 −0
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ static inline u8 kvm_get_shadow_phys_bits(void)
	return boot_cpu_data.x86_phys_bits;
}

u8 kvm_mmu_get_max_tdp_level(void);

void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 mmio_mask, u64 access_mask);
void kvm_mmu_set_me_spte_mask(u64 me_value, u64 me_mask);
void kvm_mmu_set_ept_masks(bool has_ad_bits, bool has_exec_only);
+5 −0
Original line number Diff line number Diff line
@@ -5175,6 +5175,11 @@ static inline int kvm_mmu_get_tdp_level(struct kvm_vcpu *vcpu)
	return max_tdp_level;
}

u8 kvm_mmu_get_max_tdp_level(void)
{
	return tdp_root_level ? tdp_root_level : max_tdp_level;
}

static union kvm_mmu_page_role
kvm_calc_tdp_mmu_root_page_role(struct kvm_vcpu *vcpu,
				union kvm_cpu_role cpu_role)
+1 −1
Original line number Diff line number Diff line
@@ -2232,7 +2232,7 @@ struct kvm_stats_header {
#define KVM_STATS_TYPE_LINEAR_HIST	(0x3 << KVM_STATS_TYPE_SHIFT)
#define KVM_STATS_TYPE_LOG_HIST		(0x4 << KVM_STATS_TYPE_SHIFT)
#define KVM_STATS_TYPE_DFX		(0x5 << KVM_STATS_TYPE_SHIFT)
#define KVM_STATS_TYPE_MAX		KVM_STATS_TYPE_LOG_HIST
#define KVM_STATS_TYPE_MAX		KVM_STATS_TYPE_DFX

#define KVM_STATS_UNIT_SHIFT		4
#define KVM_STATS_UNIT_MASK		(0xF << KVM_STATS_UNIT_SHIFT)
+2 −1
Original line number Diff line number Diff line
@@ -2168,7 +2168,8 @@ struct kvm_stats_header {
#define KVM_STATS_TYPE_PEAK		(0x2 << KVM_STATS_TYPE_SHIFT)
#define KVM_STATS_TYPE_LINEAR_HIST	(0x3 << KVM_STATS_TYPE_SHIFT)
#define KVM_STATS_TYPE_LOG_HIST		(0x4 << KVM_STATS_TYPE_SHIFT)
#define KVM_STATS_TYPE_MAX		KVM_STATS_TYPE_LOG_HIST
#define KVM_STATS_TYPE_DFX		(0x5 << KVM_STATS_TYPE_SHIFT)
#define KVM_STATS_TYPE_MAX		KVM_STATS_TYPE_DFX

#define KVM_STATS_UNIT_SHIFT		4
#define KVM_STATS_UNIT_MASK		(0xF << KVM_STATS_UNIT_SHIFT)
Loading