Skip to content

Commit

Permalink
Merge branch 'x86-xen-for-linus' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/tip/linux-2.6-tip

* 'x86-xen-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (42 commits)
  xen: cache cr0 value to avoid trap'n'emulate for read_cr0
  xen/x86-64: clean up warnings about IST-using traps
  xen/x86-64: fix breakpoints and hardware watchpoints
  xen: reserve Xen start_info rather than e820 reserving
  xen: add FIX_TEXT_POKE to fixmap
  lguest: update lazy mmu changes to match lguest's use of kvm hypercalls
  xen: honour VCPU availability on boot
  xen: add "capabilities" file
  xen: drop kexec bits from /sys/hypervisor since kexec isn't implemented yet
  xen/sys/hypervisor: change writable_pt to features
  xen: add /sys/hypervisor support
  xen/xenbus: export xenbus_dev_changed
  xen: use device model for suspending xenbus devices
  xen: remove suspend_cancel hook
  xen/dev-evtchn: clean up locking in evtchn
  xen: export ioctl headers to userspace
  xen: add /dev/xen/evtchn driver
  xen: add irq_from_evtchn
  xen: clean up gate trap/interrupt constants
  xen: set _PAGE_NX in __supported_pte_mask before pagetable construction
  ...
  • Loading branch information
Linus Torvalds committed Jun 10, 2009
2 parents 595dc54 + a789ed5 commit be15f9d
Show file tree
Hide file tree
Showing 37 changed files with 1,281 additions and 174 deletions.
22 changes: 11 additions & 11 deletions arch/x86/include/asm/paravirt.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ struct desc_ptr;
struct tss_struct;
struct mm_struct;
struct desc_struct;
struct task_struct;

/*
* Wrapper type for pointers to code which uses the non-standard
Expand Down Expand Up @@ -203,7 +204,8 @@ struct pv_cpu_ops {

void (*swapgs)(void);

struct pv_lazy_ops lazy_mode;
void (*start_context_switch)(struct task_struct *prev);
void (*end_context_switch)(struct task_struct *next);
};

struct pv_irq_ops {
Expand Down Expand Up @@ -1399,25 +1401,23 @@ enum paravirt_lazy_mode {
};

enum paravirt_lazy_mode paravirt_get_lazy_mode(void);
void paravirt_enter_lazy_cpu(void);
void paravirt_leave_lazy_cpu(void);
void paravirt_start_context_switch(struct task_struct *prev);
void paravirt_end_context_switch(struct task_struct *next);

void paravirt_enter_lazy_mmu(void);
void paravirt_leave_lazy_mmu(void);
void paravirt_leave_lazy(enum paravirt_lazy_mode mode);

#define __HAVE_ARCH_ENTER_LAZY_CPU_MODE
static inline void arch_enter_lazy_cpu_mode(void)
#define __HAVE_ARCH_START_CONTEXT_SWITCH
static inline void arch_start_context_switch(struct task_struct *prev)
{
PVOP_VCALL0(pv_cpu_ops.lazy_mode.enter);
PVOP_VCALL1(pv_cpu_ops.start_context_switch, prev);
}

static inline void arch_leave_lazy_cpu_mode(void)
static inline void arch_end_context_switch(struct task_struct *next)
{
PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave);
PVOP_VCALL1(pv_cpu_ops.end_context_switch, next);
}

void arch_flush_lazy_cpu_mode(void);

#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
static inline void arch_enter_lazy_mmu_mode(void)
{
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
#define pte_val(x) native_pte_val(x)
#define __pte(x) native_make_pte(x)

#define arch_end_context_switch(prev) do {} while(0)

#endif /* CONFIG_PARAVIRT */

/*
Expand Down
8 changes: 7 additions & 1 deletion arch/x86/include/asm/required-features.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,15 @@
#endif

#ifdef CONFIG_X86_64
#ifdef CONFIG_PARAVIRT
/* Paravirtualized systems may not have PSE or PGE available */
#define NEED_PSE 0
#define NEED_MSR (1<<(X86_FEATURE_MSR & 31))
#define NEED_PGE 0
#else
#define NEED_PSE (1<<(X86_FEATURE_PSE) & 31)
#define NEED_PGE (1<<(X86_FEATURE_PGE) & 31)
#endif
#define NEED_MSR (1<<(X86_FEATURE_MSR & 31))
#define NEED_FXSR (1<<(X86_FEATURE_FXSR & 31))
#define NEED_XMM (1<<(X86_FEATURE_XMM & 31))
#define NEED_XMM2 (1<<(X86_FEATURE_XMM2 & 31))
Expand Down
4 changes: 3 additions & 1 deletion arch/x86/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ struct thread_info {
#define TIF_FORCED_TF 24 /* true if TF in eflags artificially */
#define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */
#define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */
#define TIF_SYSCALL_FTRACE 27 /* for ftrace syscall instrumentation */
#define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */
#define TIF_SYSCALL_FTRACE 28 /* for ftrace syscall instrumentation */

#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
Expand All @@ -116,6 +117,7 @@ struct thread_info {
#define _TIF_FORCED_TF (1 << TIF_FORCED_TF)
#define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR)
#define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR)
#define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES)
#define _TIF_SYSCALL_FTRACE (1 << TIF_SYSCALL_FTRACE)

/* work to do in syscall_trace_enter() */
Expand Down
3 changes: 3 additions & 0 deletions arch/x86/include/asm/traps.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ asmlinkage void divide_error(void);
asmlinkage void debug(void);
asmlinkage void nmi(void);
asmlinkage void int3(void);
asmlinkage void xen_debug(void);
asmlinkage void xen_int3(void);
asmlinkage void xen_stack_segment(void);
asmlinkage void overflow(void);
asmlinkage void bounds(void);
asmlinkage void invalid_op(void);
Expand Down
5 changes: 5 additions & 0 deletions arch/x86/kernel/entry_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,11 @@ END(xen_failsafe_callback)
paranoidzeroentry_ist debug do_debug DEBUG_STACK
paranoidzeroentry_ist int3 do_int3 DEBUG_STACK
paranoiderrorentry stack_segment do_stack_segment
#ifdef CONFIG_XEN
zeroentry xen_debug do_debug
zeroentry xen_int3 do_int3
errorentry xen_stack_segment do_stack_segment
#endif
errorentry general_protection do_general_protection
errorentry page_fault do_page_fault
#ifdef CONFIG_X86_MCE
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ static void kvm_leave_lazy_mmu(void)
struct kvm_para_state *state = kvm_para_state();

mmu_queue_flush(state);
paravirt_leave_lazy(paravirt_get_lazy_mode());
paravirt_leave_lazy_mmu();
state->mode = paravirt_get_lazy_mode();
}

Expand Down
56 changes: 26 additions & 30 deletions arch/x86/kernel/paravirt.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,18 +248,16 @@ static DEFINE_PER_CPU(enum paravirt_lazy_mode, paravirt_lazy_mode) = PARAVIRT_LA

static inline void enter_lazy(enum paravirt_lazy_mode mode)
{
BUG_ON(__get_cpu_var(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);
BUG_ON(preemptible());
BUG_ON(percpu_read(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);

__get_cpu_var(paravirt_lazy_mode) = mode;
percpu_write(paravirt_lazy_mode, mode);
}

void paravirt_leave_lazy(enum paravirt_lazy_mode mode)
static void leave_lazy(enum paravirt_lazy_mode mode)
{
BUG_ON(__get_cpu_var(paravirt_lazy_mode) != mode);
BUG_ON(preemptible());
BUG_ON(percpu_read(paravirt_lazy_mode) != mode);

__get_cpu_var(paravirt_lazy_mode) = PARAVIRT_LAZY_NONE;
percpu_write(paravirt_lazy_mode, PARAVIRT_LAZY_NONE);
}

void paravirt_enter_lazy_mmu(void)
Expand All @@ -269,50 +267,50 @@ void paravirt_enter_lazy_mmu(void)

void paravirt_leave_lazy_mmu(void)
{
paravirt_leave_lazy(PARAVIRT_LAZY_MMU);
leave_lazy(PARAVIRT_LAZY_MMU);
}

void paravirt_enter_lazy_cpu(void)
void paravirt_start_context_switch(struct task_struct *prev)
{
BUG_ON(preemptible());

if (percpu_read(paravirt_lazy_mode) == PARAVIRT_LAZY_MMU) {
arch_leave_lazy_mmu_mode();
set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES);
}
enter_lazy(PARAVIRT_LAZY_CPU);
}

void paravirt_leave_lazy_cpu(void)
void paravirt_end_context_switch(struct task_struct *next)
{
paravirt_leave_lazy(PARAVIRT_LAZY_CPU);
BUG_ON(preemptible());

leave_lazy(PARAVIRT_LAZY_CPU);

if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES))
arch_enter_lazy_mmu_mode();
}

enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
{
return __get_cpu_var(paravirt_lazy_mode);
if (in_interrupt())
return PARAVIRT_LAZY_NONE;

return percpu_read(paravirt_lazy_mode);
}

void arch_flush_lazy_mmu_mode(void)
{
preempt_disable();

if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
WARN_ON(preempt_count() == 1);
arch_leave_lazy_mmu_mode();
arch_enter_lazy_mmu_mode();
}

preempt_enable();
}

void arch_flush_lazy_cpu_mode(void)
{
preempt_disable();

if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) {
WARN_ON(preempt_count() == 1);
arch_leave_lazy_cpu_mode();
arch_enter_lazy_cpu_mode();
}

preempt_enable();
}

struct pv_info pv_info = {
.name = "bare hardware",
.paravirt_enabled = 0,
Expand Down Expand Up @@ -404,10 +402,8 @@ struct pv_cpu_ops pv_cpu_ops = {
.set_iopl_mask = native_set_iopl_mask,
.io_delay = native_io_delay,

.lazy_mode = {
.enter = paravirt_nop,
.leave = paravirt_nop,
},
.start_context_switch = paravirt_nop,
.end_context_switch = paravirt_nop,
};

struct pv_apic_ops pv_apic_ops = {
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/process_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
* done before math_state_restore, so the TS bit is up
* to date.
*/
arch_leave_lazy_cpu_mode();
arch_end_context_switch(next_p);

/* If the task has used fpu the last 5 timeslices, just do a full
* restore of the math state immediately to avoid the trap; the
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/process_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
* done before math_state_restore, so the TS bit is up
* to date.
*/
arch_leave_lazy_cpu_mode();
arch_end_context_switch(next_p);

/*
* Switch FS and GS.
Expand Down
20 changes: 13 additions & 7 deletions arch/x86/kernel/vmi_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,22 +462,28 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip,
}
#endif

static void vmi_enter_lazy_cpu(void)
static void vmi_start_context_switch(struct task_struct *prev)
{
paravirt_enter_lazy_cpu();
paravirt_start_context_switch(prev);
vmi_ops.set_lazy_mode(2);
}

static void vmi_end_context_switch(struct task_struct *next)
{
vmi_ops.set_lazy_mode(0);
paravirt_end_context_switch(next);
}

static void vmi_enter_lazy_mmu(void)
{
paravirt_enter_lazy_mmu();
vmi_ops.set_lazy_mode(1);
}

static void vmi_leave_lazy(void)
static void vmi_leave_lazy_mmu(void)
{
paravirt_leave_lazy(paravirt_get_lazy_mode());
vmi_ops.set_lazy_mode(0);
paravirt_leave_lazy_mmu();
}

static inline int __init check_vmi_rom(struct vrom_header *rom)
Expand Down Expand Up @@ -711,14 +717,14 @@ static inline int __init activate_vmi(void)
para_fill(pv_cpu_ops.set_iopl_mask, SetIOPLMask);
para_fill(pv_cpu_ops.io_delay, IODelay);

para_wrap(pv_cpu_ops.lazy_mode.enter, vmi_enter_lazy_cpu,
para_wrap(pv_cpu_ops.start_context_switch, vmi_start_context_switch,
set_lazy_mode, SetLazyMode);
para_wrap(pv_cpu_ops.lazy_mode.leave, vmi_leave_lazy,
para_wrap(pv_cpu_ops.end_context_switch, vmi_end_context_switch,
set_lazy_mode, SetLazyMode);

para_wrap(pv_mmu_ops.lazy_mode.enter, vmi_enter_lazy_mmu,
set_lazy_mode, SetLazyMode);
para_wrap(pv_mmu_ops.lazy_mode.leave, vmi_leave_lazy,
para_wrap(pv_mmu_ops.lazy_mode.leave, vmi_leave_lazy_mmu,
set_lazy_mode, SetLazyMode);

/* user and kernel flush are just handled with different flags to FlushTLB */
Expand Down
16 changes: 11 additions & 5 deletions arch/x86/lguest/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,16 @@ static void lazy_hcall3(unsigned long call,

/* When lazy mode is turned off reset the per-cpu lazy mode variable and then
* issue the do-nothing hypercall to flush any stored calls. */
static void lguest_leave_lazy_mode(void)
static void lguest_leave_lazy_mmu_mode(void)
{
paravirt_leave_lazy(paravirt_get_lazy_mode());
kvm_hypercall0(LHCALL_FLUSH_ASYNC);
paravirt_leave_lazy_mmu();
}

static void lguest_end_context_switch(struct task_struct *next)
{
kvm_hypercall0(LHCALL_FLUSH_ASYNC);
paravirt_end_context_switch(next);
}

/*G:033
Expand Down Expand Up @@ -1054,8 +1060,8 @@ __init void lguest_init(void)
pv_cpu_ops.write_gdt_entry = lguest_write_gdt_entry;
pv_cpu_ops.write_idt_entry = lguest_write_idt_entry;
pv_cpu_ops.wbinvd = lguest_wbinvd;
pv_cpu_ops.lazy_mode.enter = paravirt_enter_lazy_cpu;
pv_cpu_ops.lazy_mode.leave = lguest_leave_lazy_mode;
pv_cpu_ops.start_context_switch = paravirt_start_context_switch;
pv_cpu_ops.end_context_switch = lguest_end_context_switch;

/* pagetable management */
pv_mmu_ops.write_cr3 = lguest_write_cr3;
Expand All @@ -1068,7 +1074,7 @@ __init void lguest_init(void)
pv_mmu_ops.read_cr2 = lguest_read_cr2;
pv_mmu_ops.read_cr3 = lguest_read_cr3;
pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu;
pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mode;
pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode;
pv_mmu_ops.pte_update = lguest_pte_update;
pv_mmu_ops.pte_update_defer = lguest_pte_update;

Expand Down
6 changes: 2 additions & 4 deletions arch/x86/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,10 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
if (!pmd_present(*pmd_k))
return NULL;

if (!pmd_present(*pmd)) {
if (!pmd_present(*pmd))
set_pmd(pmd, *pmd_k);
arch_flush_lazy_mmu_mode();
} else {
else
BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
}

return pmd_k;
}
Expand Down
2 changes: 0 additions & 2 deletions arch/x86/mm/highmem_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
BUG_ON(!pte_none(*(kmap_pte-idx)));
set_pte(kmap_pte-idx, mk_pte(page, prot));
arch_flush_lazy_mmu_mode();

return (void *)vaddr;
}
Expand Down Expand Up @@ -74,7 +73,6 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
#endif
}

arch_flush_lazy_mmu_mode();
pagefault_enable();
}

Expand Down
1 change: 0 additions & 1 deletion arch/x86/mm/iomap_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ iounmap_atomic(void *kvaddr, enum km_type type)
if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
kpte_clear_flush(kmap_pte-idx, vaddr);

arch_flush_lazy_mmu_mode();
pagefault_enable();
}
EXPORT_SYMBOL_GPL(iounmap_atomic);
Loading

0 comments on commit be15f9d

Please sign in to comment.