Skip to content

Commit e453f87

Browse files
jgross1bostrovs
authored andcommitted
x86/xen: switch initial pvops IRQ functions to dummy ones
The initial pvops functions handling irq flags will only ever be called before interrupts are being enabled. So switch them to be dummy functions: - xen_save_fl() can always return 0 - xen_irq_disable() is a nop - xen_irq_enable() can BUG() Add some generic paravirt functions for that purpose. Signed-off-by: Juergen Gross <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Boris Ostrovsky <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Boris Ostrovsky <[email protected]>
1 parent 12ad6cf commit e453f87

File tree

4 files changed

+20
-76
lines changed

4 files changed

+20
-76
lines changed

arch/x86/include/asm/paravirt_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,9 @@ void paravirt_leave_lazy_mmu(void);
577577
void paravirt_flush_lazy_mmu(void);
578578

579579
void _paravirt_nop(void);
580+
void paravirt_BUG(void);
580581
u64 _paravirt_ident_64(u64);
582+
unsigned long paravirt_ret0(void);
581583

582584
#define paravirt_nop ((void *)_paravirt_nop)
583585

arch/x86/kernel/paravirt.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,25 @@ asm (".pushsection .entry.text, \"ax\"\n"
4646
".type _paravirt_nop, @function\n\t"
4747
".popsection");
4848

49+
/* stub always returning 0. */
50+
asm (".pushsection .entry.text, \"ax\"\n"
51+
".global paravirt_ret0\n"
52+
"paravirt_ret0:\n\t"
53+
"xor %" _ASM_AX ", %" _ASM_AX ";\n\t"
54+
"ret\n\t"
55+
".size paravirt_ret0, . - paravirt_ret0\n\t"
56+
".type paravirt_ret0, @function\n\t"
57+
".popsection");
58+
59+
4960
void __init default_banner(void)
5061
{
5162
printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
5263
pv_info.name);
5364
}
5465

5566
/* Undefined instruction for dealing with missing ops pointers. */
56-
static void paravirt_BUG(void)
67+
noinstr void paravirt_BUG(void)
5768
{
5869
BUG();
5970
}

arch/x86/xen/enlighten.c

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,10 @@ EXPORT_SYMBOL_GPL(hypercall_page);
3131
* Pointer to the xen_vcpu_info structure or
3232
* &HYPERVISOR_shared_info->vcpu_info[cpu]. See xen_hvm_init_shared_info
3333
* and xen_vcpu_setup for details. By default it points to share_info->vcpu_info
34-
* but if the hypervisor supports VCPUOP_register_vcpu_info then it can point
35-
* to xen_vcpu_info. The pointer is used in __xen_evtchn_do_upcall to
36-
* acknowledge pending events.
37-
* Also more subtly it is used by the patched version of irq enable/disable
38-
* e.g. xen_irq_enable_direct and xen_iret in PV mode.
39-
*
40-
* The desire to be able to do those mask/unmask operations as a single
41-
* instruction by using the per-cpu offset held in %gs is the real reason
42-
* vcpu info is in a per-cpu pointer and the original reason for this
43-
* hypercall.
44-
*
34+
* but during boot it is switched to point to xen_vcpu_info.
35+
* The pointer is used in __xen_evtchn_do_upcall to acknowledge pending events.
4536
*/
4637
DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
47-
48-
/*
49-
* Per CPU pages used if hypervisor supports VCPUOP_register_vcpu_info
50-
* hypercall. This can be used both in PV and PVHVM mode. The structure
51-
* overrides the default per_cpu(xen_vcpu, cpu) value.
52-
*/
5338
DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
5439

5540
/* Linux <-> Xen vCPU id mapping */

arch/x86/xen/irq.c

Lines changed: 4 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -24,60 +24,6 @@ noinstr void xen_force_evtchn_callback(void)
2424
(void)HYPERVISOR_xen_version(0, NULL);
2525
}
2626

27-
asmlinkage __visible noinstr unsigned long xen_save_fl(void)
28-
{
29-
struct vcpu_info *vcpu;
30-
unsigned long flags;
31-
32-
vcpu = this_cpu_read(xen_vcpu);
33-
34-
/* flag has opposite sense of mask */
35-
flags = !vcpu->evtchn_upcall_mask;
36-
37-
/* convert to IF type flag
38-
-0 -> 0x00000000
39-
-1 -> 0xffffffff
40-
*/
41-
return (-flags) & X86_EFLAGS_IF;
42-
}
43-
__PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl, ".noinstr.text");
44-
45-
asmlinkage __visible noinstr void xen_irq_disable(void)
46-
{
47-
/* There's a one instruction preempt window here. We need to
48-
make sure we're don't switch CPUs between getting the vcpu
49-
pointer and updating the mask. */
50-
preempt_disable();
51-
this_cpu_read(xen_vcpu)->evtchn_upcall_mask = 1;
52-
preempt_enable_no_resched();
53-
}
54-
__PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable, ".noinstr.text");
55-
56-
asmlinkage __visible noinstr void xen_irq_enable(void)
57-
{
58-
struct vcpu_info *vcpu;
59-
60-
/*
61-
* We may be preempted as soon as vcpu->evtchn_upcall_mask is
62-
* cleared, so disable preemption to ensure we check for
63-
* events on the VCPU we are still running on.
64-
*/
65-
preempt_disable();
66-
67-
vcpu = this_cpu_read(xen_vcpu);
68-
vcpu->evtchn_upcall_mask = 0;
69-
70-
/* Doesn't matter if we get preempted here, because any
71-
pending event will get dealt with anyway. */
72-
73-
barrier(); /* unmask then check (avoid races) */
74-
if (unlikely(vcpu->evtchn_upcall_pending))
75-
xen_force_evtchn_callback();
76-
77-
preempt_enable();
78-
}
79-
__PV_CALLEE_SAVE_REGS_THUNK(xen_irq_enable, ".noinstr.text");
80-
8127
static void xen_safe_halt(void)
8228
{
8329
/* Blocking includes an implicit local_irq_enable(). */
@@ -96,10 +42,10 @@ static void xen_halt(void)
9642

9743
static const typeof(pv_ops) xen_irq_ops __initconst = {
9844
.irq = {
99-
100-
.save_fl = PV_CALLEE_SAVE(xen_save_fl),
101-
.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
102-
.irq_enable = PV_CALLEE_SAVE(xen_irq_enable),
45+
/* Initial interrupt flag handling only called while interrupts off. */
46+
.save_fl = __PV_IS_CALLEE_SAVE(paravirt_ret0),
47+
.irq_disable = __PV_IS_CALLEE_SAVE(paravirt_nop),
48+
.irq_enable = __PV_IS_CALLEE_SAVE(paravirt_BUG),
10349

10450
.safe_halt = xen_safe_halt,
10551
.halt = xen_halt,

0 commit comments

Comments
 (0)