Skip to content

Commit

Permalink
x86: replace irq_{enable|disable}() with sti()/cli()
Browse files Browse the repository at this point in the history
This removes a layer of indirection which is strictly
speaking not needed since its x86 code anyway.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Link: https://lore.kernel.org/r/20221122161152.293072-2-mlevitsk@redhat.com
[sean: move and reword IRQ shadow to be above and about safe_halt()]
Signed-off-by: Sean Christopherson <seanjc@google.com>
  • Loading branch information
Maxim Levitsky authored and sean-jc committed Jun 7, 2023
1 parent dbbfaf8 commit ed31b56
Show file tree
Hide file tree
Showing 17 changed files with 102 additions and 105 deletions.
23 changes: 10 additions & 13 deletions lib/x86/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,9 @@ static inline void cli(void)
asm volatile ("cli");
}

/*
* See also safe_halt().
*/
static inline void sti(void)
{
asm volatile ("sti");
Expand Down Expand Up @@ -735,19 +738,6 @@ static inline void wrtsc(u64 tsc)
wrmsr(MSR_IA32_TSC, tsc);
}

static inline void irq_disable(void)
{
asm volatile("cli");
}

/* Note that irq_enable() does not ensure an interrupt shadow due
* to the vagaries of compiler optimizations. If you need the
* shadow, use a single asm with "sti" and the instruction after it.
*/
static inline void irq_enable(void)
{
asm volatile("sti");
}

static inline void invlpg(volatile void *va)
{
Expand All @@ -761,6 +751,13 @@ static inline int invpcid_safe(unsigned long type, void *desc)
return asm_safe(".byte 0x66,0x0f,0x38,0x82,0x18", "a" (desc), "b" (type));
}

/*
* Execute HLT in an STI interrupt shadow to ensure that a pending IRQ that's
* intended to be a wake event arrives *after* HLT is executed. Modern CPUs,
* except for a few oddballs that KVM is unlikely to run on, block IRQs for one
* instruction after STI, *if* RFLAGS.IF=0 before STI. Note, Intel CPUs may
* block other events beyond regular IRQs, e.g. may block NMIs and SMIs too.
*/
static inline void safe_halt(void)
{
asm volatile("sti; hlt");
Expand Down
2 changes: 1 addition & 1 deletion lib/x86/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static void setup_smp_id(void *data)

void ap_online(void)
{
irq_enable();
sti();

printf("setup: CPU %" PRId32 " online\n", apic_id());
atomic_inc(&cpu_online_count);
Expand Down
2 changes: 1 addition & 1 deletion x86/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -958,7 +958,7 @@ int main(void)
setup_vm();

mask_pic_interrupts();
irq_enable();
sti();

for (i = 0; i < ARRAY_SIZE(tests); i++) {
tests[i]();
Expand Down
6 changes: 3 additions & 3 deletions x86/asyncpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static void pf_isr(struct ex_regs *r)
read_cr2(), virt, phys);
while(phys) {
safe_halt(); /* enables irq */
irq_disable();
cli();
}
break;
case KVM_PV_REASON_PAGE_READY:
Expand Down Expand Up @@ -97,15 +97,15 @@ int main(int ac, char **av)
KVM_ASYNC_PF_SEND_ALWAYS | KVM_ASYNC_PF_ENABLED);
printf("alloc memory\n");
buf = malloc(MEM);
irq_enable();
sti();
while(loop--) {
printf("start loop\n");
/* access a lot of memory to make host swap it out */
for (i=0; i < MEM; i+=4096)
buf[i] = 1;
printf("end loop\n");
}
irq_disable();
cli();

return report_summary();
}
22 changes: 11 additions & 11 deletions x86/eventinj.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,10 @@ int main(void)
test_count = 0;
flush_idt_page();
printf("Sending vec 33 to self\n");
irq_enable();
sti();
apic_self_ipi(33);
io_delay();
irq_disable();
cli();
printf("After vec 33 to self\n");
report(test_count == 1, "vec 33");

Expand All @@ -294,9 +294,9 @@ int main(void)
apic_self_ipi(32);
apic_self_ipi(33);
io_delay();
irq_enable();
sti();
asm volatile("nop");
irq_disable();
cli();
printf("After vec 32 and 33 to self\n");
report(test_count == 2, "vec 32/33");

Expand All @@ -311,7 +311,7 @@ int main(void)
flush_stack();
io_delay();
asm volatile ("sti; int $33");
irq_disable();
cli();
printf("After vec 32 and int $33\n");
report(test_count == 2, "vec 32/int $33");

Expand All @@ -321,7 +321,7 @@ int main(void)
flush_idt_page();
printf("Sending vec 33 and 62 and mask one with TPR\n");
apic_write(APIC_TASKPRI, 0xf << 4);
irq_enable();
sti();
apic_self_ipi(32);
apic_self_ipi(62);
io_delay();
Expand All @@ -330,7 +330,7 @@ int main(void)
report(test_count == 1, "TPR");
apic_write(APIC_TASKPRI, 0x0);
while(test_count != 2); /* wait for second irq */
irq_disable();
cli();

/* test fault durint NP delivery */
printf("Before NP test\n");
Expand All @@ -353,9 +353,9 @@ int main(void)
/* this is needed on VMX without NMI window notification.
Interrupt windows is used instead, so let pending NMI
to be injected */
irq_enable();
sti();
asm volatile ("nop");
irq_disable();
cli();
report(test_count == 2, "NMI");

/* generate NMI that will fault on IRET */
Expand All @@ -367,9 +367,9 @@ int main(void)
/* this is needed on VMX without NMI window notification.
Interrupt windows is used instead, so let pending NMI
to be injected */
irq_enable();
sti();
asm volatile ("nop");
irq_disable();
cli();
printf("After NMI to self\n");
report(test_count == 2, "NMI");
stack_phys = (ulong)virt_to_phys(alloc_page());
Expand Down
2 changes: 1 addition & 1 deletion x86/hyperv_connections.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ static void setup_cpu(void *ctx)
struct hv_vcpu *hv;

write_cr3((ulong)ctx);
irq_enable();
sti();

vcpu = smp_id();
hv = &hv_vcpus[vcpu];
Expand Down
4 changes: 2 additions & 2 deletions x86/hyperv_stimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ static void stimer_test(void *ctx)
struct svcpu *svcpu = &g_synic_vcpu[vcpu];
struct stimer *timer1, *timer2;

irq_enable();
sti();

timer1 = &svcpu->timer[0];
timer2 = &svcpu->timer[1];
Expand All @@ -318,7 +318,7 @@ static void stimer_test(void *ctx)
stimer_test_auto_enable_periodic(vcpu, timer1);
stimer_test_one_shot_busy(vcpu, timer1);

irq_disable();
cli();
}

static void stimer_test_cleanup(void *ctx)
Expand Down
6 changes: 3 additions & 3 deletions x86/hyperv_synic.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static void synic_test_prepare(void *ctx)
int i = 0;

write_cr3((ulong)ctx);
irq_enable();
sti();

rdmsr(HV_X64_MSR_SVERSION);
rdmsr(HV_X64_MSR_SIMP);
Expand Down Expand Up @@ -121,15 +121,15 @@ static void synic_test(void *ctx)
{
int dst_vcpu = (ulong)ctx;

irq_enable();
sti();
synic_sints_test(dst_vcpu);
}

static void synic_test_cleanup(void *ctx)
{
int i;

irq_enable();
sti();
for (i = 0; i < HV_SYNIC_SINT_COUNT; i++) {
synic_sint_destroy(i);
}
Expand Down
2 changes: 1 addition & 1 deletion x86/intel-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ static void vtd_test_ir(void)

report_prefix_push("vtd_ir");

irq_enable();
sti();

/* This will enable INTx */
pci_msi_set_enable(pci_dev, false);
Expand Down
14 changes: 7 additions & 7 deletions x86/ioapic.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ static void test_ioapic_simultaneous(void)
handle_irq(0x66, ioapic_isr_66);
ioapic_set_redir(0x0e, 0x78, TRIGGER_EDGE);
ioapic_set_redir(0x0f, 0x66, TRIGGER_EDGE);
irq_disable();
cli();
toggle_irq_line(0x0f);
toggle_irq_line(0x0e);
irq_enable();
sti();
asm volatile ("nop");
report(g_66 && g_78 && g_66_after_78 && g_66_rip == g_78_rip,
"ioapic simultaneous edge interrupts");
Expand Down Expand Up @@ -173,10 +173,10 @@ static void test_ioapic_level_tmr(bool expected_tmr_before)

static void toggle_irq_line_0x0e(void *data)
{
irq_disable();
cli();
delay(IPI_DELAY);
toggle_irq_line(0x0e);
irq_enable();
sti();
}

static void test_ioapic_edge_tmr_smp(bool expected_tmr_before)
Expand All @@ -199,10 +199,10 @@ static void test_ioapic_edge_tmr_smp(bool expected_tmr_before)

static void set_irq_line_0x0e(void *data)
{
irq_disable();
cli();
delay(IPI_DELAY);
set_irq_line(0x0e, 1);
irq_enable();
sti();
}

static void test_ioapic_level_tmr_smp(bool expected_tmr_before)
Expand Down Expand Up @@ -485,7 +485,7 @@ int main(void)
else
printf("x2apic not detected\n");

irq_enable();
sti();

ioapic_reg_version();
ioapic_reg_id();
Expand Down
4 changes: 2 additions & 2 deletions x86/pmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ static bool check_irq(void)
{
int i;
irq_received = 0;
irq_enable();
sti();
for (i = 0; i < 100000 && !irq_received; i++)
asm volatile("pause");
irq_disable();
cli();
return irq_received;
}

Expand Down
4 changes: 2 additions & 2 deletions x86/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ static noinline void test_run(struct svm_test *test)
{
u64 vmcb_phys = virt_to_phys(vmcb);

irq_disable();
cli();
vmcb_ident(vmcb);

test->prepare(test);
Expand Down Expand Up @@ -283,7 +283,7 @@ static noinline void test_run(struct svm_test *test)
"memory");
++test->exits;
} while (!test->finished(test));
irq_enable();
sti();

report(test->succeeded(test), "%s", test->name);

Expand Down

0 comments on commit ed31b56

Please sign in to comment.