Skip to content

Commit

Permalink
x86/xen: move paravirt lazy code
Browse files Browse the repository at this point in the history
Only Xen is using the paravirt lazy mode code, so it can be moved to
Xen specific sources.

This allows to make some of the functions static or to merge them into
their only call sites.

While at it do a rename from "paravirt" to "xen" for all moved
specifiers.

No functional change.

Signed-off-by: Juergen Gross <[email protected]>
Reviewed-by: Boris Ostrovsky <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Juergen Gross <[email protected]>
  • Loading branch information
jgross1 committed Sep 19, 2023
1 parent 361239f commit a4a7644
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 116 deletions.
15 changes: 0 additions & 15 deletions arch/x86/include/asm/paravirt_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@ struct paravirt_patch_site {
u8 type; /* type of this instruction */
u8 len; /* length of original instruction */
};

/* Lazy mode for batching updates / context switch */
enum paravirt_lazy_mode {
PARAVIRT_LAZY_NONE,
PARAVIRT_LAZY_MMU,
PARAVIRT_LAZY_CPU,
};
#endif

#ifdef CONFIG_PARAVIRT
Expand Down Expand Up @@ -549,14 +542,6 @@ int paravirt_disable_iospace(void);
__PVOP_VCALL(op, PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \
PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))

enum paravirt_lazy_mode paravirt_get_lazy_mode(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_flush_lazy_mmu(void);

void _paravirt_nop(void);
void paravirt_BUG(void);
unsigned long paravirt_ret0(void);
Expand Down
26 changes: 26 additions & 0 deletions arch/x86/include/asm/xen/hypervisor.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
extern struct shared_info *HYPERVISOR_shared_info;
extern struct start_info *xen_start_info;

#include <asm/bug.h>
#include <asm/processor.h>

#define XEN_SIGNATURE "XenVMMXenVMM"
Expand Down Expand Up @@ -63,4 +64,29 @@ void __init xen_pvh_init(struct boot_params *boot_params);
void __init mem_map_via_hcall(struct boot_params *boot_params_p);
#endif

/* Lazy mode for batching updates / context switch */
enum xen_lazy_mode {
XEN_LAZY_NONE,
XEN_LAZY_MMU,
XEN_LAZY_CPU,
};

DECLARE_PER_CPU(enum xen_lazy_mode, xen_lazy_mode);

static inline void enter_lazy(enum xen_lazy_mode mode)
{
BUG_ON(this_cpu_read(xen_lazy_mode) != XEN_LAZY_NONE);

this_cpu_write(xen_lazy_mode, mode);
}

static inline void leave_lazy(enum xen_lazy_mode mode)
{
BUG_ON(this_cpu_read(xen_lazy_mode) != mode);

this_cpu_write(xen_lazy_mode, XEN_LAZY_NONE);
}

enum xen_lazy_mode xen_get_lazy_mode(void);

#endif /* _ASM_X86_XEN_HYPERVISOR_H */
67 changes: 0 additions & 67 deletions arch/x86/kernel/paravirt.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,66 +143,7 @@ int paravirt_disable_iospace(void)
return request_resource(&ioport_resource, &reserve_ioports);
}

static DEFINE_PER_CPU(enum paravirt_lazy_mode, paravirt_lazy_mode) = PARAVIRT_LAZY_NONE;

static inline void enter_lazy(enum paravirt_lazy_mode mode)
{
BUG_ON(this_cpu_read(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);

this_cpu_write(paravirt_lazy_mode, mode);
}

static void leave_lazy(enum paravirt_lazy_mode mode)
{
BUG_ON(this_cpu_read(paravirt_lazy_mode) != mode);

this_cpu_write(paravirt_lazy_mode, PARAVIRT_LAZY_NONE);
}

void paravirt_enter_lazy_mmu(void)
{
enter_lazy(PARAVIRT_LAZY_MMU);
}

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

void paravirt_flush_lazy_mmu(void)
{
preempt_disable();

if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
arch_leave_lazy_mmu_mode();
arch_enter_lazy_mmu_mode();
}

preempt_enable();
}

#ifdef CONFIG_PARAVIRT_XXL
void paravirt_start_context_switch(struct task_struct *prev)
{
BUG_ON(preemptible());

if (this_cpu_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_end_context_switch(struct task_struct *next)
{
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();
}

static noinstr void pv_native_write_cr2(unsigned long val)
{
native_write_cr2(val);
Expand All @@ -229,14 +170,6 @@ static noinstr void pv_native_safe_halt(void)
}
#endif

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

return this_cpu_read(paravirt_lazy_mode);
}

struct pv_info pv_info = {
.name = "bare hardware",
#ifdef CONFIG_PARAVIRT_XXL
Expand Down
39 changes: 32 additions & 7 deletions arch/x86/xen/enlighten_pv.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ struct tls_descs {
struct desc_struct desc[3];
};

DEFINE_PER_CPU(enum xen_lazy_mode, xen_lazy_mode) = XEN_LAZY_NONE;

enum xen_lazy_mode xen_get_lazy_mode(void)
{
if (in_interrupt())
return XEN_LAZY_NONE;

return this_cpu_read(xen_lazy_mode);
}

/*
* Updating the 3 TLS descriptors in the GDT on every task switch is
* surprisingly expensive so we avoid updating them if they haven't
Expand Down Expand Up @@ -362,10 +372,25 @@ static noinstr unsigned long xen_get_debugreg(int reg)
return HYPERVISOR_get_debugreg(reg);
}

static void xen_start_context_switch(struct task_struct *prev)
{
BUG_ON(preemptible());

if (this_cpu_read(xen_lazy_mode) == XEN_LAZY_MMU) {
arch_leave_lazy_mmu_mode();
set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES);
}
enter_lazy(XEN_LAZY_CPU);
}

static void xen_end_context_switch(struct task_struct *next)
{
BUG_ON(preemptible());

xen_mc_flush();
paravirt_end_context_switch(next);
leave_lazy(XEN_LAZY_CPU);
if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES))
arch_enter_lazy_mmu_mode();
}

static unsigned long xen_store_tr(void)
Expand Down Expand Up @@ -472,7 +497,7 @@ static void xen_set_ldt(const void *addr, unsigned entries)

MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);

xen_mc_issue(PARAVIRT_LAZY_CPU);
xen_mc_issue(XEN_LAZY_CPU);
}

static void xen_load_gdt(const struct desc_ptr *dtr)
Expand Down Expand Up @@ -568,7 +593,7 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
* exception between the new %fs descriptor being loaded and
* %fs being effectively cleared at __switch_to().
*/
if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)
if (xen_get_lazy_mode() == XEN_LAZY_CPU)
loadsegment(fs, 0);

xen_mc_batch();
Expand All @@ -577,7 +602,7 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
load_TLS_descriptor(t, cpu, 1);
load_TLS_descriptor(t, cpu, 2);

xen_mc_issue(PARAVIRT_LAZY_CPU);
xen_mc_issue(XEN_LAZY_CPU);
}

static void xen_load_gs_index(unsigned int idx)
Expand Down Expand Up @@ -909,7 +934,7 @@ static void xen_load_sp0(unsigned long sp0)

mcs = xen_mc_entry(0);
MULTI_stack_switch(mcs.mc, __KERNEL_DS, sp0);
xen_mc_issue(PARAVIRT_LAZY_CPU);
xen_mc_issue(XEN_LAZY_CPU);
this_cpu_write(cpu_tss_rw.x86_tss.sp0, sp0);
}

Expand Down Expand Up @@ -973,7 +998,7 @@ static void xen_write_cr0(unsigned long cr0)

MULTI_fpu_taskswitch(mcs.mc, (cr0 & X86_CR0_TS) != 0);

xen_mc_issue(PARAVIRT_LAZY_CPU);
xen_mc_issue(XEN_LAZY_CPU);
}

static void xen_write_cr4(unsigned long cr4)
Expand Down Expand Up @@ -1156,7 +1181,7 @@ static const typeof(pv_ops) xen_cpu_ops __initconst = {
#endif
.io_delay = xen_io_delay,

.start_context_switch = paravirt_start_context_switch,
.start_context_switch = xen_start_context_switch,
.end_context_switch = xen_end_context_switch,
},
};
Expand Down
Loading

0 comments on commit a4a7644

Please sign in to comment.