2018-03-07 20:57:14 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in
|
|
|
|
* the documentation and/or other materials provided with the
|
|
|
|
* distribution.
|
|
|
|
* * Neither the name of Intel Corporation nor the names of its
|
|
|
|
* contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef VM_H_
|
|
|
|
#define VM_H_
|
|
|
|
|
|
|
|
enum vm_privilege_level {
|
|
|
|
VM_PRIVILEGE_LEVEL_HIGH = 0,
|
|
|
|
VM_PRIVILEGE_LEVEL_MEDIUM,
|
|
|
|
VM_PRIVILEGE_LEVEL_LOW
|
|
|
|
};
|
|
|
|
|
|
|
|
#define MAX_VM_NAME_LEN 16
|
|
|
|
struct vm_attr {
|
2018-03-23 03:05:50 +08:00
|
|
|
char name[MAX_VM_NAME_LEN]; /* Virtual machine name string */
|
2018-03-07 20:57:14 +08:00
|
|
|
int id; /* Virtual machine identifier */
|
|
|
|
int boot_idx; /* Index indicating the boot sequence for this VM */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct vm_hw_info {
|
|
|
|
int num_vcpus; /* Number of total virtual cores */
|
2018-05-15 10:57:24 +08:00
|
|
|
int exp_num_vcpus; /* Number of real expected virtual cores */
|
2018-05-16 16:12:22 +08:00
|
|
|
int created_vcpus; /* Number of created vcpus */
|
2018-03-07 20:57:14 +08:00
|
|
|
struct vcpu **vcpu_array; /* vcpu array of this VM */
|
|
|
|
uint64_t gpa_lowtop; /* top lowmem gpa of this VM */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct sw_linux {
|
|
|
|
void *ramdisk_src_addr;
|
|
|
|
void *ramdisk_load_addr;
|
|
|
|
uint32_t ramdisk_size;
|
|
|
|
void *bootargs_src_addr;
|
|
|
|
void *bootargs_load_addr;
|
|
|
|
uint32_t bootargs_size;
|
|
|
|
void *dtb_src_addr;
|
|
|
|
void *dtb_load_addr;
|
|
|
|
uint32_t dtb_size;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct sw_kernel_info {
|
|
|
|
void *kernel_src_addr;
|
|
|
|
void *kernel_load_addr;
|
|
|
|
void *kernel_entry_addr;
|
|
|
|
uint32_t kernel_size;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct vm_sw_info {
|
|
|
|
int kernel_type; /* Guest kernel type */
|
|
|
|
/* Kernel information (common for all guest types) */
|
|
|
|
struct sw_kernel_info kernel_info;
|
|
|
|
/* Additional information specific to Linux guests */
|
|
|
|
struct sw_linux linux_info;
|
2018-05-07 19:19:02 +08:00
|
|
|
/* HVA to IO shared page */
|
|
|
|
void *io_shared_page;
|
2018-03-07 20:57:14 +08:00
|
|
|
};
|
|
|
|
|
2018-04-05 19:58:40 +08:00
|
|
|
struct vm_pm_info {
|
2018-04-18 00:07:38 +08:00
|
|
|
uint8_t px_cnt; /* count of all Px states */
|
2018-04-05 19:58:40 +08:00
|
|
|
struct cpu_px_data px_data[MAX_PSTATE];
|
2018-04-18 00:07:38 +08:00
|
|
|
uint8_t cx_cnt; /* count of all Cx entries */
|
|
|
|
struct cpu_cx_data cx_data[MAX_CSTATE];
|
2018-04-05 19:58:40 +08:00
|
|
|
};
|
|
|
|
|
2018-03-07 20:57:14 +08:00
|
|
|
/* VM guest types */
|
|
|
|
#define VM_LINUX_GUEST 0x02
|
|
|
|
#define VM_MONO_GUEST 0x01
|
|
|
|
|
|
|
|
enum vpic_wire_mode {
|
|
|
|
VPIC_WIRE_INTR = 0,
|
|
|
|
VPIC_WIRE_LAPIC,
|
|
|
|
VPIC_WIRE_IOAPIC,
|
|
|
|
VPIC_WIRE_NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Enumerated type for VM states */
|
|
|
|
enum vm_state {
|
|
|
|
VM_CREATED = 0, /* VM created / awaiting start (boot) */
|
|
|
|
VM_STARTED, /* VM started (booted) */
|
|
|
|
VM_PAUSED, /* VM paused */
|
|
|
|
VM_STATE_UNKNOWN
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Structure for VM state information */
|
|
|
|
struct vm_state_info {
|
|
|
|
enum vm_state state; /* State of the VM */
|
|
|
|
unsigned int privilege; /* Privilege level of the VM */
|
|
|
|
unsigned int boot_count;/* Number of times the VM has booted */
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
struct vm_arch {
|
2018-04-03 18:45:29 +08:00
|
|
|
uint64_t guest_init_pml4;/* Guest init pml4 */
|
2018-03-05 15:09:30 +08:00
|
|
|
/* EPT hierarchy for Normal World */
|
2018-04-03 22:25:40 +08:00
|
|
|
uint64_t nworld_eptp;
|
2018-03-05 15:09:30 +08:00
|
|
|
/* EPT hierarchy for Secure World
|
|
|
|
* Secure world can access Normal World's memory,
|
|
|
|
* but Normal World can not access Secure World's memory.
|
|
|
|
*/
|
2018-04-03 22:25:40 +08:00
|
|
|
uint64_t sworld_eptp;
|
|
|
|
uint64_t m2p; /* machine address to guest physical address */
|
2018-03-07 20:57:14 +08:00
|
|
|
void *tmp_pg_array; /* Page array for tmp guest paging struct */
|
|
|
|
void *iobitmap[2];/* IO bitmap page array base address for this VM */
|
|
|
|
void *msr_bitmap; /* MSR bitmap page base address for this VM */
|
|
|
|
void *virt_ioapic; /* Virtual IOAPIC base address */
|
|
|
|
/**
|
|
|
|
* A link to the IO handler of this VM.
|
|
|
|
* We only register io handle to this link
|
|
|
|
* when create VM on sequences and ungister it when
|
|
|
|
* destory VM. So there no need lock to prevent preempt.
|
|
|
|
* Besides, there only a few io handlers now, we don't
|
|
|
|
* need binary search temporary.
|
|
|
|
*/
|
|
|
|
struct vm_io_handler *io_handler;
|
|
|
|
|
|
|
|
/* reference to virtual platform to come here (as needed) */
|
|
|
|
};
|
|
|
|
|
2018-03-23 03:05:50 +08:00
|
|
|
#define CPUID_CHECK_SUBLEAF (1 << 0)
|
|
|
|
#define MAX_VM_VCPUID_ENTRIES 64
|
|
|
|
struct vcpuid_entry {
|
|
|
|
uint32_t eax;
|
|
|
|
uint32_t ebx;
|
|
|
|
uint32_t ecx;
|
|
|
|
uint32_t edx;
|
|
|
|
uint32_t leaf;
|
|
|
|
uint32_t subleaf;
|
|
|
|
uint32_t flags;
|
|
|
|
uint32_t padding;
|
|
|
|
};
|
|
|
|
|
2018-03-07 20:57:14 +08:00
|
|
|
struct vpic;
|
|
|
|
struct vm {
|
|
|
|
struct vm_attr attr; /* Reference to this VM's attributes */
|
|
|
|
struct vm_hw_info hw; /* Reference to this VM's HW information */
|
|
|
|
struct vm_sw_info sw; /* Reference to SW associated with this VM */
|
2018-04-05 19:58:40 +08:00
|
|
|
struct vm_pm_info pm; /* Reference to this VM's arch information */
|
2018-03-07 20:57:14 +08:00
|
|
|
struct vm_arch arch_vm; /* Reference to this VM's arch information */
|
|
|
|
struct vm_state_info state_info;/* State info of this VM */
|
|
|
|
enum vm_state state; /* VM state */
|
|
|
|
struct vcpu *current_vcpu; /* VCPU that caused vm exit */
|
|
|
|
void *vuart; /* Virtual UART */
|
|
|
|
struct vpic *vpic; /* Virtual PIC */
|
|
|
|
uint32_t vpic_wire_mode;
|
|
|
|
struct iommu_domain *iommu_domain; /* iommu domain of this VM */
|
|
|
|
struct list_head list; /* list of VM */
|
|
|
|
spinlock_t spinlock; /* Spin-lock used to protect VM modifications */
|
|
|
|
|
|
|
|
struct list_head mmio_list; /* list for mmio. This list is not updated
|
|
|
|
* when vm is active. So no lock needed
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct _vm_shared_memory *shared_memory_area;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
struct _vm_virtual_device_node *head;
|
|
|
|
struct _vm_virtual_device_node *tail;
|
|
|
|
} virtual_device_list;
|
|
|
|
|
|
|
|
unsigned char GUID[16];
|
2018-03-05 15:09:30 +08:00
|
|
|
struct secure_world_control sworld_control;
|
2018-03-23 03:05:50 +08:00
|
|
|
|
|
|
|
uint32_t vcpuid_entry_nr, vcpuid_level, vcpuid_xlevel;
|
|
|
|
struct vcpuid_entry vcpuid_entries[MAX_VM_VCPUID_ENTRIES];
|
2018-03-07 20:57:14 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct vm_description {
|
|
|
|
/* Virtual machine identifier, assigned by the system */
|
|
|
|
char *vm_attr_name;
|
|
|
|
/* The logical CPU IDs associated with this VM - The first CPU listed
|
|
|
|
* will be the VM's BSP
|
|
|
|
*/
|
|
|
|
int *vm_hw_logical_core_ids;
|
|
|
|
unsigned char GUID[16]; /* GUID of the vm will be created */
|
|
|
|
int vm_hw_num_cores; /* Number of virtual cores */
|
|
|
|
/* Indicates to APs that the BSP has created a VM for this
|
|
|
|
* description
|
|
|
|
*/
|
|
|
|
bool vm_created;
|
|
|
|
/* Index indicating VM's privilege level */
|
|
|
|
unsigned int vm_state_info_privilege;
|
2018-03-05 15:09:30 +08:00
|
|
|
/* Whether secure world is enabled for current VM. */
|
|
|
|
bool sworld_enabled;
|
2018-03-07 20:57:14 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct vm_description_array {
|
|
|
|
int num_vm_desc;
|
|
|
|
struct vm_description vm_desc_array[];
|
|
|
|
};
|
|
|
|
|
|
|
|
int shutdown_vm(struct vm *vm);
|
|
|
|
int pause_vm(struct vm *vm);
|
|
|
|
int start_vm(struct vm *vm);
|
|
|
|
int create_vm(struct vm_description *vm_desc, struct vm **vm);
|
|
|
|
int prepare_vm0(void);
|
2018-05-15 10:57:24 +08:00
|
|
|
void vm_fixup(struct vm *vm);
|
2018-03-07 20:57:14 +08:00
|
|
|
|
|
|
|
struct vm *get_vm_from_vmid(int vm_id);
|
|
|
|
struct vm_description *get_vm_desc(int idx);
|
|
|
|
|
|
|
|
extern struct list_head vm_list;
|
|
|
|
extern spinlock_t vm_list_lock;
|
|
|
|
extern bool x2apic_enabled;
|
|
|
|
|
|
|
|
#endif /* VM_H_ */
|