/* * Apply patch if appropriate, return length of new instruction * sequence. The callee does nop padding for us. */ static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned long ip, unsigned len) { switch (type) { case PARAVIRT_PATCH(pv_irq_ops.irq_disable): return patch_internal(VMI_CALL_DisableInterrupts, len, insns, ip); case PARAVIRT_PATCH(pv_irq_ops.irq_enable): return patch_internal(VMI_CALL_EnableInterrupts, len, insns, ip); case PARAVIRT_PATCH(pv_irq_ops.restore_fl): return patch_internal(VMI_CALL_SetInterruptMask, len, insns, ip); case PARAVIRT_PATCH(pv_irq_ops.save_fl): return patch_internal(VMI_CALL_GetInterruptMask, len, insns, ip); case PARAVIRT_PATCH(pv_cpu_ops.iret): return patch_internal(VMI_CALL_IRET, len, insns, ip); case PARAVIRT_PATCH(pv_cpu_ops.nmi_return): return patch_internal(VMI_CALL_IRET, len, insns, ip); case PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit): return patch_internal(VMI_CALL_SYSEXIT, len, insns, ip); default: break; } return len; }
/* * Apply patch if appropriate, return length of new instruction * sequence. The callee does nop padding for us. */ static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len) { switch (type) { case PARAVIRT_IRQ_DISABLE: return patch_internal(VMI_CALL_DisableInterrupts, len, insns); case PARAVIRT_IRQ_ENABLE: return patch_internal(VMI_CALL_EnableInterrupts, len, insns); case PARAVIRT_RESTORE_FLAGS: return patch_internal(VMI_CALL_SetInterruptMask, len, insns); case PARAVIRT_SAVE_FLAGS: return patch_internal(VMI_CALL_GetInterruptMask, len, insns); case PARAVIRT_SAVE_FLAGS_IRQ_DISABLE: if (len >= 10) { patch_internal(VMI_CALL_GetInterruptMask, len, insns); patch_internal(VMI_CALL_DisableInterrupts, len-5, insns+5); return 10; } else { /* * You bastards didn't leave enough room to * patch save_flags_irq_disable inline. Patch * to a helper */ BUG_ON(len < 5); *(char *)insns = MNEM_CALL; patch_offset(insns, irq_save_disable_callout); return 5; } case PARAVIRT_INTERRUPT_RETURN: return patch_internal(VMI_CALL_IRET, len, insns); case PARAVIRT_STI_SYSEXIT: return patch_internal(VMI_CALL_SYSEXIT, len, insns); default: break; } return len; }