Skip to content
paravirt.h 33.3 KiB
Newer Older
#ifndef __ASM_PARAVIRT_H
#define __ASM_PARAVIRT_H
/* Various instructions on x86 need to be replaced for
 * para-virtualization: those hooks are defined here. */
/* Bitmask of what can be clobbered: usually at least eax. */
#define CLBR_NONE 0x0
#define CLBR_EAX 0x1
#define CLBR_ECX 0x2
#define CLBR_EDX 0x4
#define CLBR_ANY 0x7

struct thread_struct;
struct Xgt_desc_struct;
struct tss_struct;
struct desc_struct;

/* Lazy mode for batching updates / context switch */
enum paravirt_lazy_mode {
	PARAVIRT_LAZY_NONE = 0,
	PARAVIRT_LAZY_MMU = 1,
	PARAVIRT_LAZY_CPU = 2,
struct paravirt_ops
{
	unsigned int kernel_rpl;
 	int paravirt_enabled;
	const char *name;

	/*
	 * Patch may replace one of the defined code sequences with arbitrary
	 * code, subject to the same register constraints.  This generally
	 * means the code is not free to clobber any registers other than EAX.
	 * The patch function should return the number of bytes of code
	 * generated, as we nop pad the rest in generic code.
	 */
	unsigned (*patch)(u8 type, u16 clobber, void *firstinsn, unsigned len);

	/* Basic arch-specific setup */
	void (*arch_setup)(void);
	char *(*memory_setup)(void);
	void (*init_IRQ)(void);
	/*
	 * Called before/after init_mm pagetable setup. setup_start
	 * may reset %cr3, and may pre-install parts of the pagetable;
	 * pagetable setup is expected to preserve any existing
	 * mapping.
	 */
	void (*pagetable_setup_start)(pgd_t *pgd_base);
	void (*pagetable_setup_done)(pgd_t *pgd_base);

	/* Print a banner to identify the environment */
	/* Set and set time of day */
	unsigned long (*get_wallclock)(void);
	int (*set_wallclock)(unsigned long);

	/* cpuid emulation, mostly so that caps bits can be disabled */
	void (*cpuid)(unsigned int *eax, unsigned int *ebx,
		      unsigned int *ecx, unsigned int *edx);

	/* hooks for various privileged instructions */
	unsigned long (*get_debugreg)(int regno);
	void (*set_debugreg)(int regno, unsigned long value);
	void (*clts)(void);
	unsigned long (*read_cr0)(void);
	void (*write_cr0)(unsigned long);
	unsigned long (*read_cr2)(void);
	void (*write_cr2)(unsigned long);
	unsigned long (*read_cr3)(void);
	void (*write_cr3)(unsigned long);
	unsigned long (*read_cr4_safe)(void);
	unsigned long (*read_cr4)(void);
	void (*write_cr4)(unsigned long);
	/*
	 * Get/set interrupt state.  save_fl and restore_fl are only
	 * expected to use X86_EFLAGS_IF; all other bits
	 * returned from save_fl are undefined, and may be ignored by
	 * restore_fl.
	 */
	unsigned long (*save_fl)(void);
	void (*restore_fl)(unsigned long);
	void (*irq_disable)(void);
	void (*irq_enable)(void);
	void (*safe_halt)(void);
	void (*halt)(void);
	void (*wbinvd)(void);
	/* MSR, PMC and TSR operations.
	   err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
	u64 (*read_msr)(unsigned int msr, int *err);
	int (*write_msr)(unsigned int msr, u64 val);

	u64 (*read_tsc)(void);
	u64 (*read_pmc)(void);
 	u64 (*get_scheduled_cycles)(void);
	unsigned long (*get_cpu_khz)(void);
	/* Segment descriptor handling */
	void (*load_tr_desc)(void);
	void (*load_gdt)(const struct Xgt_desc_struct *);
	void (*load_idt)(const struct Xgt_desc_struct *);
	void (*store_gdt)(struct Xgt_desc_struct *);
	void (*store_idt)(struct Xgt_desc_struct *);
	void (*set_ldt)(const void *desc, unsigned entries);
	unsigned long (*store_tr)(void);
	void (*load_tls)(struct thread_struct *t, unsigned int cpu);
	void (*write_ldt_entry)(struct desc_struct *,
				int entrynum, u32 low, u32 high);
	void (*write_gdt_entry)(struct desc_struct *,
				int entrynum, u32 low, u32 high);
	void (*write_idt_entry)(struct desc_struct *,
				int entrynum, u32 low, u32 high);
	void (*load_esp0)(struct tss_struct *tss, struct thread_struct *t);
	void (*set_iopl_mask)(unsigned mask);
	void (*io_delay)(void);
	/*
	 * Hooks for intercepting the creation/use/destruction of an
	 * mm_struct.
	 */
	void (*activate_mm)(struct mm_struct *prev,
			    struct mm_struct *next);
	void (*dup_mmap)(struct mm_struct *oldmm,
			 struct mm_struct *mm);
	void (*exit_mmap)(struct mm_struct *mm);

#ifdef CONFIG_X86_LOCAL_APIC
	/*
	 * Direct APIC operations, principally for VMI.  Ideally
	 * these shouldn't be in this interface.
	 */
	void (*apic_write)(unsigned long reg, unsigned long v);
	void (*apic_write_atomic)(unsigned long reg, unsigned long v);
	unsigned long (*apic_read)(unsigned long reg);
	void (*setup_boot_clock)(void);
	void (*setup_secondary_clock)(void);

	void (*startup_ipi_hook)(int phys_apicid,
				 unsigned long start_eip,
				 unsigned long start_esp);
	void (*flush_tlb_user)(void);
	void (*flush_tlb_kernel)(void);
	void (*flush_tlb_others)(const cpumask_t *cpus, struct mm_struct *mm,
				 unsigned long va);
	/* Hooks for allocating/releasing pagetable pages */
	void (*alloc_pt)(u32 pfn);
	void (*alloc_pd)(u32 pfn);
	void (*alloc_pd_clone)(u32 pfn, u32 clonepfn, u32 start, u32 count);
	void (*release_pt)(u32 pfn);
	void (*release_pd)(u32 pfn);

	/* Pagetable manipulation functions */
	void (*set_pte)(pte_t *ptep, pte_t pteval);
	void (*set_pte_at)(struct mm_struct *mm, unsigned long addr,
			   pte_t *ptep, pte_t pteval);
	void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval);
	void (*pte_update)(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
	void (*pte_update_defer)(struct mm_struct *mm,
				 unsigned long addr, pte_t *ptep);
#ifdef CONFIG_HIGHPTE
	void *(*kmap_atomic_pte)(struct page *page, enum km_type type);
#endif

	void (*set_pte_atomic)(pte_t *ptep, pte_t pteval);
 	void (*set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
	void (*set_pud)(pud_t *pudp, pud_t pudval);
Loading
Loading full blame...