Unverified Commit 9cb12b91 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!166 SPR: KVM: Add new instructions, Bus Lock Debug Exception, Bus Lock VM...

!166 SPR: KVM: Add new instructions, Bus Lock Debug Exception, Bus Lock VM exit and Notify VM exit support

Merge Pull Request from: @allen-shi 
 
This PR is to add new instructions(AVX_VNNI and AVX512_FP16), Bus Lock Debug Exception, Bus Lock VM exit and Notify VM exit support, and kabi is not changed based on OpenEuler-22.03-LTS kabi whitelist.

 **Intel-Kernel Issue** 
[#I5O6WB](https://gitee.com/openeuler/intel-kernel/issues/I5O6WB)
[#I5RJCB](https://gitee.com/openeuler/intel-kernel/issues/I5RJCB)
[#I5PAJ5](https://gitee.com/openeuler/intel-kernel/issues/I5PAJ5)
[#I5RHW7](https://gitee.com/openeuler/intel-kernel/issues/I5RHW7)

 **Test** 
1. Built and run the kernel successfully on OpenEuler 22.03 LTS.
2. SPR new instructions feature(AVX_VNNI and AVX512_FP16) is supported on guests.
3. Bus Lock Debug Exception feature is supported on guests. 
4. Bus Lock VM Exit feature is supported.
5. Notify VM Exit feature is supported. 

 **Known Issue** 
N/A

 **Default config change** 
N/A 
 
Link:https://gitee.com/openeuler/kernel/pulls/166

 
Reviewed-by: default avatarKevin Zhu <zhukeqian1@huawei.com>
Reviewed-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
Reviewed-by: default avatarJason Zeng <jason.zeng@intel.com>
Reviewed-by: default avatarChen Wei <chenwei@xfusion.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents 4ef5a878 4f38b7f4
Loading
Loading
Loading
Loading
+100 −4
Original line number Diff line number Diff line
@@ -1084,6 +1084,10 @@ The following bits are defined in the flags field:
  fields contain a valid state. This bit will be set whenever
  KVM_CAP_EXCEPTION_PAYLOAD is enabled.

- KVM_VCPUEVENT_VALID_TRIPLE_FAULT may be set to signal that the
  triple_fault_pending field contains a valid state. This bit will
  be set whenever KVM_CAP_X86_TRIPLE_FAULT_EVENT is enabled.

ARM/ARM64:
^^^^^^^^^^

@@ -1179,6 +1183,10 @@ can be set in the flags field to signal that the
exception_has_payload, exception_payload, and exception.pending fields
contain a valid state and shall be written into the VCPU.

If KVM_CAP_X86_TRIPLE_FAULT_EVENT is enabled, KVM_VCPUEVENT_VALID_TRIPLE_FAULT
can be set in flags field to signal that the triple_fault field contains
a valid state and shall be written into the VCPU.

ARM/ARM64:
^^^^^^^^^^

@@ -5033,9 +5041,11 @@ local APIC is not used.
	__u16 flags;

More architecture-specific flags detailing state of the VCPU that may
affect the device's behavior.  The only currently defined flag is
KVM_RUN_X86_SMM, which is valid on x86 machines and is set if the
VCPU is in system management mode.
affect the device's behavior. Current defined flags:
  /* x86, set if the VCPU is in system management mode */
  #define KVM_RUN_X86_SMM     (1 << 0)
  /* x86, set if bus lock detected in VM */
  #define KVM_RUN_BUS_LOCK    (1 << 1)

::

@@ -5486,6 +5496,26 @@ array field represents return values. The userspace should update the return
values of SBI call before resuming the VCPU. For more details on RISC-V SBI
spec refer, https://github.com/riscv/riscv-sbi-doc.

::

    /* KVM_EXIT_NOTIFY */
    struct {
  #define KVM_NOTIFY_CONTEXT_INVALID	(1 << 0)
      __u32 flags;
    } notify;

Used on x86 systems. When the VM capability KVM_CAP_X86_NOTIFY_VMEXIT is
enabled, a VM exit generated if no event window occurs in VM non-root mode
for a specified amount of time. Once KVM_X86_NOTIFY_VMEXIT_USER is set when
enabling the cap, it would exit to userspace with the exit reason
KVM_EXIT_NOTIFY for further handling. The "flags" field contains more
detailed info.

The valid value for 'flags' is:

  - KVM_NOTIFY_CONTEXT_INVALID -- the VM context is corrupted and not valid
    in VMCS. It would run into unknown result if resume the target VM.

::

		/* Fix the size of the union. */
@@ -6197,7 +6227,7 @@ KVM_EXIT_X86_RDMSR and KVM_EXIT_X86_WRMSR exit notifications which user space
can then handle to implement model specific MSR handling and/or user notifications
to inform a user that an MSR was not handled.

7.25 KVM_CAP_SGX_ATTRIBUTE
7.22 KVM_CAP_SGX_ATTRIBUTE
----------------------

:Architectures: x86
@@ -6241,6 +6271,72 @@ if the value was set to zero or KVM_ENABLE_CAP was not invoked, KVM
uses the return value of KVM_CHECK_EXTENSION(KVM_CAP_MAX_VCPU_ID) as
the maximum APIC ID.

7.24 KVM_CAP_X86_BUS_LOCK_EXIT
-------------------------------

:Architectures: x86
:Target: VM
:Parameters: args[0] defines the policy used when bus locks detected in guest
:Returns: 0 on success, -EINVAL when args[0] contains invalid bits

Valid bits in args[0] are::

  #define KVM_BUS_LOCK_DETECTION_OFF      (1 << 0)
  #define KVM_BUS_LOCK_DETECTION_EXIT     (1 << 1)

Enabling this capability on a VM provides userspace with a way to select
a policy to handle the bus locks detected in guest. Userspace can obtain
the supported modes from the result of KVM_CHECK_EXTENSION and define it
through the KVM_ENABLE_CAP.

KVM_BUS_LOCK_DETECTION_OFF and KVM_BUS_LOCK_DETECTION_EXIT are supported
currently and mutually exclusive with each other. More bits can be added in
the future.

With KVM_BUS_LOCK_DETECTION_OFF set, bus locks in guest will not cause vm exits
so that no additional actions are needed. This is the default mode.

With KVM_BUS_LOCK_DETECTION_EXIT set, vm exits happen when bus lock detected
in VM. KVM just exits to userspace when handling them. Userspace can enforce
its own throttling or other policy based mitigations.

This capability is aimed to address the thread that VM can exploit bus locks to
degree the performance of the whole system. Once the userspace enable this
capability and select the KVM_BUS_LOCK_DETECTION_EXIT mode, KVM will set the
KVM_RUN_BUS_LOCK flag in vcpu-run->flags field and exit to userspace. Concerning
the bus lock vm exit can be preempted by a higher priority VM exit, the exit
notifications to userspace can be KVM_EXIT_BUS_LOCK or other reasons.
KVM_RUN_BUS_LOCK flag is used to distinguish between them.

7.25 KVM_CAP_X86_NOTIFY_VMEXIT
------------------------------

:Architectures: x86
:Target: VM
:Parameters: args[0] is the value of notify window as well as some flags
:Returns: 0 on success, -EINVAL if args[0] contains invalid flags or notify
          VM exit is unsupported.

Bits 63:32 of args[0] are used for notify window.
Bits 31:0 of args[0] are for some flags. Valid bits are::

  #define KVM_X86_NOTIFY_VMEXIT_ENABLED    (1 << 0)
  #define KVM_X86_NOTIFY_VMEXIT_USER       (1 << 1)

This capability allows userspace to configure the notify VM exit on/off
in per-VM scope during VM creation. Notify VM exit is disabled by default.
When userspace sets KVM_X86_NOTIFY_VMEXIT_ENABLED bit in args[0], VMM will
enable this feature with the notify window provided, which will generate
a VM exit if no event window occurs in VM non-root mode for a specified of
time (notify window).

If KVM_X86_NOTIFY_VMEXIT_USER is set in args[0], upon notify VM exits happen,
KVM would exit to userspace for handling.

This capability is aimed to mitigate the threat that malicious VMs can
cause CPU stuck (due to event windows don't open up) and make the CPU
unavailable to host or other VMs.

8. Other capabilities.
======================

+28 −3
Original line number Diff line number Diff line
@@ -52,6 +52,12 @@
#define KVM_DIRTY_LOG_MANUAL_CAPS   (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
					KVM_DIRTY_LOG_INITIALLY_SET)

#define KVM_BUS_LOCK_DETECTION_VALID_MODE	(KVM_BUS_LOCK_DETECTION_OFF | \
						 KVM_BUS_LOCK_DETECTION_EXIT)

#define KVM_X86_NOTIFY_VMEXIT_VALID_BITS	(KVM_X86_NOTIFY_VMEXIT_ENABLED | \
						 KVM_X86_NOTIFY_VMEXIT_USER)

/* x86-specific vcpu->requests bit members */
#define KVM_REQ_MIGRATE_TIMER		KVM_ARCH_REQ(0)
#define KVM_REQ_REPORT_TPR_ACCESS	KVM_ARCH_REQ(1)
@@ -196,13 +202,22 @@ enum x86_intercept_stage;

#define KVM_NR_DB_REGS	4

#define DR6_BUS_LOCK    (1 << 11)
#define DR6_BD		(1 << 13)
#define DR6_BS		(1 << 14)
#define DR6_BT		(1 << 15)
#define DR6_RTM		(1 << 16)
#define DR6_FIXED_1	0xfffe0ff0
#define DR6_INIT	0xffff0ff0
#define DR6_VOLATILE	0x0001e00f
/*
 * DR6_ACTIVE_LOW combines fixed-1 and active-low bits.
 * We can regard all the bits in DR6_FIXED_1 as active_low bits;
 * they will never be 0 for now, but when they are defined
 * in the future it will require no code change.
 *
 * DR6_ACTIVE_LOW is also used as the init/reset value for DR6.
 */
#define DR6_ACTIVE_LOW	0xffff0ff0
#define DR6_VOLATILE	0x0001e80f
#define DR6_FIXED_1	(DR6_ACTIVE_LOW & ~DR6_VOLATILE)

#define DR7_BP_EN_MASK	0x000000ff
#define DR7_GE		(1 << 9)
@@ -994,8 +1009,13 @@ struct kvm_arch {
	bool guest_can_read_msr_platform_info;
	bool exception_payload_enabled;

	bool triple_fault_event;

	bool bus_lock_detection_enabled;

	u32 notify_window;
	u32 notify_vmexit_flags;

	/* Guest can access the SGX PROVISIONKEY. */
	bool sgx_provisioning_allowed;

@@ -1088,6 +1108,7 @@ struct kvm_vcpu_stat {
	u64 preemption_reported;
	u64 preemption_other;
	u64 preemption_timer_exits;
	u64 notify_window_exits;
};

struct x86_instruction_info;
@@ -1436,6 +1457,10 @@ extern u8 kvm_tsc_scaling_ratio_frac_bits;
extern u64  kvm_max_tsc_scaling_ratio;
/* 1ull << kvm_tsc_scaling_ratio_frac_bits */
extern u64  kvm_default_tsc_scaling_ratio;
/* bus lock detection supported? */
extern bool kvm_has_bus_lock_exit;
/* notify vmexit supported? */
extern bool kvm_has_notify_vmexit;

extern u64 kvm_mce_cap_supported;

+8 −0
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@
#define SECONDARY_EXEC_PT_USE_GPA		VMCS_CONTROL_BIT(PT_USE_GPA)
#define SECONDARY_EXEC_TSC_SCALING              VMCS_CONTROL_BIT(TSC_SCALING)
#define SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE	VMCS_CONTROL_BIT(USR_WAIT_PAUSE)
#define SECONDARY_EXEC_BUS_LOCK_DETECTION	VMCS_CONTROL_BIT(BUS_LOCK_DETECTION)
#define SECONDARY_EXEC_NOTIFY_VM_EXITING	VMCS_CONTROL_BIT(NOTIFY_VM_EXITING)

/*
 * Definitions of Tertiary Processor-Based VM-Execution Controls.
@@ -279,6 +281,7 @@ enum vmcs_field {
	SECONDARY_VM_EXEC_CONTROL       = 0x0000401e,
	PLE_GAP                         = 0x00004020,
	PLE_WINDOW                      = 0x00004022,
	NOTIFY_WINDOW                   = 0x00004024,
	VM_INSTRUCTION_ERROR            = 0x00004400,
	VM_EXIT_REASON                  = 0x00004402,
	VM_EXIT_INTR_INFO               = 0x00004404,
@@ -565,6 +568,11 @@ enum vm_entry_failure_code {
#define EPT_VIOLATION_EXECUTABLE	(1 << EPT_VIOLATION_EXECUTABLE_BIT)
#define EPT_VIOLATION_GVA_TRANSLATED	(1 << EPT_VIOLATION_GVA_TRANSLATED_BIT)

/*
 * Exit Qualifications for NOTIFY VM EXIT
 */
#define NOTIFY_VM_CONTEXT_INVALID     BIT(0)

/*
 * VM-instruction error numbers
 */
+2 −0
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@
#define VMX_FEATURE_TSC_SCALING		( 2*32+ 25) /* Scale hardware TSC when read in guest */
#define VMX_FEATURE_USR_WAIT_PAUSE	( 2*32+ 26) /* Enable TPAUSE, UMONITOR, UMWAIT in guest */
#define VMX_FEATURE_ENCLV_EXITING	( 2*32+ 28) /* "" VM-Exit on ENCLV (leaf dependent) */
#define VMX_FEATURE_BUS_LOCK_DETECTION	( 2*32+ 30) /* "" VM-Exit when bus lock caused */
#define VMX_FEATURE_NOTIFY_VM_EXITING	( 2*32+ 31) /* VM-Exit when no event windows after notify window */

/* Tertiary Processor-Based VM-Execution Controls, word 3 */
#define VMX_TERTIARY_FEATURE_IPI_VIRT		( 3*32+  4) /* Enable IPI virtualization */
+6 −1
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ struct kvm_ioapic_state {
#define KVM_NR_IRQCHIPS          3

#define KVM_RUN_X86_SMM		 (1 << 0)
#define KVM_RUN_X86_BUS_LOCK     (1 << 1)

/* for KVM_GET_REGS and KVM_SET_REGS */
struct kvm_regs {
@@ -309,6 +310,7 @@ struct kvm_reinject_control {
#define KVM_VCPUEVENT_VALID_SHADOW	0x00000004
#define KVM_VCPUEVENT_VALID_SMM		0x00000008
#define KVM_VCPUEVENT_VALID_PAYLOAD	0x00000010
#define KVM_VCPUEVENT_VALID_TRIPLE_FAULT	0x00000020

/* Interrupt shadow states */
#define KVM_X86_SHADOW_INT_MOV_SS	0x01
@@ -343,7 +345,10 @@ struct kvm_vcpu_events {
		__u8 smm_inside_nmi;
		__u8 latched_init;
	} smi;
	__u8 reserved[27];
	struct {
		__u8 pending;
	} triple_fault;
	__u8 reserved[26];
	__u8 exception_has_payload;
	__u64 exception_payload;
};
Loading