mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-25 06:03:36 -04:00
Merge branch 'kvm-updates-2.6.27' of git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm
* 'kvm-updates-2.6.27' of git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm: (70 commits) KVM: Adjust smp_call_function_mask() callers to new requirements KVM: MMU: Fix potential race setting upper shadow ptes on nonpae hosts KVM: x86 emulator: emulate clflush KVM: MMU: improve invalid shadow root page handling KVM: MMU: nuke shadowed pgtable pages and ptes on memslot destruction KVM: Prefix some x86 low level function with kvm_, to avoid namespace issues KVM: check injected pic irq within valid pic irqs KVM: x86 emulator: Fix HLT instruction KVM: Apply the kernel sigmask to vcpus blocked due to being uninitialized KVM: VMX: Add ept_sync_context in flush_tlb KVM: mmu_shrink: kvm_mmu_zap_page requires slots_lock to be held x86: KVM guest: make kvm_smp_prepare_boot_cpu() static KVM: SVM: fix suspend/resume support KVM: s390: rename private structures KVM: s390: Set guest storage limit and offset to sane values KVM: Fix memory leak on guest exit KVM: s390: dont allocate dirty bitmap KVM: move slots_lock acquision down to vapic_exit KVM: VMX: Fake emulate Intel perfctr MSRs KVM: VMX: Fix a wrong usage of vmcs_config ...
This commit is contained in:
commit
f076ab8d04
37 changed files with 1215 additions and 520 deletions
|
|
@ -38,6 +38,7 @@
|
|||
/* memory slots that does not exposed to userspace */
|
||||
#define KVM_PRIVATE_MEM_SLOTS 4
|
||||
|
||||
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
|
||||
|
||||
/* define exit reasons from vmm to kvm*/
|
||||
#define EXIT_REASON_VM_PANIC 0
|
||||
|
|
@ -521,4 +522,6 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu);
|
|||
int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
|
||||
void kvm_sal_emul(struct kvm_vcpu *vcpu);
|
||||
|
||||
static inline void kvm_inject_nmi(struct kvm_vcpu *vcpu) {}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
/* memory slots that does not exposed to userspace */
|
||||
#define KVM_PRIVATE_MEM_SLOTS 4
|
||||
|
||||
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
|
||||
|
||||
/* We don't currently support large pages. */
|
||||
#define KVM_PAGES_PER_HPAGE (1<<31)
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ struct sca_block {
|
|||
#define CPUSTAT_J 0x00000002
|
||||
#define CPUSTAT_P 0x00000001
|
||||
|
||||
struct sie_block {
|
||||
struct kvm_s390_sie_block {
|
||||
atomic_t cpuflags; /* 0x0000 */
|
||||
__u32 prefix; /* 0x0004 */
|
||||
__u8 reserved8[32]; /* 0x0008 */
|
||||
|
|
@ -140,14 +140,14 @@ struct kvm_vcpu_stat {
|
|||
u32 diagnose_44;
|
||||
};
|
||||
|
||||
struct io_info {
|
||||
struct kvm_s390_io_info {
|
||||
__u16 subchannel_id; /* 0x0b8 */
|
||||
__u16 subchannel_nr; /* 0x0ba */
|
||||
__u32 io_int_parm; /* 0x0bc */
|
||||
__u32 io_int_word; /* 0x0c0 */
|
||||
};
|
||||
|
||||
struct ext_info {
|
||||
struct kvm_s390_ext_info {
|
||||
__u32 ext_params;
|
||||
__u64 ext_params2;
|
||||
};
|
||||
|
|
@ -160,22 +160,22 @@ struct ext_info {
|
|||
#define PGM_SPECIFICATION 0x06
|
||||
#define PGM_DATA 0x07
|
||||
|
||||
struct pgm_info {
|
||||
struct kvm_s390_pgm_info {
|
||||
__u16 code;
|
||||
};
|
||||
|
||||
struct prefix_info {
|
||||
struct kvm_s390_prefix_info {
|
||||
__u32 address;
|
||||
};
|
||||
|
||||
struct interrupt_info {
|
||||
struct kvm_s390_interrupt_info {
|
||||
struct list_head list;
|
||||
u64 type;
|
||||
union {
|
||||
struct io_info io;
|
||||
struct ext_info ext;
|
||||
struct pgm_info pgm;
|
||||
struct prefix_info prefix;
|
||||
struct kvm_s390_io_info io;
|
||||
struct kvm_s390_ext_info ext;
|
||||
struct kvm_s390_pgm_info pgm;
|
||||
struct kvm_s390_prefix_info prefix;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -183,35 +183,35 @@ struct interrupt_info {
|
|||
#define ACTION_STORE_ON_STOP 1
|
||||
#define ACTION_STOP_ON_STOP 2
|
||||
|
||||
struct local_interrupt {
|
||||
struct kvm_s390_local_interrupt {
|
||||
spinlock_t lock;
|
||||
struct list_head list;
|
||||
atomic_t active;
|
||||
struct float_interrupt *float_int;
|
||||
struct kvm_s390_float_interrupt *float_int;
|
||||
int timer_due; /* event indicator for waitqueue below */
|
||||
wait_queue_head_t wq;
|
||||
atomic_t *cpuflags;
|
||||
unsigned int action_bits;
|
||||
};
|
||||
|
||||
struct float_interrupt {
|
||||
struct kvm_s390_float_interrupt {
|
||||
spinlock_t lock;
|
||||
struct list_head list;
|
||||
atomic_t active;
|
||||
int next_rr_cpu;
|
||||
unsigned long idle_mask [(64 + sizeof(long) - 1) / sizeof(long)];
|
||||
struct local_interrupt *local_int[64];
|
||||
struct kvm_s390_local_interrupt *local_int[64];
|
||||
};
|
||||
|
||||
|
||||
struct kvm_vcpu_arch {
|
||||
struct sie_block *sie_block;
|
||||
struct kvm_s390_sie_block *sie_block;
|
||||
unsigned long guest_gprs[16];
|
||||
s390_fp_regs host_fpregs;
|
||||
unsigned int host_acrs[NUM_ACRS];
|
||||
s390_fp_regs guest_fpregs;
|
||||
unsigned int guest_acrs[NUM_ACRS];
|
||||
struct local_interrupt local_int;
|
||||
struct kvm_s390_local_interrupt local_int;
|
||||
struct timer_list ckc_timer;
|
||||
union {
|
||||
cpuid_t cpu_id;
|
||||
|
|
@ -228,8 +228,8 @@ struct kvm_arch{
|
|||
unsigned long guest_memsize;
|
||||
struct sca_block *sca;
|
||||
debug_info_t *dbf;
|
||||
struct float_interrupt float_int;
|
||||
struct kvm_s390_float_interrupt float_int;
|
||||
};
|
||||
|
||||
extern int sie64a(struct sie_block *, __u64 *);
|
||||
extern int sie64a(struct kvm_s390_sie_block *, __u64 *);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -228,5 +228,6 @@ struct kvm_pit_state {
|
|||
#define KVM_TRC_CLTS (KVM_TRC_HANDLER + 0x12)
|
||||
#define KVM_TRC_LMSW (KVM_TRC_HANDLER + 0x13)
|
||||
#define KVM_TRC_APIC_ACCESS (KVM_TRC_HANDLER + 0x14)
|
||||
#define KVM_TRC_TDP_FAULT (KVM_TRC_HANDLER + 0x15)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#define KVM_PRIVATE_MEM_SLOTS 4
|
||||
|
||||
#define KVM_PIO_PAGE_OFFSET 1
|
||||
#define KVM_COALESCED_MMIO_PAGE_OFFSET 2
|
||||
|
||||
#define CR3_PAE_RESERVED_BITS ((X86_CR3_PWT | X86_CR3_PCD) - 1)
|
||||
#define CR3_NONPAE_RESERVED_BITS ((PAGE_SIZE-1) & ~(X86_CR3_PWT | X86_CR3_PCD))
|
||||
|
|
@ -79,6 +80,7 @@
|
|||
#define KVM_MIN_FREE_MMU_PAGES 5
|
||||
#define KVM_REFILL_PAGES 25
|
||||
#define KVM_MAX_CPUID_ENTRIES 40
|
||||
#define KVM_NR_VAR_MTRR 8
|
||||
|
||||
extern spinlock_t kvm_lock;
|
||||
extern struct list_head vm_list;
|
||||
|
|
@ -109,12 +111,12 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
VCPU_SREG_CS,
|
||||
VCPU_SREG_DS,
|
||||
VCPU_SREG_ES,
|
||||
VCPU_SREG_CS,
|
||||
VCPU_SREG_SS,
|
||||
VCPU_SREG_DS,
|
||||
VCPU_SREG_FS,
|
||||
VCPU_SREG_GS,
|
||||
VCPU_SREG_SS,
|
||||
VCPU_SREG_TR,
|
||||
VCPU_SREG_LDTR,
|
||||
};
|
||||
|
|
@ -243,6 +245,7 @@ struct kvm_vcpu_arch {
|
|||
gfn_t last_pt_write_gfn;
|
||||
int last_pt_write_count;
|
||||
u64 *last_pte_updated;
|
||||
gfn_t last_pte_gfn;
|
||||
|
||||
struct {
|
||||
gfn_t gfn; /* presumed gfn during guest pte update */
|
||||
|
|
@ -287,6 +290,10 @@ struct kvm_vcpu_arch {
|
|||
unsigned int hv_clock_tsc_khz;
|
||||
unsigned int time_offset;
|
||||
struct page *time_page;
|
||||
|
||||
bool nmi_pending;
|
||||
|
||||
u64 mtrr[0x100];
|
||||
};
|
||||
|
||||
struct kvm_mem_alias {
|
||||
|
|
@ -344,6 +351,7 @@ struct kvm_vcpu_stat {
|
|||
u32 mmio_exits;
|
||||
u32 signal_exits;
|
||||
u32 irq_window_exits;
|
||||
u32 nmi_window_exits;
|
||||
u32 halt_exits;
|
||||
u32 halt_wakeup;
|
||||
u32 request_irq_exits;
|
||||
|
|
@ -379,7 +387,6 @@ struct kvm_x86_ops {
|
|||
void (*prepare_guest_switch)(struct kvm_vcpu *vcpu);
|
||||
void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu);
|
||||
void (*vcpu_put)(struct kvm_vcpu *vcpu);
|
||||
void (*vcpu_decache)(struct kvm_vcpu *vcpu);
|
||||
|
||||
int (*set_guest_debug)(struct kvm_vcpu *vcpu,
|
||||
struct kvm_debug_guest *dbg);
|
||||
|
|
@ -497,6 +504,10 @@ int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr,
|
|||
int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr,
|
||||
unsigned long value);
|
||||
|
||||
void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg);
|
||||
int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
|
||||
int type_bits, int seg);
|
||||
|
||||
int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason);
|
||||
|
||||
void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
|
||||
|
|
@ -515,6 +526,8 @@ void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
|
|||
void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
|
||||
u32 error_code);
|
||||
|
||||
void kvm_inject_nmi(struct kvm_vcpu *vcpu);
|
||||
|
||||
void fx_init(struct kvm_vcpu *vcpu);
|
||||
|
||||
int emulator_read_std(unsigned long addr,
|
||||
|
|
@ -554,55 +567,53 @@ static inline struct kvm_mmu_page *page_header(hpa_t shadow_page)
|
|||
return (struct kvm_mmu_page *)page_private(page);
|
||||
}
|
||||
|
||||
static inline u16 read_fs(void)
|
||||
static inline u16 kvm_read_fs(void)
|
||||
{
|
||||
u16 seg;
|
||||
asm("mov %%fs, %0" : "=g"(seg));
|
||||
return seg;
|
||||
}
|
||||
|
||||
static inline u16 read_gs(void)
|
||||
static inline u16 kvm_read_gs(void)
|
||||
{
|
||||
u16 seg;
|
||||
asm("mov %%gs, %0" : "=g"(seg));
|
||||
return seg;
|
||||
}
|
||||
|
||||
static inline u16 read_ldt(void)
|
||||
static inline u16 kvm_read_ldt(void)
|
||||
{
|
||||
u16 ldt;
|
||||
asm("sldt %0" : "=g"(ldt));
|
||||
return ldt;
|
||||
}
|
||||
|
||||
static inline void load_fs(u16 sel)
|
||||
static inline void kvm_load_fs(u16 sel)
|
||||
{
|
||||
asm("mov %0, %%fs" : : "rm"(sel));
|
||||
}
|
||||
|
||||
static inline void load_gs(u16 sel)
|
||||
static inline void kvm_load_gs(u16 sel)
|
||||
{
|
||||
asm("mov %0, %%gs" : : "rm"(sel));
|
||||
}
|
||||
|
||||
#ifndef load_ldt
|
||||
static inline void load_ldt(u16 sel)
|
||||
static inline void kvm_load_ldt(u16 sel)
|
||||
{
|
||||
asm("lldt %0" : : "rm"(sel));
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void get_idt(struct descriptor_table *table)
|
||||
static inline void kvm_get_idt(struct descriptor_table *table)
|
||||
{
|
||||
asm("sidt %0" : "=m"(*table));
|
||||
}
|
||||
|
||||
static inline void get_gdt(struct descriptor_table *table)
|
||||
static inline void kvm_get_gdt(struct descriptor_table *table)
|
||||
{
|
||||
asm("sgdt %0" : "=m"(*table));
|
||||
}
|
||||
|
||||
static inline unsigned long read_tr_base(void)
|
||||
static inline unsigned long kvm_read_tr_base(void)
|
||||
{
|
||||
u16 tr;
|
||||
asm("str %0" : "=g"(tr));
|
||||
|
|
@ -619,17 +630,17 @@ static inline unsigned long read_msr(unsigned long msr)
|
|||
}
|
||||
#endif
|
||||
|
||||
static inline void fx_save(struct i387_fxsave_struct *image)
|
||||
static inline void kvm_fx_save(struct i387_fxsave_struct *image)
|
||||
{
|
||||
asm("fxsave (%0)":: "r" (image));
|
||||
}
|
||||
|
||||
static inline void fx_restore(struct i387_fxsave_struct *image)
|
||||
static inline void kvm_fx_restore(struct i387_fxsave_struct *image)
|
||||
{
|
||||
asm("fxrstor (%0)":: "r" (image));
|
||||
}
|
||||
|
||||
static inline void fx_finit(void)
|
||||
static inline void kvm_fx_finit(void)
|
||||
{
|
||||
asm("finit");
|
||||
}
|
||||
|
|
@ -691,4 +702,28 @@ enum {
|
|||
trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
|
||||
vcpu, 0, 0, 0, 0, 0, 0)
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define KVM_EX_ENTRY ".quad"
|
||||
#else
|
||||
#define KVM_EX_ENTRY ".long"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hardware virtualization extension instructions may fault if a
|
||||
* reboot turns off virtualization while processes are running.
|
||||
* Trap the fault and ignore the instruction if that happens.
|
||||
*/
|
||||
asmlinkage void kvm_handle_fault_on_reboot(void);
|
||||
|
||||
#define __kvm_handle_fault_on_reboot(insn) \
|
||||
"666: " insn "\n\t" \
|
||||
".pushsection .text.fixup, \"ax\" \n" \
|
||||
"667: \n\t" \
|
||||
"push $666b \n\t" \
|
||||
"jmp kvm_handle_fault_on_reboot \n\t" \
|
||||
".popsection \n\t" \
|
||||
".pushsection __ex_table, \"a\" \n\t" \
|
||||
KVM_EX_ENTRY " 666b, 667b \n\t" \
|
||||
".popsection"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -124,7 +124,8 @@ struct decode_cache {
|
|||
u8 rex_prefix;
|
||||
struct operand src;
|
||||
struct operand dst;
|
||||
unsigned long *override_base;
|
||||
bool has_seg_override;
|
||||
u8 seg_override;
|
||||
unsigned int d;
|
||||
unsigned long regs[NR_VCPU_REGS];
|
||||
unsigned long eip;
|
||||
|
|
@ -134,6 +135,7 @@ struct decode_cache {
|
|||
u8 modrm_reg;
|
||||
u8 modrm_rm;
|
||||
u8 use_modrm_ea;
|
||||
bool rip_relative;
|
||||
unsigned long modrm_ea;
|
||||
void *modrm_ptr;
|
||||
unsigned long modrm_val;
|
||||
|
|
@ -150,12 +152,7 @@ struct x86_emulate_ctxt {
|
|||
/* Emulated execution mode, represented by an X86EMUL_MODE value. */
|
||||
int mode;
|
||||
|
||||
unsigned long cs_base;
|
||||
unsigned long ds_base;
|
||||
unsigned long es_base;
|
||||
unsigned long ss_base;
|
||||
unsigned long gs_base;
|
||||
unsigned long fs_base;
|
||||
u32 cs_base;
|
||||
|
||||
/* decode cache */
|
||||
|
||||
|
|
|
|||
|
|
@ -173,6 +173,30 @@ struct kvm_run {
|
|||
};
|
||||
};
|
||||
|
||||
/* for KVM_REGISTER_COALESCED_MMIO / KVM_UNREGISTER_COALESCED_MMIO */
|
||||
|
||||
struct kvm_coalesced_mmio_zone {
|
||||
__u64 addr;
|
||||
__u32 size;
|
||||
__u32 pad;
|
||||
};
|
||||
|
||||
struct kvm_coalesced_mmio {
|
||||
__u64 phys_addr;
|
||||
__u32 len;
|
||||
__u32 pad;
|
||||
__u8 data[8];
|
||||
};
|
||||
|
||||
struct kvm_coalesced_mmio_ring {
|
||||
__u32 first, last;
|
||||
struct kvm_coalesced_mmio coalesced_mmio[0];
|
||||
};
|
||||
|
||||
#define KVM_COALESCED_MMIO_MAX \
|
||||
((PAGE_SIZE - sizeof(struct kvm_coalesced_mmio_ring)) / \
|
||||
sizeof(struct kvm_coalesced_mmio))
|
||||
|
||||
/* for KVM_TRANSLATE */
|
||||
struct kvm_translation {
|
||||
/* in */
|
||||
|
|
@ -294,14 +318,14 @@ struct kvm_trace_rec {
|
|||
__u32 vcpu_id;
|
||||
union {
|
||||
struct {
|
||||
__u32 cycle_lo, cycle_hi;
|
||||
__u64 cycle_u64;
|
||||
__u32 extra_u32[KVM_TRC_EXTRA_MAX];
|
||||
} cycle;
|
||||
struct {
|
||||
__u32 extra_u32[KVM_TRC_EXTRA_MAX];
|
||||
} nocycle;
|
||||
} u;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
#define KVMIO 0xAE
|
||||
|
||||
|
|
@ -346,6 +370,7 @@ struct kvm_trace_rec {
|
|||
#define KVM_CAP_NOP_IO_DELAY 12
|
||||
#define KVM_CAP_PV_MMU 13
|
||||
#define KVM_CAP_MP_STATE 14
|
||||
#define KVM_CAP_COALESCED_MMIO 15
|
||||
|
||||
/*
|
||||
* ioctls for VM fds
|
||||
|
|
@ -371,6 +396,10 @@ struct kvm_trace_rec {
|
|||
#define KVM_CREATE_PIT _IO(KVMIO, 0x64)
|
||||
#define KVM_GET_PIT _IOWR(KVMIO, 0x65, struct kvm_pit_state)
|
||||
#define KVM_SET_PIT _IOR(KVMIO, 0x66, struct kvm_pit_state)
|
||||
#define KVM_REGISTER_COALESCED_MMIO \
|
||||
_IOW(KVMIO, 0x67, struct kvm_coalesced_mmio_zone)
|
||||
#define KVM_UNREGISTER_COALESCED_MMIO \
|
||||
_IOW(KVMIO, 0x68, struct kvm_coalesced_mmio_zone)
|
||||
|
||||
/*
|
||||
* ioctls for vcpu fds
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ struct kvm_io_bus {
|
|||
|
||||
void kvm_io_bus_init(struct kvm_io_bus *bus);
|
||||
void kvm_io_bus_destroy(struct kvm_io_bus *bus);
|
||||
struct kvm_io_device *kvm_io_bus_find_dev(struct kvm_io_bus *bus, gpa_t addr);
|
||||
struct kvm_io_device *kvm_io_bus_find_dev(struct kvm_io_bus *bus,
|
||||
gpa_t addr, int len, int is_write);
|
||||
void kvm_io_bus_register_dev(struct kvm_io_bus *bus,
|
||||
struct kvm_io_device *dev);
|
||||
|
||||
|
|
@ -116,6 +117,10 @@ struct kvm {
|
|||
struct kvm_vm_stat stat;
|
||||
struct kvm_arch arch;
|
||||
atomic_t users_count;
|
||||
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
|
||||
struct kvm_coalesced_mmio_dev *coalesced_mmio_dev;
|
||||
struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* The guest did something we don't support. */
|
||||
|
|
@ -135,9 +140,6 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu);
|
|||
void vcpu_load(struct kvm_vcpu *vcpu);
|
||||
void vcpu_put(struct kvm_vcpu *vcpu);
|
||||
|
||||
void decache_vcpus_on_cpu(int cpu);
|
||||
|
||||
|
||||
int kvm_init(void *opaque, unsigned int vcpu_size,
|
||||
struct module *module);
|
||||
void kvm_exit(void);
|
||||
|
|
@ -166,6 +168,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
|
|||
struct kvm_userspace_memory_region *mem,
|
||||
struct kvm_memory_slot old,
|
||||
int user_alloc);
|
||||
void kvm_arch_flush_shadow(struct kvm *kvm);
|
||||
gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn);
|
||||
struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn);
|
||||
unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn);
|
||||
|
|
|
|||
Loading…
Reference in a new issue