arch/s390/kernel/wti.c

Source file repositories/reference/linux-study-clean/arch/s390/kernel/wti.c

File Facts

System
Linux kernel
Corpus path
arch/s390/kernel/wti.c
Extension
.c
Size
4971 bytes
Lines
216
Domain
Architecture Layer
Bucket
arch/s390
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct wti_debug {
	unsigned long	missed;
	unsigned long	addr;
	pid_t		pid;
};

struct wti_state {
	/* debug data for s390dbf */
	struct wti_debug	dbg;
	/*
	 * Represents the real-time thread responsible to
	 * acknowledge the warning-track interrupt and trigger
	 * preliminary and postliminary precautions.
	 */
	struct task_struct	*thread;
	/*
	 * If pending is true, the real-time thread must be scheduled.
	 * If not, a wake up of that thread will remain a noop.
	 */
	bool			pending;
};

static DEFINE_PER_CPU(struct wti_state, wti_state);

static debug_info_t *wti_dbg;

/*
 * During a warning-track grace period, interrupts are disabled
 * to prevent delays of the warning-track acknowledgment.
 *
 * Once the CPU is physically dispatched again, interrupts are
 * re-enabled.
 */

static void wti_irq_disable(void)
{
	unsigned long flags;
	struct ctlreg cr6;

	local_irq_save(flags);
	local_ctl_store(6, &cr6);
	/* disable all I/O interrupts */
	cr6.val &= ~0xff000000UL;
	local_ctl_load(6, &cr6);
	local_irq_restore(flags);
}

static void wti_irq_enable(void)
{
	unsigned long flags;
	struct ctlreg cr6;

	local_irq_save(flags);
	local_ctl_store(6, &cr6);
	/* enable all I/O interrupts */
	cr6.val |= 0xff000000UL;
	local_ctl_load(6, &cr6);
	local_irq_restore(flags);
}

static void store_debug_data(struct wti_state *st)
{
	struct pt_regs *regs = get_irq_regs();

	st->dbg.pid = current->pid;
	st->dbg.addr = 0;
	if (!user_mode(regs))
		st->dbg.addr = regs->psw.addr;
}

static void wti_interrupt(struct ext_code ext_code,
			  unsigned int param32, unsigned long param64)
{
	struct wti_state *st = this_cpu_ptr(&wti_state);

	inc_irq_stat(IRQEXT_WTI);
	wti_irq_disable();
	store_debug_data(st);
	st->pending = true;
	wake_up_process(st->thread);
}

static int wti_pending(unsigned int cpu)
{
	struct wti_state *st = per_cpu_ptr(&wti_state, cpu);

	return st->pending;
}

static void wti_dbf_grace_period(struct wti_state *st)

Annotation

Implementation Notes