:p
atchew
Login
Unlike (synchronous) exception handlers, interrupt handlers don't normally have a need to know the outer context's register state. Similarly, the vast majority of key handlers has no need for such. 1: keyhandler: don't pass cpu_user_regs around 2: IRQ: generalize [gs]et_irq_regs() 3: serial: drop serial_rx_fn's regs parameter 4: PV-shim: drop pv_console_rx()'s regs parameter 5: serial: drop serial_[rt]x_interrupt()'s regs parameter 6: IRQ: drop regs parameter from handler functions 7: x86/vPMU: drop regs parameter from interrupt functions 8: x86/APIC: drop regs parameter from direct vector handler functions Jan
There are exactly two handlers which care about the registers. Have handle_keypress() make the pointer available via a per-CPU variable, thus eliminating the need to pass it to all IRQ key handlers, making sure that a console-invoked key's handling can still nest inside a sysctl-invoked one's. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- Subsequently we may want to eliminate the fn/irq_fn union as well, along with dropping the now redundant irq_keyhandler_fn_t. --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -XXX,XX +XXX,XX @@ static void cf_check keypress_action(voi } static DECLARE_TASKLET(keypress_tasklet, keypress_action, NULL); +static DEFINE_PER_CPU(struct cpu_user_regs *, keypress_regs); void handle_keypress(unsigned char key, struct cpu_user_regs *regs) { @@ -XXX,XX +XXX,XX @@ void handle_keypress(unsigned char key, if ( !in_irq() || h->irq_callback ) { console_start_log_everything(); - h->irq_callback ? h->irq_fn(key, regs) : h->fn(key); + if ( h->irq_callback ) + { + struct cpu_user_regs *old = this_cpu(keypress_regs); + + this_cpu(keypress_regs) = regs; + h->irq_fn(key); + this_cpu(keypress_regs) = old; + } + else + h->fn(key); console_end_log_everything(); } else @@ -XXX,XX +XXX,XX @@ void cf_check dump_execstate(struct cpu_ watchdog_enable(); } -static void cf_check dump_registers( - unsigned char key, struct cpu_user_regs *regs) +static void cf_check dump_registers(unsigned char key) { unsigned int cpu; @@ -XXX,XX +XXX,XX @@ static void cf_check dump_registers( cpumask_copy(&dump_execstate_mask, &cpu_online_map); /* Get local execution state out immediately, in case we get stuck. */ - if ( regs ) - dump_execstate(regs); + if ( this_cpu(keypress_regs) ) + dump_execstate(this_cpu(keypress_regs)); else run_in_exception_handler(dump_execstate); @@ -XXX,XX +XXX,XX @@ static void cf_check dump_hwdom_register } } -static void cf_check reboot_machine( - unsigned char key, struct cpu_user_regs *regs) +static void cf_check reboot_machine(unsigned char key) { printk("'%c' pressed -> rebooting machine\n", key); machine_restart(0); @@ -XXX,XX +XXX,XX @@ static void cf_check run_all_nonirq_keyh static DECLARE_TASKLET(run_all_keyhandlers_tasklet, run_all_nonirq_keyhandlers, NULL); -static void cf_check run_all_keyhandlers( - unsigned char key, struct cpu_user_regs *regs) +static void cf_check run_all_keyhandlers(unsigned char key) { struct keyhandler *h; unsigned int k; @@ -XXX,XX +XXX,XX @@ static void cf_check run_all_keyhandlers if ( !h->irq_fn || !h->diagnostic || !h->irq_callback ) continue; printk("[%c: %s]\n", k, h->desc); - h->irq_fn(k, regs); + h->irq_fn(k); } watchdog_enable(); @@ -XXX,XX +XXX,XX @@ static void cf_check do_debugger_trap_fa barrier(); } -static void cf_check do_debug_key(unsigned char key, struct cpu_user_regs *regs) +static void cf_check do_debug_key(unsigned char key) { printk("'%c' pressed -> trapping into debugger\n", key); - if ( regs ) - do_debugger_trap_fatal(regs); + if ( this_cpu(keypress_regs) ) + do_debugger_trap_fatal(this_cpu(keypress_regs)); else run_in_exception_handler(do_debugger_trap_fatal); } -static void cf_check do_toggle_alt_key( - unsigned char key, struct cpu_user_regs *regs) +static void cf_check do_toggle_alt_key(unsigned char key) { alt_key_handling = !alt_key_handling; printk("'%c' pressed -> using %s key handling\n", key, --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -XXX,XX +XXX,XX @@ static int *__read_mostly upper_thresh_a static int *__read_mostly lower_thresh_adj = &xenlog_lower_thresh; static const char *__read_mostly thresh_adj = "standard"; -static void cf_check do_toggle_guest(unsigned char key, struct cpu_user_regs *regs) +static void cf_check do_toggle_guest(unsigned char key) { if ( upper_thresh_adj == &xenlog_upper_thresh ) { @@ -XXX,XX +XXX,XX @@ static void do_adj_thresh(unsigned char loglvl_str(*upper_thresh_adj)); } -static void cf_check do_inc_thresh(unsigned char key, struct cpu_user_regs *regs) +static void cf_check do_inc_thresh(unsigned char key) { ++*lower_thresh_adj; do_adj_thresh(key); } -static void cf_check do_dec_thresh(unsigned char key, struct cpu_user_regs *regs) +static void cf_check do_dec_thresh(unsigned char key) { if ( *lower_thresh_adj ) --*lower_thresh_adj; --- a/xen/include/xen/keyhandler.h +++ b/xen/include/xen/keyhandler.h @@ -XXX,XX +XXX,XX @@ typedef void (keyhandler_fn_t)(unsigned * * Called in hardirq context with interrupts disabled. */ -struct cpu_user_regs; -typedef void (irq_keyhandler_fn_t)(unsigned char key, - struct cpu_user_regs *regs); +typedef void irq_keyhandler_fn_t(unsigned char key); /* Initialize keytable with default handlers. */ void initialize_keytable(void); @@ -XXX,XX +XXX,XX @@ void register_irq_keyhandler(unsigned ch bool diagnostic); /* Inject a keypress into the key-handling subsystem. */ +struct cpu_user_regs; extern void handle_keypress(unsigned char key, struct cpu_user_regs *regs); enum crash_reason {
It's simply not needed anymore. Note how Linux made this change many years ago already, in 2.6.19 (late 2006, see [1]). Signed-off-by: Jan Beulich <jbeulich@suse.com> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?id=7d12e780e003f93433d49ce78cfedf4b4c52adc5 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -XXX,XX +XXX,XX @@ void gic_interrupt(struct cpu_user_regs } while (1); } -static void maintenance_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) +static void maintenance_interrupt(int irq, void *dev_id) { /* * This is a dummy interrupt handler. --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -XXX,XX +XXX,XX @@ void irq_set_affinity(struct irq_desc *d } int request_irq(unsigned int irq, unsigned int irqflags, - void (*handler)(int irq, void *dev_id, - struct cpu_user_regs *regs), + void (*handler)(int irq, void *dev_id), const char *devname, void *dev_id) { struct irqaction *action; @@ -XXX,XX +XXX,XX @@ void do_IRQ(struct cpu_user_regs *regs, do { - action->handler(irq, action->dev_id, regs); + action->handler(irq, action->dev_id); action = action->next; } while ( action ); --- a/xen/arch/arm/time.c +++ b/xen/arch/arm/time.c @@ -XXX,XX +XXX,XX @@ int reprogram_timer(s_time_t timeout) } /* Handle the firing timer */ -static void htimer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) +static void htimer_interrupt(int irq, void *dev_id) { if ( unlikely(!(READ_SYSREG(CNTHP_CTL_EL2) & CNTx_CTL_PENDING)) ) return; @@ -XXX,XX +XXX,XX @@ static void htimer_interrupt(int irq, vo WRITE_SYSREG(0, CNTHP_CTL_EL2); } -static void vtimer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) +static void vtimer_interrupt(int irq, void *dev_id) { /* * Edge-triggered interrupts can be used for the virtual timer. Even --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -XXX,XX +XXX,XX @@ static int __init cf_check irq_ratelimit __initcall(irq_ratelimit_init); int __init request_irq(unsigned int irq, unsigned int irqflags, - void (*handler)(int irq, void *dev_id, struct cpu_user_regs *regs), + void (*handler)(int irq, void *dev_id), const char * devname, void *dev_id) { struct irqaction * action; @@ -XXX,XX +XXX,XX @@ void do_IRQ(struct cpu_user_regs *regs) spin_unlock_irq(&desc->lock); tsc_in = tb_init_done ? get_cycles() : 0; - action->handler(irq, action->dev_id, regs); + action->handler(irq, action->dev_id); TRACE_3D(TRC_HW_IRQ_HANDLED, irq, tsc_in, get_cycles()); spin_lock_irq(&desc->lock); --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -XXX,XX +XXX,XX @@ again: } } -static void cf_check hpet_interrupt_handler( - int irq, void *data, struct cpu_user_regs *regs) +static void cf_check hpet_interrupt_handler(int irq, void *data) { struct hpet_event_channel *ch = data; --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -XXX,XX +XXX,XX @@ static void smp_send_timer_broadcast_ipi } } -static void cf_check timer_interrupt( - int irq, void *dev_id, struct cpu_user_regs *regs) +static void cf_check timer_interrupt(int irq, void *dev_id) { ASSERT(local_irq_is_enabled()); --- a/xen/common/irq.c +++ b/xen/common/irq.c @@ -XXX,XX +XXX,XX @@ int init_one_irq_desc(struct irq_desc *d return err; } -void cf_check no_action(int cpl, void *dev_id, struct cpu_user_regs *regs) +void cf_check no_action(int cpl, void *dev_id) { } --- a/xen/drivers/char/cadence-uart.c +++ b/xen/drivers/char/cadence-uart.c @@ -XXX,XX +XXX,XX @@ static struct cuart { #define cuart_read(uart, off) readl((uart)->regs + (off)) #define cuart_write(uart, off,val) writel((val), (uart)->regs + (off)) -static void cuart_interrupt(int irq, void *data, struct cpu_user_regs *regs) +static void cuart_interrupt(int irq, void *data) { struct serial_port *port = data; struct cuart *uart = port->uart; --- a/xen/drivers/char/exynos4210-uart.c +++ b/xen/drivers/char/exynos4210-uart.c @@ -XXX,XX +XXX,XX @@ static struct exynos4210_uart { #define exynos4210_read(uart, off) readl((uart)->regs + off) #define exynos4210_write(uart, off, val) writel(val, (uart->regs) + off) -static void exynos4210_uart_interrupt(int irq, void *data, struct cpu_user_regs *regs) +static void exynos4210_uart_interrupt(int irq, void *data) { struct serial_port *port = data; struct exynos4210_uart *uart = port->uart; --- a/xen/drivers/char/imx-lpuart.c +++ b/xen/drivers/char/imx-lpuart.c @@ -XXX,XX +XXX,XX @@ static struct imx_lpuart { struct vuart_info vuart; } imx8_com; -static void imx_lpuart_interrupt(int irq, void *data, - struct cpu_user_regs *regs) +static void imx_lpuart_interrupt(int irq, void *data) { struct serial_port *port = data; struct imx_lpuart *uart = port->uart; --- a/xen/drivers/char/meson-uart.c +++ b/xen/drivers/char/meson-uart.c @@ -XXX,XX +XXX,XX @@ static struct meson_uart { struct vuart_info vuart; } meson_com; -static void meson_uart_interrupt(int irq, void *data, - struct cpu_user_regs *regs) +static void meson_uart_interrupt(int irq, void *data) { struct serial_port *port = data; struct meson_uart *uart = port->uart; --- a/xen/drivers/char/mvebu-uart.c +++ b/xen/drivers/char/mvebu-uart.c @@ -XXX,XX +XXX,XX @@ static struct mvebu3700_uart { #define mvebu3700_read(uart, off) readl((uart)->regs + (off)) #define mvebu3700_write(uart, off, val) writel(val, (uart)->regs + (off)) -static void mvebu3700_uart_interrupt(int irq, void *data, - struct cpu_user_regs *regs) +static void mvebu3700_uart_interrupt(int irq, void *data) { struct serial_port *port = data; struct mvebu3700_uart *uart = port->uart; --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -XXX,XX +XXX,XX @@ static void handle_dw_usr_busy_quirk(str } } -static void cf_check ns16550_interrupt( - int irq, void *dev_id, struct cpu_user_regs *regs) +static void cf_check ns16550_interrupt(int irq, void *dev_id) { struct serial_port *port = dev_id; struct ns16550 *uart = port->uart; --- a/xen/drivers/char/omap-uart.c +++ b/xen/drivers/char/omap-uart.c @@ -XXX,XX +XXX,XX @@ static struct omap_uart { struct vuart_info vuart; } omap_com = {0}; -static void omap_uart_interrupt(int irq, void *data, struct cpu_user_regs *regs) +static void omap_uart_interrupt(int irq, void *data) { struct serial_port *port = data; struct omap_uart *uart = port->uart; --- a/xen/drivers/char/pl011.c +++ b/xen/drivers/char/pl011.c @@ -XXX,XX +XXX,XX @@ static unsigned int pl011_intr_status(st return (pl011_read(uart, RIS) & pl011_read(uart, IMSC)); } -static void pl011_interrupt(int irq, void *data, struct cpu_user_regs *regs) +static void pl011_interrupt(int irq, void *data) { struct serial_port *port = data; struct pl011 *uart = port->uart; --- a/xen/drivers/char/scif-uart.c +++ b/xen/drivers/char/scif-uart.c @@ -XXX,XX +XXX,XX @@ static const struct port_params port_par }, }; -static void scif_uart_interrupt(int irq, void *data, struct cpu_user_regs *regs) +static void scif_uart_interrupt(int irq, void *data) { struct serial_port *port = data; struct scif_uart *uart = port->uart; --- a/xen/drivers/passthrough/amd/iommu_init.c +++ b/xen/drivers/passthrough/amd/iommu_init.c @@ -XXX,XX +XXX,XX @@ static void cf_check do_amd_iommu_irq(vo static DECLARE_SOFTIRQ_TASKLET(amd_iommu_irq_tasklet, do_amd_iommu_irq, NULL); -static void cf_check iommu_interrupt_handler( - int irq, void *dev_id, struct cpu_user_regs *regs) +static void cf_check iommu_interrupt_handler(int irq, void *dev_id) { unsigned long flags; struct amd_iommu *iommu = dev_id; --- a/xen/drivers/passthrough/arm/smmu.c +++ b/xen/drivers/passthrough/arm/smmu.c @@ -XXX,XX +XXX,XX @@ static irqreturn_t arm_smmu_global_fault } /* Xen: Interrupt handlers wrapper */ -static void arm_smmu_context_fault_xen(int irq, void *dev, - struct cpu_user_regs *regs) +static void arm_smmu_context_fault_xen(int irq, void *dev) { arm_smmu_context_fault(irq, dev); } #define arm_smmu_context_fault arm_smmu_context_fault_xen -static void arm_smmu_global_fault_xen(int irq, void *dev, - struct cpu_user_regs *regs) +static void arm_smmu_global_fault_xen(int irq, void *dev) { arm_smmu_global_fault(irq, dev); } --- a/xen/drivers/passthrough/arm/smmu-v3.c +++ b/xen/drivers/passthrough/arm/smmu-v3.c @@ -XXX,XX +XXX,XX @@ static void arm_smmu_priq_tasklet(void * static int arm_smmu_device_disable(struct arm_smmu_device *smmu); -static void arm_smmu_gerror_handler(int irq, void *dev, - struct cpu_user_regs *regs) +static void arm_smmu_gerror_handler(int irq, void *dev) { u32 gerror, gerrorn, active; struct arm_smmu_device *smmu = dev; @@ -XXX,XX +XXX,XX @@ static void arm_smmu_gerror_handler(int writel(gerror, smmu->base + ARM_SMMU_GERRORN); } -static void arm_smmu_combined_irq_handler(int irq, void *dev, - struct cpu_user_regs *regs) +static void arm_smmu_combined_irq_handler(int irq, void *dev) { struct arm_smmu_device *smmu = dev; @@ -XXX,XX +XXX,XX @@ static void arm_smmu_combined_irq_taskle arm_smmu_priq_tasklet(dev); } -static void arm_smmu_evtq_irq_tasklet(int irq, void *dev, - struct cpu_user_regs *regs) +static void arm_smmu_evtq_irq_tasklet(int irq, void *dev) { struct arm_smmu_device *smmu = dev; tasklet_schedule(&(smmu->evtq_irq_tasklet)); } -static void arm_smmu_priq_irq_tasklet(int irq, void *dev, - struct cpu_user_regs *regs) +static void arm_smmu_priq_irq_tasklet(int irq, void *dev) { struct arm_smmu_device *smmu = dev; --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -XXX,XX +XXX,XX @@ static void cf_check do_iommu_page_fault __do_iommu_page_fault(drhd->iommu); } -static void cf_check iommu_page_fault( - int irq, void *dev_id, struct cpu_user_regs *regs) +static void cf_check iommu_page_fault(int irq, void *dev_id) { /* * Just flag the tasklet as runnable. This is fine, according to VT-d --- a/xen/include/xen/irq.h +++ b/xen/include/xen/irq.h @@ -XXX,XX +XXX,XX @@ ASSERT(!in_irq() && (local_irq_is_enabled() || num_online_cpus() <= 1)) struct irqaction { - void (*handler)(int irq, void *dev_id, struct cpu_user_regs *regs); + void (*handler)(int irq, void *dev_id); const char *name; void *dev_id; bool free_on_release; @@ -XXX,XX +XXX,XX @@ extern int setup_irq(unsigned int irq, u struct irqaction *new); extern void release_irq(unsigned int irq, const void *dev_id); extern int request_irq(unsigned int irq, unsigned int irqflags, - void (*handler)(int irq, void *dev_id, - struct cpu_user_regs *regs), + void (*handler)(int irq, void *dev_id), const char *devname, void *dev_id); extern hw_irq_controller no_irq_type; -void cf_check no_action(int cpl, void *dev_id, struct cpu_user_regs *regs); +void cf_check no_action(int cpl, void *dev_id); unsigned int cf_check irq_startup_none(struct irq_desc *desc); void cf_check irq_actor_none(struct irq_desc *desc); #define irq_shutdown_none irq_actor_none
In the one place where it's needed, get_irq_regs() can be used instead. This is in preparation of dropping the register parameters from IRQ handler functions. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -XXX,XX +XXX,XX @@ static void switch_serial_input(void) printk("\n"); } -static void __serial_rx(char c, struct cpu_user_regs *regs) +static void __serial_rx(char c) { switch ( console_rx ) { case 0: - return handle_keypress(c, regs); + return handle_keypress(c, get_irq_regs()); case 1: /* @@ -XXX,XX +XXX,XX @@ static void __serial_rx(char c, struct c #endif } -static void cf_check serial_rx(char c, struct cpu_user_regs *regs) +static void cf_check serial_rx(char c) { static int switch_code_count = 0; @@ -XXX,XX +XXX,XX @@ static void cf_check serial_rx(char c, s } for ( ; switch_code_count != 0; switch_code_count-- ) - __serial_rx(switch_code, regs); + __serial_rx(switch_code); /* Finally process the just-received character. */ - __serial_rx(c, regs); + __serial_rx(c); } static void cf_check notify_dom0_con_ring(void *unused) --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -XXX,XX +XXX,XX @@ void serial_rx_interrupt(struct serial_p spin_unlock_irqrestore(&port->rx_lock, flags); if ( fn != NULL ) - (*fn)(c & 0x7f, regs); + fn(c & 0x7f); } void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs) --- a/xen/drivers/char/xen_pv_console.c +++ b/xen/drivers/char/xen_pv_console.c @@ -XXX,XX +XXX,XX @@ size_t pv_console_rx(struct cpu_user_reg { c = cons_ring->in[MASK_XENCONS_IDX(cons++, cons_ring->in)]; if ( cons_rx_handler ) - cons_rx_handler(c, regs); + cons_rx_handler(c); recv++; } --- a/xen/include/xen/serial.h +++ b/xen/include/xen/serial.h @@ -XXX,XX +XXX,XX @@ struct cpu_user_regs; /* Register a character-receive hook on the specified COM port. */ -typedef void (*serial_rx_fn)(char c, struct cpu_user_regs *regs); +typedef void (*serial_rx_fn)(char c); void serial_set_rx_handler(int handle, serial_rx_fn fn); /* Number of characters we buffer for a polling receiver. */
It's not needed anymore. This is in preparation of dropping the register parameters from IRQ handler functions. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/guest/xen/xen.c +++ b/xen/arch/x86/guest/xen/xen.c @@ -XXX,XX +XXX,XX @@ static void cf_check xen_evtchn_upcall(s port += l1 * BITS_PER_LONG; if ( pv_console && port == pv_console_evtchn() ) - pv_console_rx(regs); + pv_console_rx(); else if ( pv_shim ) pv_shim_inject_evtchn(port); } --- a/xen/drivers/char/xen_pv_console.c +++ b/xen/drivers/char/xen_pv_console.c @@ -XXX,XX +XXX,XX @@ evtchn_port_t pv_console_evtchn(void) return cons_evtchn; } -size_t pv_console_rx(struct cpu_user_regs *regs) +size_t pv_console_rx(void) { char c; XENCONS_RING_IDX cons, prod; --- a/xen/include/xen/pv_console.h +++ b/xen/include/xen/pv_console.h @@ -XXX,XX +XXX,XX @@ void pv_console_init(void); void pv_console_set_rx_handler(serial_rx_fn fn); void pv_console_init_postirq(void); void pv_console_puts(const char *buf, size_t nr); -size_t pv_console_rx(struct cpu_user_regs *regs); +size_t pv_console_rx(void); evtchn_port_t pv_console_evtchn(void); #else @@ -XXX,XX +XXX,XX @@ static inline void pv_console_init(void) static inline void pv_console_set_rx_handler(serial_rx_fn fn) { } static inline void pv_console_init_postirq(void) { } static inline void pv_console_puts(const char *buf, size_t nr) { } -static inline size_t pv_console_rx(struct cpu_user_regs *regs) { return 0; } +static inline size_t pv_console_rx(void) { return 0; } #endif /* !CONFIG_XEN_GUEST */ #endif /* __XEN_PV_CONSOLE_H__ */
Unlike (synchronous) exception handlers, interrupt handlers don't normally have a need to know the outer context's register state. Similarly, the vast majority of key handlers has no need for such. 1: serial: fake IRQ-regs context in poll handlers 2: keyhandler: drop regs parameter from handle_keyregs() 3: serial: drop serial_rx_fn's regs parameter 4: PV-shim: drop pv_console_rx()'s regs parameter 5: serial: drop serial_[rt]x_interrupt()'s regs parameter 6: IRQ: drop regs parameter from handler functions 7: x86/APIC: drop regs parameter from direct vector handler functions 8: consolidate do_bug_frame() / bug_fn_t Jan
In preparation of dropping the register parameters from serial_[rt]x_interrupt() and in turn from IRQ handler functions, register state needs making available another way for the few key handlers which need it. Fake IRQ-like state. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- The use of guest_cpu_user_regs() in dbc_uart_poll() is inconsistent with other console poll functions we have, and it's unclear whether that's actually generally correct. Andrew suggested to move set_irq_regs() to BUGFRAME_run_fn handling; it's not clear to me whether that would be (a) correct from an abstract pov (that's exception, not interrupt context after all) and (b) really beneficial. --- v2: New. --- a/xen/drivers/char/ehci-dbgp.c +++ b/xen/drivers/char/ehci-dbgp.c @@ -XXX,XX +XXX,XX @@ static void cf_check _ehci_dbgp_poll(str unsigned long flags; unsigned int timeout = MICROSECS(DBGP_CHECK_INTERVAL); bool empty = false; + struct cpu_user_regs *old_regs; if ( !dbgp->ehci_debug ) return; @@ -XXX,XX +XXX,XX @@ static void cf_check _ehci_dbgp_poll(str spin_unlock_irqrestore(&port->tx_lock, flags); } + /* Mimic interrupt context. */ + old_regs = set_irq_regs(regs); + if ( dbgp->in.chunk ) serial_rx_interrupt(port, regs); if ( empty ) serial_tx_interrupt(port, regs); + set_irq_regs(old_regs); + if ( spin_trylock_irqsave(&port->tx_lock, flags) ) { if ( dbgp->state == dbgp_idle && !dbgp->in.chunk && --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -XXX,XX +XXX,XX @@ static void cf_check __ns16550_poll(stru { struct serial_port *port = this_cpu(poll_port); struct ns16550 *uart = port->uart; + struct cpu_user_regs *old_regs; if ( uart->intr_works ) return; /* Interrupts work - no more polling */ + /* Mimic interrupt context. */ + old_regs = set_irq_regs(regs); + while ( ns_read_reg(uart, UART_LSR) & UART_LSR_DR ) { if ( ns16550_ioport_invalid(uart) ) @@ -XXX,XX +XXX,XX @@ static void cf_check __ns16550_poll(stru serial_tx_interrupt(port, regs); out: + set_irq_regs(old_regs); set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms)); } --- a/xen/drivers/char/xhci-dbc.c +++ b/xen/drivers/char/xhci-dbc.c @@ -XXX,XX +XXX,XX @@ static void cf_check dbc_uart_poll(void struct dbc_uart *uart = port->uart; struct dbc *dbc = &uart->dbc; unsigned long flags = 0; + struct cpu_user_regs *old_regs; if ( spin_trylock_irqsave(&port->tx_lock, flags) ) { @@ -XXX,XX +XXX,XX @@ static void cf_check dbc_uart_poll(void spin_unlock_irqrestore(&port->tx_lock, flags); } + /* Mimic interrupt context. */ + old_regs = set_irq_regs(guest_cpu_user_regs()); + while ( dbc_work_ring_size(&dbc->dbc_iwork) ) serial_rx_interrupt(port, guest_cpu_user_regs()); serial_tx_interrupt(port, guest_cpu_user_regs()); + + set_irq_regs(old_regs); set_timer(&uart->timer, NOW() + MICROSECS(DBC_POLL_INTERVAL)); }
In preparation for further removal of regs parameters, drop it here. In the two places where it's actually needed, retrieve IRQ context if available, or else guest context. Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> --- As an alternative to the new boolean parameter, I wonder if we couldn't special-case the idle vCPU case: It's only there where we would not have proper context retrievable via guest_cpu_user_regs(). --- v3: Re-base. v2: New. --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -XXX,XX +XXX,XX @@ static struct keyhandler { static void cf_check keypress_action(void *unused) { - handle_keypress(keypress_key, NULL); + handle_keypress(keypress_key, true); } static DECLARE_TASKLET(keypress_tasklet, keypress_action, NULL); -void handle_keypress(unsigned char key, struct cpu_user_regs *regs) +void handle_keypress(unsigned char key, bool need_context) { struct keyhandler *h; @@ -XXX,XX +XXX,XX @@ void handle_keypress(unsigned char key, if ( !in_irq() || h->irq_callback ) { console_start_log_everything(); - h->irq_callback ? h->irq_fn(key, regs) : h->fn(key); + h->irq_callback ? h->irq_fn(key, need_context) : h->fn(key); console_end_log_everything(); } else @@ -XXX,XX +XXX,XX @@ void cf_check dump_execstate(struct cpu_ } static void cf_check dump_registers( - unsigned char key, struct cpu_user_regs *regs) + unsigned char key, bool need_context) { unsigned int cpu; @@ -XXX,XX +XXX,XX @@ static void cf_check dump_registers( cpumask_copy(&dump_execstate_mask, &cpu_online_map); /* Get local execution state out immediately, in case we get stuck. */ - if ( regs ) - dump_execstate(regs); + if ( !need_context ) + dump_execstate(get_irq_regs() ?: guest_cpu_user_regs()); else run_in_exception_handler(dump_execstate); @@ -XXX,XX +XXX,XX @@ static void cf_check dump_hwdom_register } } -static void cf_check reboot_machine( - unsigned char key, struct cpu_user_regs *regs) +static void cf_check reboot_machine(unsigned char key, bool unused) { printk("'%c' pressed -> rebooting machine\n", key); machine_restart(0); @@ -XXX,XX +XXX,XX @@ static void cf_check run_all_nonirq_keyh static DECLARE_TASKLET(run_all_keyhandlers_tasklet, run_all_nonirq_keyhandlers, NULL); -static void cf_check run_all_keyhandlers( - unsigned char key, struct cpu_user_regs *regs) +static void cf_check run_all_keyhandlers(unsigned char key, bool need_context) { struct keyhandler *h; unsigned int k; @@ -XXX,XX +XXX,XX @@ static void cf_check run_all_keyhandlers if ( !h->irq_fn || !h->diagnostic || !h->irq_callback ) continue; printk("[%c: %s]\n", k, h->desc); - h->irq_fn(k, regs); + h->irq_fn(k, need_context); } watchdog_enable(); @@ -XXX,XX +XXX,XX @@ static void cf_check run_all_keyhandlers tasklet_schedule(&run_all_keyhandlers_tasklet); } -static void cf_check do_toggle_alt_key( - unsigned char key, struct cpu_user_regs *regs) +static void cf_check do_toggle_alt_key(unsigned char key, bool unused) { alt_key_handling = !alt_key_handling; printk("'%c' pressed -> using %s key handling\n", key, @@ -XXX,XX +XXX,XX @@ void keyhandler_crash_action(enum crash_ if ( *action == '+' ) mdelay(10); else - handle_keypress(*action, NULL); + handle_keypress(*action, true); action++; } } --- a/xen/common/sysctl.c +++ b/xen/common/sysctl.c @@ -XXX,XX +XXX,XX @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe { if ( copy_from_guest_offset(&c, op->u.debug_keys.keys, i, 1) ) goto out; - handle_keypress(c, guest_cpu_user_regs()); + handle_keypress(c, false); } ret = 0; copyback = 0; --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -XXX,XX +XXX,XX @@ static int *__read_mostly upper_thresh_a static int *__read_mostly lower_thresh_adj = &xenlog_lower_thresh; static const char *__read_mostly thresh_adj = "standard"; -static void cf_check do_toggle_guest(unsigned char key, struct cpu_user_regs *regs) +static void cf_check do_toggle_guest(unsigned char key, bool unused) { if ( upper_thresh_adj == &xenlog_upper_thresh ) { @@ -XXX,XX +XXX,XX @@ static void do_adj_thresh(unsigned char loglvl_str(*upper_thresh_adj)); } -static void cf_check do_inc_thresh(unsigned char key, struct cpu_user_regs *regs) +static void cf_check do_inc_thresh(unsigned char key, bool unused) { ++*lower_thresh_adj; do_adj_thresh(key); } -static void cf_check do_dec_thresh(unsigned char key, struct cpu_user_regs *regs) +static void cf_check do_dec_thresh(unsigned char key, bool unused) { if ( *lower_thresh_adj ) --*lower_thresh_adj; @@ -XXX,XX +XXX,XX @@ static void __serial_rx(char c, struct c switch ( console_rx ) { case 0: - return handle_keypress(c, regs); + return handle_keypress(c, false); case 1: /* --- a/xen/include/xen/keyhandler.h +++ b/xen/include/xen/keyhandler.h @@ -XXX,XX +XXX,XX @@ typedef void (keyhandler_fn_t)(unsigned * * Called in hardirq context with interrupts disabled. */ -struct cpu_user_regs; typedef void (irq_keyhandler_fn_t)(unsigned char key, - struct cpu_user_regs *regs); + bool need_context); /* Initialize keytable with default handlers. */ void initialize_keytable(void); @@ -XXX,XX +XXX,XX @@ void register_irq_keyhandler(unsigned ch bool diagnostic); /* Inject a keypress into the key-handling subsystem. */ -extern void handle_keypress(unsigned char key, struct cpu_user_regs *regs); +extern void handle_keypress(unsigned char key, bool need_context); enum crash_reason { CRASHREASON_PANIC,
It's simply not needed anymore. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- v2: Re-base over earlier (new/split) patches. --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -XXX,XX +XXX,XX @@ static void switch_serial_input(void) printk("\n"); } -static void __serial_rx(char c, struct cpu_user_regs *regs) +static void __serial_rx(char c) { switch ( console_rx ) { @@ -XXX,XX +XXX,XX @@ static void __serial_rx(char c, struct c #endif } -static void cf_check serial_rx(char c, struct cpu_user_regs *regs) +static void cf_check serial_rx(char c) { static int switch_code_count = 0; @@ -XXX,XX +XXX,XX @@ static void cf_check serial_rx(char c, s } for ( ; switch_code_count != 0; switch_code_count-- ) - __serial_rx(switch_code, regs); + __serial_rx(switch_code); /* Finally process the just-received character. */ - __serial_rx(c, regs); + __serial_rx(c); } static void cf_check notify_dom0_con_ring(void *unused) --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -XXX,XX +XXX,XX @@ void serial_rx_interrupt(struct serial_p spin_unlock_irqrestore(&port->rx_lock, flags); if ( fn != NULL ) - (*fn)(c & 0x7f, regs); + fn(c & 0x7f); } void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs) --- a/xen/drivers/char/xen_pv_console.c +++ b/xen/drivers/char/xen_pv_console.c @@ -XXX,XX +XXX,XX @@ size_t pv_console_rx(struct cpu_user_reg { c = cons_ring->in[MASK_XENCONS_IDX(cons++, cons_ring->in)]; if ( cons_rx_handler ) - cons_rx_handler(c, regs); + cons_rx_handler(c); recv++; } --- a/xen/include/xen/serial.h +++ b/xen/include/xen/serial.h @@ -XXX,XX +XXX,XX @@ struct cpu_user_regs; /* Register a character-receive hook on the specified COM port. */ -typedef void (*serial_rx_fn)(char c, struct cpu_user_regs *regs); +typedef void (*serial_rx_fn)(char c); void serial_set_rx_handler(int handle, serial_rx_fn fn); /* Number of characters we buffer for a polling receiver. */
It's not needed anymore. This is in preparation of dropping the register parameters from IRQ handler functions. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> --- a/xen/arch/x86/guest/xen/xen.c +++ b/xen/arch/x86/guest/xen/xen.c @@ -XXX,XX +XXX,XX @@ static void cf_check xen_evtchn_upcall(s port += l1 * BITS_PER_LONG; if ( pv_console && port == pv_console_evtchn() ) - pv_console_rx(regs); + pv_console_rx(); else if ( pv_shim ) pv_shim_inject_evtchn(port); } --- a/xen/drivers/char/xen_pv_console.c +++ b/xen/drivers/char/xen_pv_console.c @@ -XXX,XX +XXX,XX @@ evtchn_port_t pv_console_evtchn(void) return cons_evtchn; } -size_t pv_console_rx(struct cpu_user_regs *regs) +size_t pv_console_rx(void) { char c; XENCONS_RING_IDX cons, prod; --- a/xen/include/xen/pv_console.h +++ b/xen/include/xen/pv_console.h @@ -XXX,XX +XXX,XX @@ void pv_console_init(void); void pv_console_set_rx_handler(serial_rx_fn fn); void pv_console_init_postirq(void); void pv_console_puts(const char *buf, size_t nr); -size_t pv_console_rx(struct cpu_user_regs *regs); +size_t pv_console_rx(void); evtchn_port_t pv_console_evtchn(void); #else @@ -XXX,XX +XXX,XX @@ static inline void pv_console_init(void) static inline void pv_console_set_rx_handler(serial_rx_fn fn) { } static inline void pv_console_init_postirq(void) { } static inline void pv_console_puts(const char *buf, size_t nr) { } -static inline size_t pv_console_rx(struct cpu_user_regs *regs) { return 0; } +static inline size_t pv_console_rx(void) { return 0; } #endif /* !CONFIG_XEN_GUEST */ #endif /* __XEN_PV_CONSOLE_H__ */
They're simply not needed anymore. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- v2: Setting of IRQ regs split off to an earlier patch. --- a/xen/drivers/char/cadence-uart.c +++ b/xen/drivers/char/cadence-uart.c @@ -XXX,XX +XXX,XX @@ static void cuart_interrupt(int irq, voi /* ACK. */ if ( status & UART_SR_INTR_RTRIG ) { - serial_rx_interrupt(port, regs); + serial_rx_interrupt(port); cuart_write(uart, R_UART_CISR, UART_SR_INTR_RTRIG); } } while ( status & UART_SR_INTR_RTRIG ); --- a/xen/drivers/char/ehci-dbgp.c +++ b/xen/drivers/char/ehci-dbgp.c @@ -XXX,XX +XXX,XX @@ static void cf_check _ehci_dbgp_poll(str old_regs = set_irq_regs(regs); if ( dbgp->in.chunk ) - serial_rx_interrupt(port, regs); + serial_rx_interrupt(port); if ( empty ) - serial_tx_interrupt(port, regs); + serial_tx_interrupt(port); set_irq_regs(old_regs); --- a/xen/drivers/char/exynos4210-uart.c +++ b/xen/drivers/char/exynos4210-uart.c @@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_interrupt(in if ( status & (UINTM_RXD | UINTM_ERROR) ) { /* uart->regs[UINTM] |= RXD|ERROR; */ - serial_rx_interrupt(port, regs); + serial_rx_interrupt(port); /* uart->regs[UINTM] &= ~(RXD|ERROR); */ exynos4210_write(uart, UINTP, UINTM_RXD | UINTM_ERROR); } @@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_interrupt(in if ( status & (UINTM_TXD | UINTM_MODEM) ) { /* uart->regs[UINTM] |= TXD|MODEM; */ - serial_tx_interrupt(port, regs); + serial_tx_interrupt(port); /* uart->regs[UINTM] &= ~(TXD|MODEM); */ exynos4210_write(uart, UINTP, UINTM_TXD | UINTM_MODEM); } --- a/xen/drivers/char/imx-lpuart.c +++ b/xen/drivers/char/imx-lpuart.c @@ -XXX,XX +XXX,XX @@ static void imx_lpuart_interrupt(int irq rxcnt = imx_lpuart_read(uart, UARTWATER) >> UARTWATER_RXCNT_OFF; if ( (sts & UARTSTAT_RDRF) || (rxcnt > 0) ) - serial_rx_interrupt(port, regs); + serial_rx_interrupt(port); if ( sts & UARTSTAT_TDRE ) - serial_tx_interrupt(port, regs); + serial_tx_interrupt(port); imx_lpuart_write(uart, UARTSTAT, sts); } --- a/xen/drivers/char/meson-uart.c +++ b/xen/drivers/char/meson-uart.c @@ -XXX,XX +XXX,XX @@ static void meson_uart_interrupt(int irq uint32_t st = readl(uart->regs + AML_UART_STATUS_REG); if ( !(st & AML_UART_RX_FIFO_EMPTY) ) - serial_rx_interrupt(port, regs); + serial_rx_interrupt(port); if ( !(st & AML_UART_TX_FIFO_FULL) ) - serial_tx_interrupt(port, regs); + serial_tx_interrupt(port); } static void __init meson_uart_init_preirq(struct serial_port *port) --- a/xen/drivers/char/mvebu-uart.c +++ b/xen/drivers/char/mvebu-uart.c @@ -XXX,XX +XXX,XX @@ static void mvebu3700_uart_interrupt(int if ( st & (STATUS_RX_RDY | STATUS_OVR_ERR | STATUS_FRM_ERR | STATUS_BRK_DET) ) - serial_rx_interrupt(port, regs); + serial_rx_interrupt(port); if ( st & STATUS_TX_RDY ) - serial_tx_interrupt(port, regs); + serial_tx_interrupt(port); } static void __init mvebu3700_uart_init_preirq(struct serial_port *port) --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -XXX,XX +XXX,XX @@ static void cf_check ns16550_interrupt( u8 lsr = ns_read_reg(uart, UART_LSR); if ( (lsr & uart->lsr_mask) == uart->lsr_mask ) - serial_tx_interrupt(port, regs); + serial_tx_interrupt(port); if ( lsr & UART_LSR_DR ) - serial_rx_interrupt(port, regs); + serial_rx_interrupt(port); /* A "busy-detect" condition is observed on Allwinner/sunxi UART * after LCR is written during setup. It needs to be cleared at @@ -XXX,XX +XXX,XX @@ static void cf_check __ns16550_poll(stru if ( ns16550_ioport_invalid(uart) ) goto out; - serial_rx_interrupt(port, regs); + serial_rx_interrupt(port); } if ( ( ns_read_reg(uart, UART_LSR) & uart->lsr_mask ) == uart->lsr_mask ) - serial_tx_interrupt(port, regs); + serial_tx_interrupt(port); out: set_irq_regs(old_regs); --- a/xen/drivers/char/omap-uart.c +++ b/xen/drivers/char/omap-uart.c @@ -XXX,XX +XXX,XX @@ static void omap_uart_interrupt(int irq, { lsr = omap_read(uart, UART_LSR) & 0xff; if ( lsr & UART_LSR_THRE ) - serial_tx_interrupt(port, regs); + serial_tx_interrupt(port); if ( lsr & UART_LSR_DR ) - serial_rx_interrupt(port, regs); + serial_rx_interrupt(port); if ( port->txbufc == port->txbufp ) { reg = omap_read(uart, UART_IER); --- a/xen/drivers/char/pl011.c +++ b/xen/drivers/char/pl011.c @@ -XXX,XX +XXX,XX @@ static void pl011_interrupt(int irq, voi pl011_write(uart, ICR, status & ~(TXI|RTI|RXI)); if ( status & (RTI|RXI) ) - serial_rx_interrupt(port, regs); + serial_rx_interrupt(port); /* TODO if ( status & (DSRMI|DCDMI|CTSMI|RIMI) ) @@ -XXX,XX +XXX,XX @@ static void pl011_interrupt(int irq, voi */ if ( status & (TXI) ) - serial_tx_interrupt(port, regs); + serial_tx_interrupt(port); status = pl011_intr_status(uart); } while (status != 0); --- a/xen/drivers/char/scif-uart.c +++ b/xen/drivers/char/scif-uart.c @@ -XXX,XX +XXX,XX @@ static void scif_uart_interrupt(int irq, { /* TX Interrupt */ if ( status & SCFSR_TDFE ) - serial_tx_interrupt(port, regs); + serial_tx_interrupt(port); /* RX Interrupt */ if ( status & (SCFSR_RDF | SCFSR_DR) ) - serial_rx_interrupt(port, regs); + serial_rx_interrupt(port); /* Error Interrupt */ if ( status & params->error_mask ) --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -XXX,XX +XXX,XX @@ static inline void serial_stop_tx(struct port->driver->stop_tx(port); } -void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs) +void serial_rx_interrupt(struct serial_port *port) { char c; serial_rx_fn fn = NULL; @@ -XXX,XX +XXX,XX @@ void serial_rx_interrupt(struct serial_p fn(c & 0x7f); } -void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs) +void serial_tx_interrupt(struct serial_port *port) { int i, n; unsigned long flags; --- a/xen/drivers/char/xhci-dbc.c +++ b/xen/drivers/char/xhci-dbc.c @@ -XXX,XX +XXX,XX @@ static void cf_check dbc_uart_poll(void old_regs = set_irq_regs(guest_cpu_user_regs()); while ( dbc_work_ring_size(&dbc->dbc_iwork) ) - serial_rx_interrupt(port, guest_cpu_user_regs()); + serial_rx_interrupt(port); - serial_tx_interrupt(port, guest_cpu_user_regs()); + serial_tx_interrupt(port); set_irq_regs(old_regs); set_timer(&uart->timer, NOW() + MICROSECS(DBC_POLL_INTERVAL)); --- a/xen/include/xen/serial.h +++ b/xen/include/xen/serial.h @@ -XXX,XX +XXX,XX @@ #include <xen/init.h> #include <xen/spinlock.h> -struct cpu_user_regs; - /* Register a character-receive hook on the specified COM port. */ typedef void (*serial_rx_fn)(char c); void serial_set_rx_handler(int handle, serial_rx_fn fn); @@ -XXX,XX +XXX,XX @@ void serial_register_uart(int idx, struc /* Place the serial port into asynchronous transmit mode. */ void serial_async_transmit(struct serial_port *port); /* Process work in interrupt context. */ -void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs); -void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs); +void serial_rx_interrupt(struct serial_port *port); +void serial_tx_interrupt(struct serial_port *port); /* * Initialisers for individual uart drivers.
It's simply not needed anymore. Note how Linux made this change many years ago already, in 2.6.19 (late 2006, see [1]). Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> Acked-by: Julien Grall <jgrall@amazon.com> [1] https://git.kernel.org/torvalds/c/7d12e780e003f93433d49ce78cfedf4b4c52adc5 --- v2: Arm build fixes. --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -XXX,XX +XXX,XX @@ void gic_interrupt(struct cpu_user_regs } while (1); } -static void maintenance_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) +static void maintenance_interrupt(int irq, void *dev_id) { /* * This is a dummy interrupt handler. --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -XXX,XX +XXX,XX @@ void irq_set_affinity(struct irq_desc *d } int request_irq(unsigned int irq, unsigned int irqflags, - void (*handler)(int irq, void *dev_id, - struct cpu_user_regs *regs), + void (*handler)(int irq, void *dev_id), const char *devname, void *dev_id) { struct irqaction *action; @@ -XXX,XX +XXX,XX @@ void do_IRQ(struct cpu_user_regs *regs, do { - action->handler(irq, action->dev_id, regs); + action->handler(irq, action->dev_id); action = action->next; } while ( action ); --- a/xen/arch/arm/time.c +++ b/xen/arch/arm/time.c @@ -XXX,XX +XXX,XX @@ int reprogram_timer(s_time_t timeout) } /* Handle the firing timer */ -static void htimer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) +static void htimer_interrupt(int irq, void *dev_id) { if ( unlikely(!(READ_SYSREG(CNTHP_CTL_EL2) & CNTx_CTL_PENDING)) ) return; @@ -XXX,XX +XXX,XX @@ static void htimer_interrupt(int irq, vo WRITE_SYSREG(0, CNTHP_CTL_EL2); } -static void vtimer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) +static void vtimer_interrupt(int irq, void *dev_id) { /* * Edge-triggered interrupts can be used for the virtual timer. Even --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -XXX,XX +XXX,XX @@ static int __init cf_check irq_ratelimit __initcall(irq_ratelimit_init); int __init request_irq(unsigned int irq, unsigned int irqflags, - void (*handler)(int irq, void *dev_id, struct cpu_user_regs *regs), + void (*handler)(int irq, void *dev_id), const char * devname, void *dev_id) { struct irqaction * action; @@ -XXX,XX +XXX,XX @@ void do_IRQ(struct cpu_user_regs *regs) spin_unlock_irq(&desc->lock); tsc_in = tb_init_done ? get_cycles() : 0; - action->handler(irq, action->dev_id, regs); + action->handler(irq, action->dev_id); TRACE_3D(TRC_HW_IRQ_HANDLED, irq, tsc_in, get_cycles()); spin_lock_irq(&desc->lock); --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -XXX,XX +XXX,XX @@ again: } } -static void cf_check hpet_interrupt_handler( - int irq, void *data, struct cpu_user_regs *regs) +static void cf_check hpet_interrupt_handler(int irq, void *data) { struct hpet_event_channel *ch = data; --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -XXX,XX +XXX,XX @@ static void smp_send_timer_broadcast_ipi } } -static void cf_check timer_interrupt( - int irq, void *dev_id, struct cpu_user_regs *regs) +static void cf_check timer_interrupt(int irq, void *dev_id) { ASSERT(local_irq_is_enabled()); --- a/xen/common/irq.c +++ b/xen/common/irq.c @@ -XXX,XX +XXX,XX @@ int init_one_irq_desc(struct irq_desc *d return err; } -void cf_check no_action(int cpl, void *dev_id, struct cpu_user_regs *regs) +void cf_check no_action(int cpl, void *dev_id) { } --- a/xen/drivers/char/cadence-uart.c +++ b/xen/drivers/char/cadence-uart.c @@ -XXX,XX +XXX,XX @@ static struct cuart { #define cuart_read(uart, off) readl((uart)->regs + (off)) #define cuart_write(uart, off,val) writel((val), (uart)->regs + (off)) -static void cuart_interrupt(int irq, void *data, struct cpu_user_regs *regs) +static void cuart_interrupt(int irq, void *data) { struct serial_port *port = data; struct cuart *uart = port->uart; --- a/xen/drivers/char/exynos4210-uart.c +++ b/xen/drivers/char/exynos4210-uart.c @@ -XXX,XX +XXX,XX @@ static struct exynos4210_uart { #define exynos4210_read(uart, off) readl((uart)->regs + off) #define exynos4210_write(uart, off, val) writel(val, (uart->regs) + off) -static void exynos4210_uart_interrupt(int irq, void *data, struct cpu_user_regs *regs) +static void exynos4210_uart_interrupt(int irq, void *data) { struct serial_port *port = data; struct exynos4210_uart *uart = port->uart; --- a/xen/drivers/char/imx-lpuart.c +++ b/xen/drivers/char/imx-lpuart.c @@ -XXX,XX +XXX,XX @@ static struct imx_lpuart { struct vuart_info vuart; } imx8_com; -static void imx_lpuart_interrupt(int irq, void *data, - struct cpu_user_regs *regs) +static void imx_lpuart_interrupt(int irq, void *data) { struct serial_port *port = data; struct imx_lpuart *uart = port->uart; --- a/xen/drivers/char/meson-uart.c +++ b/xen/drivers/char/meson-uart.c @@ -XXX,XX +XXX,XX @@ static struct meson_uart { struct vuart_info vuart; } meson_com; -static void meson_uart_interrupt(int irq, void *data, - struct cpu_user_regs *regs) +static void meson_uart_interrupt(int irq, void *data) { struct serial_port *port = data; struct meson_uart *uart = port->uart; --- a/xen/drivers/char/mvebu-uart.c +++ b/xen/drivers/char/mvebu-uart.c @@ -XXX,XX +XXX,XX @@ static struct mvebu3700_uart { #define mvebu3700_read(uart, off) readl((uart)->regs + (off)) #define mvebu3700_write(uart, off, val) writel(val, (uart)->regs + (off)) -static void mvebu3700_uart_interrupt(int irq, void *data, - struct cpu_user_regs *regs) +static void mvebu3700_uart_interrupt(int irq, void *data) { struct serial_port *port = data; struct mvebu3700_uart *uart = port->uart; --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -XXX,XX +XXX,XX @@ static void handle_dw_usr_busy_quirk(str } } -static void cf_check ns16550_interrupt( - int irq, void *dev_id, struct cpu_user_regs *regs) +static void cf_check ns16550_interrupt(int irq, void *dev_id) { struct serial_port *port = dev_id; struct ns16550 *uart = port->uart; --- a/xen/drivers/char/omap-uart.c +++ b/xen/drivers/char/omap-uart.c @@ -XXX,XX +XXX,XX @@ static struct omap_uart { struct vuart_info vuart; } omap_com = {0}; -static void omap_uart_interrupt(int irq, void *data, struct cpu_user_regs *regs) +static void omap_uart_interrupt(int irq, void *data) { struct serial_port *port = data; struct omap_uart *uart = port->uart; --- a/xen/drivers/char/pl011.c +++ b/xen/drivers/char/pl011.c @@ -XXX,XX +XXX,XX @@ static unsigned int pl011_intr_status(st return (pl011_read(uart, RIS) & pl011_read(uart, IMSC)); } -static void pl011_interrupt(int irq, void *data, struct cpu_user_regs *regs) +static void pl011_interrupt(int irq, void *data) { struct serial_port *port = data; struct pl011 *uart = port->uart; --- a/xen/drivers/char/scif-uart.c +++ b/xen/drivers/char/scif-uart.c @@ -XXX,XX +XXX,XX @@ static const struct port_params port_par }, }; -static void scif_uart_interrupt(int irq, void *data, struct cpu_user_regs *regs) +static void scif_uart_interrupt(int irq, void *data) { struct serial_port *port = data; struct scif_uart *uart = port->uart; --- a/xen/drivers/passthrough/amd/iommu_init.c +++ b/xen/drivers/passthrough/amd/iommu_init.c @@ -XXX,XX +XXX,XX @@ static void cf_check do_amd_iommu_irq(vo static DECLARE_SOFTIRQ_TASKLET(amd_iommu_irq_tasklet, do_amd_iommu_irq, NULL); -static void cf_check iommu_interrupt_handler( - int irq, void *dev_id, struct cpu_user_regs *regs) +static void cf_check iommu_interrupt_handler(int irq, void *dev_id) { unsigned long flags; struct amd_iommu *iommu = dev_id; --- a/xen/drivers/passthrough/arm/ipmmu-vmsa.c +++ b/xen/drivers/passthrough/arm/ipmmu-vmsa.c @@ -XXX,XX +XXX,XX @@ static void ipmmu_domain_irq(struct ipmm domain->d, status, iova); } -static void ipmmu_irq(int irq, void *dev, struct cpu_user_regs *regs) +static void ipmmu_irq(int irq, void *dev) { struct ipmmu_vmsa_device *mmu = dev; unsigned int i; --- a/xen/drivers/passthrough/arm/smmu.c +++ b/xen/drivers/passthrough/arm/smmu.c @@ -XXX,XX +XXX,XX @@ static irqreturn_t arm_smmu_global_fault } /* Xen: Interrupt handlers wrapper */ -static void arm_smmu_context_fault_xen(int irq, void *dev, - struct cpu_user_regs *regs) +static void arm_smmu_context_fault_xen(int irq, void *dev) { arm_smmu_context_fault(irq, dev); } #define arm_smmu_context_fault arm_smmu_context_fault_xen -static void arm_smmu_global_fault_xen(int irq, void *dev, - struct cpu_user_regs *regs) +static void arm_smmu_global_fault_xen(int irq, void *dev) { arm_smmu_global_fault(irq, dev); } --- a/xen/drivers/passthrough/arm/smmu-v3.c +++ b/xen/drivers/passthrough/arm/smmu-v3.c @@ -XXX,XX +XXX,XX @@ static void arm_smmu_priq_tasklet(void * static int arm_smmu_device_disable(struct arm_smmu_device *smmu); -static void arm_smmu_gerror_handler(int irq, void *dev, - struct cpu_user_regs *regs) +static void arm_smmu_gerror_handler(int irq, void *dev) { u32 gerror, gerrorn, active; struct arm_smmu_device *smmu = dev; @@ -XXX,XX +XXX,XX @@ static void arm_smmu_gerror_handler(int writel(gerror, smmu->base + ARM_SMMU_GERRORN); } -static void arm_smmu_combined_irq_handler(int irq, void *dev, - struct cpu_user_regs *regs) +static void arm_smmu_combined_irq_handler(int irq, void *dev) { struct arm_smmu_device *smmu = dev; - arm_smmu_gerror_handler(irq, dev, regs); + arm_smmu_gerror_handler(irq, dev); tasklet_schedule(&(smmu->combined_irq_tasklet)); } @@ -XXX,XX +XXX,XX @@ static void arm_smmu_combined_irq_taskle arm_smmu_priq_tasklet(dev); } -static void arm_smmu_evtq_irq_tasklet(int irq, void *dev, - struct cpu_user_regs *regs) +static void arm_smmu_evtq_irq_tasklet(int irq, void *dev) { struct arm_smmu_device *smmu = dev; tasklet_schedule(&(smmu->evtq_irq_tasklet)); } -static void arm_smmu_priq_irq_tasklet(int irq, void *dev, - struct cpu_user_regs *regs) +static void arm_smmu_priq_irq_tasklet(int irq, void *dev) { struct arm_smmu_device *smmu = dev; --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -XXX,XX +XXX,XX @@ static void cf_check do_iommu_page_fault __do_iommu_page_fault(drhd->iommu); } -static void cf_check iommu_page_fault( - int irq, void *dev_id, struct cpu_user_regs *regs) +static void cf_check iommu_page_fault(int irq, void *dev_id) { /* * Just flag the tasklet as runnable. This is fine, according to VT-d --- a/xen/include/xen/irq.h +++ b/xen/include/xen/irq.h @@ -XXX,XX +XXX,XX @@ ASSERT(!in_irq() && (local_irq_is_enabled() || num_online_cpus() <= 1)) struct irqaction { - void (*handler)(int irq, void *dev_id, struct cpu_user_regs *regs); + void (*handler)(int irq, void *dev_id); const char *name; void *dev_id; bool free_on_release; @@ -XXX,XX +XXX,XX @@ extern int setup_irq(unsigned int irq, u struct irqaction *new); extern void release_irq(unsigned int irq, const void *dev_id); extern int request_irq(unsigned int irq, unsigned int irqflags, - void (*handler)(int irq, void *dev_id, - struct cpu_user_regs *regs), + void (*handler)(int irq, void *dev_id), const char *devname, void *dev_id); extern hw_irq_controller no_irq_type; -void cf_check no_action(int cpl, void *dev_id, struct cpu_user_regs *regs); +void cf_check no_action(int cpl, void *dev_id); unsigned int cf_check irq_startup_none(struct irq_desc *desc); void cf_check irq_actor_none(struct irq_desc *desc); #define irq_shutdown_none irq_actor_none
The only place it was needed is in the spurious handler, and there we can use get_irq_regs() instead. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -XXX,XX +XXX,XX @@ int reprogram_timer(s_time_t timeout) return apic_tmict || !timeout; } -static void cf_check apic_timer_interrupt(struct cpu_user_regs *regs) +static void cf_check apic_timer_interrupt(void) { ack_APIC_irq(); perfc_incr(apic_timer); @@ -XXX,XX +XXX,XX @@ void smp_send_state_dump(unsigned int cp /* * Spurious interrupts should _never_ happen with our APIC/SMP architecture. */ -static void cf_check spurious_interrupt(struct cpu_user_regs *regs) +static void cf_check spurious_interrupt(void) { /* * Check if this is a vectored interrupt (most likely, as this is probably @@ -XXX,XX +XXX,XX @@ static void cf_check spurious_interrupt( is_spurious = !nmi_check_continuation(); if (this_cpu(state_dump_pending)) { this_cpu(state_dump_pending) = false; - dump_execstate(regs); + dump_execstate(get_irq_regs()); is_spurious = false; } @@ -XXX,XX +XXX,XX @@ static void cf_check spurious_interrupt( * This interrupt should never happen with our APIC/SMP architecture */ -static void cf_check error_interrupt(struct cpu_user_regs *regs) +static void cf_check error_interrupt(void) { static const char *const esr_fields[] = { ", Send CS error", @@ -XXX,XX +XXX,XX @@ static void cf_check error_interrupt(str * This interrupt handles performance counters interrupt */ -static void cf_check pmu_interrupt(struct cpu_user_regs *regs) +static void cf_check pmu_interrupt(void) { ack_APIC_irq(); vpmu_do_interrupt(); --- a/xen/arch/x86/cpu/mcheck/mce_intel.c +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c @@ -XXX,XX +XXX,XX @@ bool __read_mostly lmce_support; #define MCE_RING 0x1 static DEFINE_PER_CPU(int, last_state); -static void cf_check intel_thermal_interrupt(struct cpu_user_regs *regs) +static void cf_check intel_thermal_interrupt(void) { uint64_t msr_content; unsigned int cpu = smp_processor_id(); @@ -XXX,XX +XXX,XX @@ static void cpu_mcheck_disable(void) clear_cmci(); } -static void cf_check cmci_interrupt(struct cpu_user_regs *regs) +static void cf_check cmci_interrupt(void) { mctelem_cookie_t mctc; struct mca_summary bs; --- a/xen/arch/x86/guest/xen/xen.c +++ b/xen/arch/x86/guest/xen/xen.c @@ -XXX,XX +XXX,XX @@ static void __init init_memmap(void) } } -static void cf_check xen_evtchn_upcall(struct cpu_user_regs *regs) +static void cf_check xen_evtchn_upcall(void) { struct vcpu_info *vcpu_info = this_cpu(vcpu_info); unsigned long pending; --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -XXX,XX +XXX,XX @@ static struct hvm_function_table __initd }; /* Handle VT-d posted-interrupt when VCPU is blocked. */ -static void cf_check pi_wakeup_interrupt(struct cpu_user_regs *regs) +static void cf_check pi_wakeup_interrupt(void) { struct vmx_vcpu *vmx, *tmp; spinlock_t *lock = &per_cpu(vmx_pi_blocking, smp_processor_id()).lock; @@ -XXX,XX +XXX,XX @@ static void cf_check pi_wakeup_interrupt } /* Handle VT-d posted-interrupt when VCPU is running. */ -static void cf_check pi_notification_interrupt(struct cpu_user_regs *regs) +static void cf_check pi_notification_interrupt(void) { ack_APIC_irq(); this_cpu(irq_count)++; --- a/xen/arch/x86/include/asm/irq.h +++ b/xen/arch/x86/include/asm/irq.h @@ -XXX,XX +XXX,XX @@ extern int opt_irq_vector_map; #define platform_legacy_irq(irq) ((irq) < 16) -void cf_check event_check_interrupt(struct cpu_user_regs *regs); -void cf_check invalidate_interrupt(struct cpu_user_regs *regs); -void cf_check call_function_interrupt(struct cpu_user_regs *regs); -void cf_check irq_move_cleanup_interrupt(struct cpu_user_regs *regs); +void cf_check event_check_interrupt(void); +void cf_check invalidate_interrupt(void); +void cf_check call_function_interrupt(void); +void cf_check irq_move_cleanup_interrupt(void); uint8_t alloc_hipriority_vector(void); -void set_direct_apic_vector( - uint8_t vector, void (*handler)(struct cpu_user_regs *regs)); -void alloc_direct_apic_vector( - uint8_t *vector, void (*handler)(struct cpu_user_regs *regs)); +void set_direct_apic_vector(uint8_t vector, void (*handler)(void)); +void alloc_direct_apic_vector(uint8_t *vector, void (*handler)(void)); void do_IRQ(struct cpu_user_regs *regs); --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -XXX,XX +XXX,XX @@ void move_native_irq(struct irq_desc *de desc->handler->enable(desc); } -void cf_check irq_move_cleanup_interrupt(struct cpu_user_regs *regs) +void cf_check irq_move_cleanup_interrupt(void) { unsigned vector, me; @@ -XXX,XX +XXX,XX @@ uint8_t alloc_hipriority_vector(void) return next++; } -static void (*direct_apic_vector[X86_NR_VECTORS])(struct cpu_user_regs *regs); -void set_direct_apic_vector( - uint8_t vector, void (*handler)(struct cpu_user_regs *regs)) +static void (*direct_apic_vector[X86_NR_VECTORS])(void); +void set_direct_apic_vector(uint8_t vector, void (*handler)(void)) { BUG_ON(direct_apic_vector[vector] != NULL); direct_apic_vector[vector] = handler; } -void alloc_direct_apic_vector( - uint8_t *vector, void (*handler)(struct cpu_user_regs *regs)) +void alloc_direct_apic_vector(uint8_t *vector, void (*handler)(void)) { static DEFINE_SPINLOCK(lock); @@ -XXX,XX +XXX,XX @@ void do_IRQ(struct cpu_user_regs *regs) if ( irq < 0 ) { if ( direct_apic_vector[vector] ) - direct_apic_vector[vector](regs); + direct_apic_vector[vector](); else { const char *kind = ", LAPIC"; --- a/xen/arch/x86/smp.c +++ b/xen/arch/x86/smp.c @@ -XXX,XX +XXX,XX @@ static cpumask_t flush_cpumask; static const void *flush_va; static unsigned int flush_flags; -void cf_check invalidate_interrupt(struct cpu_user_regs *regs) +void cf_check invalidate_interrupt(void) { unsigned int flags = flush_flags; ack_APIC_irq(); @@ -XXX,XX +XXX,XX @@ void smp_send_nmi_allbutself(void) send_IPI_mask(&cpu_online_map, APIC_DM_NMI); } -void cf_check event_check_interrupt(struct cpu_user_regs *regs) +void cf_check event_check_interrupt(void) { ack_APIC_irq(); perfc_incr(ipis); this_cpu(irq_count)++; } -void cf_check call_function_interrupt(struct cpu_user_regs *regs) +void cf_check call_function_interrupt(void) { ack_APIC_irq(); perfc_incr(ipis);
The type not being used in do_bug_frame() is suspicious. Apparently that's solely because the type uses a pointer-to-const parameter, when so far run_in_exception_handler() wanted functions taking pointer- to-non-const. Expand use of const, in turn requiring common code's do_bug_frame() as well as [gs]et_irq_regs() to also gain const. This then brings the former function also closer to the common one, with Arm's use of vaddr_t remaining as a difference. While there also replace the bogus use of hard tabs in [gs]et_irq_regs() (I clearly didn't mean to put it in like this). Signed-off-by: Jan Beulich <jbeulich@suse.com> --- This is an alternative proposal to https://lists.xen.org/archives/html/xen-devel/2023-12/msg01385.html. --- v3: Retain / extend use of const. Make part of series. v2: [skipped] --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -XXX,XX +XXX,XX @@ void do_IRQ(struct cpu_user_regs *regs, { struct irq_desc *desc = irq_to_desc(irq); struct irqaction *action; - struct cpu_user_regs *old_regs = set_irq_regs(regs); + const struct cpu_user_regs *old_regs = set_irq_regs(regs); perfc_incr(irqs); --- a/xen/arch/x86/include/asm/processor.h +++ b/xen/arch/x86/include/asm/processor.h @@ -XXX,XX +XXX,XX @@ static always_inline void rep_nop(void) void show_code(const struct cpu_user_regs *regs); void show_stack_overflow(unsigned int cpu, const struct cpu_user_regs *regs); void show_registers(const struct cpu_user_regs *regs); -#define dump_execution_state() \ - run_in_exception_handler(show_execution_state_nonconst) +#define dump_execution_state() run_in_exception_handler(show_execution_state) void show_page_walk(unsigned long addr); void noreturn fatal_trap(const struct cpu_user_regs *regs, bool show_remote); --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -XXX,XX +XXX,XX @@ void do_IRQ(struct cpu_user_regs *regs) struct irq_desc *desc; unsigned int vector = (uint8_t)regs->entry_vector; int irq = this_cpu(vector_irq)[vector]; - struct cpu_user_regs *old_regs = set_irq_regs(regs); + const struct cpu_user_regs *old_regs = set_irq_regs(regs); perfc_incr(irqs); this_cpu(irq_count)++; --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -XXX,XX +XXX,XX @@ void show_stack_overflow(unsigned int cp printk("\n"); } -void show_execution_state(const struct cpu_user_regs *regs) +void cf_check show_execution_state(const struct cpu_user_regs *regs) { /* Prevent interleaving of output. */ unsigned long flags = console_lock_recursive_irqsave(); @@ -XXX,XX +XXX,XX @@ void show_execution_state(const struct c console_unlock_recursive_irqrestore(flags); } -void cf_check show_execution_state_nonconst(struct cpu_user_regs *regs) -{ - show_execution_state(regs); -} - void vcpu_show_execution_state(struct vcpu *v) { unsigned long flags = 0; --- a/xen/common/bug.c +++ b/xen/common/bug.c @@ -XXX,XX +XXX,XX @@ * Returns a negative value in case of an error otherwise * BUGFRAME_{run_fn, warn, bug, assert} */ -int do_bug_frame(struct cpu_user_regs *regs, unsigned long pc) +int do_bug_frame(const struct cpu_user_regs *regs, unsigned long pc) { const struct bug_frame *bug = NULL; const struct virtual_region *region; @@ -XXX,XX +XXX,XX @@ int do_bug_frame(struct cpu_user_regs *r if ( id == BUGFRAME_run_fn ) { - void (*fn)(struct cpu_user_regs *) = bug_ptr(bug); + bug_fn_t *fn = bug_ptr(bug); fn(regs); - /* Re-enforce consistent types, because of the casts involved. */ - if ( false ) - run_in_exception_handler(fn); - return id; } --- a/xen/common/irq.c +++ b/xen/common/irq.c @@ -XXX,XX +XXX,XX @@ #include <xen/irq.h> #include <xen/errno.h> -DEFINE_PER_CPU(struct cpu_user_regs *, irq_regs); +DEFINE_PER_CPU(const struct cpu_user_regs *, irq_regs); int init_one_irq_desc(struct irq_desc *desc) { --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -XXX,XX +XXX,XX @@ static void cf_check show_handlers(unsig static cpumask_t dump_execstate_mask; -void cf_check dump_execstate(struct cpu_user_regs *regs) +void cf_check dump_execstate(const struct cpu_user_regs *regs) { unsigned int cpu = smp_processor_id(); --- a/xen/drivers/char/ehci-dbgp.c +++ b/xen/drivers/char/ehci-dbgp.c @@ -XXX,XX +XXX,XX @@ static int cf_check ehci_dbgp_getc(struc /* Safe: ehci_dbgp_poll() runs as timer handler, so not reentrant. */ static struct serial_port *poll_port; -static void cf_check _ehci_dbgp_poll(struct cpu_user_regs *regs) +static void cf_check _ehci_dbgp_poll(const struct cpu_user_regs *regs) { struct serial_port *port = poll_port; struct ehci_dbgp *dbgp = port->uart; unsigned long flags; unsigned int timeout = MICROSECS(DBGP_CHECK_INTERVAL); bool empty = false; - struct cpu_user_regs *old_regs; + const struct cpu_user_regs *old_regs; if ( !dbgp->ehci_debug ) return; --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -XXX,XX +XXX,XX @@ static void cf_check ns16550_interrupt(i /* Safe: ns16550_poll() runs as softirq so not reentrant on a given CPU. */ static DEFINE_PER_CPU(struct serial_port *, poll_port); -static void cf_check __ns16550_poll(struct cpu_user_regs *regs) +static void cf_check __ns16550_poll(const struct cpu_user_regs *regs) { struct serial_port *port = this_cpu(poll_port); struct ns16550 *uart = port->uart; - struct cpu_user_regs *old_regs; + const struct cpu_user_regs *old_regs; if ( uart->intr_works ) return; /* Interrupts work - no more polling */ --- a/xen/drivers/char/xhci-dbc.c +++ b/xen/drivers/char/xhci-dbc.c @@ -XXX,XX +XXX,XX @@ static void cf_check dbc_uart_poll(void struct dbc_uart *uart = port->uart; struct dbc *dbc = &uart->dbc; unsigned long flags = 0; - struct cpu_user_regs *old_regs; + const struct cpu_user_regs *old_regs; if ( spin_trylock_irqsave(&port->tx_lock, flags) ) { --- a/xen/include/xen/bug.h +++ b/xen/include/xen/bug.h @@ -XXX,XX +XXX,XX @@ typedef void bug_fn_t(const struct cpu_u #ifndef run_in_exception_handler -static void always_inline run_in_exception_handler( - void (*fn)(struct cpu_user_regs *regs)) +static void always_inline run_in_exception_handler(bug_fn_t *fn) { BUG_FRAME(BUGFRAME_run_fn, 0, fn, 0, NULL); } @@ -XXX,XX +XXX,XX @@ static void always_inline run_in_excepti * Returns a negative value in case of an error otherwise * BUGFRAME_{run_fn, warn, bug, assert} */ -int do_bug_frame(struct cpu_user_regs *regs, unsigned long pc); +int do_bug_frame(const struct cpu_user_regs *regs, unsigned long pc); #endif /* CONFIG_GENERIC_BUG_FRAME */ --- a/xen/include/xen/irq.h +++ b/xen/include/xen/irq.h @@ -XXX,XX +XXX,XX @@ void cf_check irq_actor_none(struct irq_ * Per-cpu interrupted context register state - the inner-most interrupt frame * on the stack. */ -DECLARE_PER_CPU(struct cpu_user_regs *, irq_regs); +DECLARE_PER_CPU(const struct cpu_user_regs *, irq_regs); -static inline struct cpu_user_regs *get_irq_regs(void) +static inline const struct cpu_user_regs *get_irq_regs(void) { - return this_cpu(irq_regs); + return this_cpu(irq_regs); } -static inline struct cpu_user_regs *set_irq_regs(struct cpu_user_regs *new_regs) +static inline const struct cpu_user_regs *set_irq_regs( + const struct cpu_user_regs *new_regs) { - struct cpu_user_regs *old_regs, **pp_regs = &this_cpu(irq_regs); + const struct cpu_user_regs *old_regs, **pp_regs = &this_cpu(irq_regs); - old_regs = *pp_regs; - *pp_regs = new_regs; + old_regs = *pp_regs; + *pp_regs = new_regs; - return old_regs; + return old_regs; } struct domain; --- a/xen/include/xen/kernel.h +++ b/xen/include/xen/kernel.h @@ -XXX,XX +XXX,XX @@ extern const unsigned int xen_config_dat struct cpu_user_regs; struct vcpu; -void show_execution_state(const struct cpu_user_regs *regs); -void cf_check show_execution_state_nonconst(struct cpu_user_regs *regs); +void cf_check show_execution_state(const struct cpu_user_regs *regs); void vcpu_show_execution_state(struct vcpu *v); #endif /* _LINUX_KERNEL_H */ --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -XXX,XX +XXX,XX @@ extern char *print_tainted(char *str); extern void add_taint(unsigned int taint); struct cpu_user_regs; -void cf_check dump_execstate(struct cpu_user_regs *regs); +void cf_check dump_execstate(const struct cpu_user_regs *regs); void init_constructors(void);