mirror of
				https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
				synced 2025-10-31 07:02:06 +00:00 
			
		
		
		
	 130ace11a9
			
		
	
	
		130ace11a9
		
	
	
	
	
		
			
			Make the following style cleanups: * drop unnecessary //#include from xen-asm_32.S * compulsive adding of space after comma * reformat multiline comments Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
		
			
				
	
	
		
			143 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			143 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * Asm versions of Xen pv-ops, suitable for either direct use or
 | |
|  * inlining.  The inline versions are the same as the direct-use
 | |
|  * versions, with the pre- and post-amble chopped off.
 | |
|  *
 | |
|  * This code is encoded for size rather than absolute efficiency, with
 | |
|  * a view to being able to inline as much as possible.
 | |
|  *
 | |
|  * We only bother with direct forms (ie, vcpu in percpu data) of the
 | |
|  * operations here; the indirect forms are better handled in C, since
 | |
|  * they're generally too large to inline anyway.
 | |
|  */
 | |
| 
 | |
| #include <asm/asm-offsets.h>
 | |
| #include <asm/percpu.h>
 | |
| #include <asm/processor-flags.h>
 | |
| 
 | |
| #include "xen-asm.h"
 | |
| 
 | |
| /*
 | |
|  * Enable events.  This clears the event mask and tests the pending
 | |
|  * event status with one and operation.  If there are pending events,
 | |
|  * then enter the hypervisor to get them handled.
 | |
|  */
 | |
| ENTRY(xen_irq_enable_direct)
 | |
| 	/* Unmask events */
 | |
| 	movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
 | |
| 
 | |
| 	/*
 | |
| 	 * Preempt here doesn't matter because that will deal with any
 | |
| 	 * pending interrupts.  The pending check may end up being run
 | |
| 	 * on the wrong CPU, but that doesn't hurt.
 | |
| 	 */
 | |
| 
 | |
| 	/* Test for pending */
 | |
| 	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
 | |
| 	jz 1f
 | |
| 
 | |
| 2:	call check_events
 | |
| 1:
 | |
| ENDPATCH(xen_irq_enable_direct)
 | |
| 	ret
 | |
| 	ENDPROC(xen_irq_enable_direct)
 | |
| 	RELOC(xen_irq_enable_direct, 2b+1)
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Disabling events is simply a matter of making the event mask
 | |
|  * non-zero.
 | |
|  */
 | |
| ENTRY(xen_irq_disable_direct)
 | |
| 	movb $1, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
 | |
| ENDPATCH(xen_irq_disable_direct)
 | |
| 	ret
 | |
| 	ENDPROC(xen_irq_disable_direct)
 | |
| 	RELOC(xen_irq_disable_direct, 0)
 | |
| 
 | |
| /*
 | |
|  * (xen_)save_fl is used to get the current interrupt enable status.
 | |
|  * Callers expect the status to be in X86_EFLAGS_IF, and other bits
 | |
|  * may be set in the return value.  We take advantage of this by
 | |
|  * making sure that X86_EFLAGS_IF has the right value (and other bits
 | |
|  * in that byte are 0), but other bits in the return value are
 | |
|  * undefined.  We need to toggle the state of the bit, because Xen and
 | |
|  * x86 use opposite senses (mask vs enable).
 | |
|  */
 | |
| ENTRY(xen_save_fl_direct)
 | |
| 	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
 | |
| 	setz %ah
 | |
| 	addb %ah, %ah
 | |
| ENDPATCH(xen_save_fl_direct)
 | |
| 	ret
 | |
| 	ENDPROC(xen_save_fl_direct)
 | |
| 	RELOC(xen_save_fl_direct, 0)
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * In principle the caller should be passing us a value return from
 | |
|  * xen_save_fl_direct, but for robustness sake we test only the
 | |
|  * X86_EFLAGS_IF flag rather than the whole byte. After setting the
 | |
|  * interrupt mask state, it checks for unmasked pending events and
 | |
|  * enters the hypervisor to get them delivered if so.
 | |
|  */
 | |
| ENTRY(xen_restore_fl_direct)
 | |
| #ifdef CONFIG_X86_64
 | |
| 	testw $X86_EFLAGS_IF, %di
 | |
| #else
 | |
| 	testb $X86_EFLAGS_IF>>8, %ah
 | |
| #endif
 | |
| 	setz PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
 | |
| 	/*
 | |
| 	 * Preempt here doesn't matter because that will deal with any
 | |
| 	 * pending interrupts.  The pending check may end up being run
 | |
| 	 * on the wrong CPU, but that doesn't hurt.
 | |
| 	 */
 | |
| 
 | |
| 	/* check for unmasked and pending */
 | |
| 	cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
 | |
| 	jz 1f
 | |
| 2:	call check_events
 | |
| 1:
 | |
| ENDPATCH(xen_restore_fl_direct)
 | |
| 	ret
 | |
| 	ENDPROC(xen_restore_fl_direct)
 | |
| 	RELOC(xen_restore_fl_direct, 2b+1)
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Force an event check by making a hypercall, but preserve regs
 | |
|  * before making the call.
 | |
|  */
 | |
| check_events:
 | |
| #ifdef CONFIG_X86_32
 | |
| 	push %eax
 | |
| 	push %ecx
 | |
| 	push %edx
 | |
| 	call xen_force_evtchn_callback
 | |
| 	pop %edx
 | |
| 	pop %ecx
 | |
| 	pop %eax
 | |
| #else
 | |
| 	push %rax
 | |
| 	push %rcx
 | |
| 	push %rdx
 | |
| 	push %rsi
 | |
| 	push %rdi
 | |
| 	push %r8
 | |
| 	push %r9
 | |
| 	push %r10
 | |
| 	push %r11
 | |
| 	call xen_force_evtchn_callback
 | |
| 	pop %r11
 | |
| 	pop %r10
 | |
| 	pop %r9
 | |
| 	pop %r8
 | |
| 	pop %rdi
 | |
| 	pop %rsi
 | |
| 	pop %rdx
 | |
| 	pop %rcx
 | |
| 	pop %rax
 | |
| #endif
 | |
| 	ret
 |