All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
To: Ingo Molnar <mingo@elte.hu>
Cc: Christoph Hellwig <hch@infradead.org>,
	linux-kernel@vger.kernel.org,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Andrew Morton <akpm@zip.com.au>,
	Thomas Gleixner <tglx@linutronix.de>,
	Jason Wessel <jason.wessel@windriver.com>
Subject: Re: [patch] kgdb light, v6
Date: Sun, 10 Feb 2008 21:55:46 +0100	[thread overview]
Message-ID: <200802102155.46505.bzolnier@gmail.com> (raw)
In-Reply-To: <20080210171742.GF7088@elte.hu>


few minor issues (some may have been addressed already)

On Sunday 10 February 2008, Ingo Molnar wrote:

[...]

> diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
> new file mode 100644
> index 0000000..7130273
> --- /dev/null
> +++ b/arch/x86/kernel/kgdb.c

[...]

> +static struct hw_breakpoint {
> +	unsigned		enabled;
> +	unsigned		type;
> +	unsigned		len;
> +	unsigned long		addr;
> +} breakinfo[4] = {
> +	{ .enabled = 0 },
> +	{ .enabled = 0 },
> +	{ .enabled = 0 },
> +	{ .enabled = 0 },
> +};

is this initialization really needed?  the whole thing is static anyway

> +static void kgdb_correct_hw_break(void)
> +{
> +	unsigned long dr7;
> +	int correctit = 0;
> +	int breakbit;
> +	int breakno;
> +
> +	get_debugreg(dr7, 7);
> +	for (breakno = 0; breakno < 4; breakno++) {
> +		breakbit = 2 << (breakno << 1);
> +		if (!(dr7 & breakbit) && breakinfo[breakno].enabled) {
> +			correctit = 1;
> +			dr7 |= breakbit;
> +			dr7 &= ~(0xf0000 << (breakno << 2));
> +			dr7 |= ((breakinfo[breakno].len << 2) |
> +				 breakinfo[breakno].type) <<
> +			       ((breakno << 2) + 16);
> +			switch (breakno) {
> +			case 0:
> +				set_debugreg(breakinfo[0].addr, 0);
> +				break;
> +
> +			case 1:
> +				set_debugreg(breakinfo[1].addr, 1);
> +				break;
> +
> +			case 2:
> +				set_debugreg(breakinfo[2].addr, 2);
> +				break;
> +
> +			case 3:
> +				set_debugreg(breakinfo[3].addr, 3);
> +				break;

			if (breakno >= 0 && breakno <= 3)
				set_debugreg(breakinfo[breakno].addr, breakno);

[...]

> +/**
> + *	kgdb_arch_init - Perform any architecture specific initalization.
> + *
> + *	This function will handle the initalization of any architecture
> + *	specific callbacks.
> + */
> +int kgdb_arch_init(void)
> +{
> +	register_die_notifier(&kgdb_notifier);
> +	return 0;

return register_die_notifier();

[...]

> diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
> new file mode 100644
> index 0000000..a5d2d00
> --- /dev/null
> +++ b/drivers/serial/kgdboc.c

[...]

> +MODULE_DESCRIPTION("KGDB Console TTY Driver");
> +MODULE_LICENSE("GPL");

should be at the bottom of the file

> +static char config[MAX_KGDB_SERIAL_CONSOLE_CONFIG_STR];
> +static struct kparam_string kps = {
> +	.string			= config,
> +	.maxlen			= MAX_KGDB_SERIAL_CONSOLE_CONFIG_STR,
> +};
> +
> +static struct tty_driver	*kgdb_tty_driver;
> +static int			kgdb_tty_line;
> +
> +static int kgdboc_option_setup(char *opt)

__init

> +{
> +	if (strlen(opt) > MAX_KGDB_SERIAL_CONSOLE_CONFIG_STR) {
> +		printk(KERN_ERR "kgdboc: config string too long\n");
> +		return -ENOSPC;
> +	}
> +	strcpy(config, opt);
> +
> +	return 0;
> +}
> +__setup("kgdboc=", kgdboc_option_setup);

no need for obsolete __setup, we have module_param_call() below

> +static int configure_kgdboc(void)

__init

> +{
> +	struct tty_driver *p;
> +	int tty_line = 0;
> +	int err;
> +
> +	err = kgdboc_option_setup(config);
> +	if (err || !strlen(config) || isspace(config[0]))
> +		goto noconfig;
> +
> +	err = -ENODEV;
> +
> +	p = tty_find_polling_driver(config, &tty_line);
> +	if (!p)
> +		goto noconfig;
> +
> +	kgdb_tty_driver = p;
> +	kgdb_tty_line = tty_line;
> +
> +	err = kgdb_register_io_module(&kgdboc_io_ops);
> +	if (err)
> +		goto noconfig;
> +
> +	configured = 1;
> +
> +	return 0;
> +
> +noconfig:
> +	config[0] = 0;
> +	configured = 0;
> +
> +	return err;
> +}
> +
> +static int init_kgdboc(void)

__init

> +{
> +	/* Already configured? */
> +	if (configured == 1)
> +		return 0;
> +
> +	return configure_kgdboc();
> +}
> +
> +static void cleanup_kgdboc(void)

I would suggest __exit but it can be called from param_set_kgdboc_var()

[ I have a feeling that somethings is wrong with this but I'm too lazy
  to read the code in depth... ]

> diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
> index 0f5a179..a72116a 100644
> --- a/drivers/serial/serial_core.c
> +++ b/drivers/serial/serial_core.c

[...]

> +#ifdef CONFIG_CONSOLE_POLL
> +

unnecessary new line

[...]

> diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h
> new file mode 100644
> index 0000000..7f4ee55
> --- /dev/null
> +++ b/include/linux/kgdb.h
> @@ -0,0 +1,329 @@

[...]

> +/* The maximum number of KGDB I/O modules that can be loaded */
> +#define KGDB_MAX_IO_HANDLERS	3

unused

> +#ifndef KGDB_MAX_BREAKPOINTS
> +# define KGDB_MAX_BREAKPOINTS	1000
> +#endif
> +
> +#define KGDB_HW_BREAKPOINT	1

unused

[...]

> +/*
> + * struct kgdb_io - Describe the interface for an I/O driver to talk with KGDB.
> + * @name: Name of the I/O driver.
> + * @read_char: Pointer to a function that will return one char.
> + * @write_char: Pointer to a function that will write one char.
> + * @flush: Pointer to a function that will flush any pending writes.
> + * @init: Pointer to a function that will initialize the device.
> + * @late_init: Pointer to a function that will do any setup that has

there is no late_init in the structure

> + * other dependencies.
> + * @pre_exception: Pointer to a function that will do any prep work for
> + * the I/O driver.
> + * @post_exception: Pointer to a function that will do any cleanup work
> + * for the I/O driver.
> + *
> + * The @init and @late_init function pointers allow for an I/O driver
> + * such as a serial driver to fully initialize the port with @init and
> + * be called very early, yet safely call request_irq() later in the boot
> + * sequence.
> + *
> + * @init is allowed to return a non-0 return value to indicate failure.
> + * If this is called early on, then KGDB will try again when it would call
> + * @late_init.  If it has failed later in boot as well, the user will be
> + * notified.
> + */
> +struct kgdb_io {
> +	const char		*name;
> +	int			(*read_char) (void);
> +	void			(*write_char) (u8);
> +	void			(*flush) (void);
> +	int			(*init) (void);
> +	void			(*pre_exception) (void);
> +	void			(*post_exception) (void);
> +};

[...]

> diff --git a/kernel/kgdb.c b/kernel/kgdb.c
> new file mode 100644
> index 0000000..b5dd949
> --- /dev/null
> +++ b/kernel/kgdb.c

[...]

> +/*
> + * SW breakpoint management:
> + */
> +static int kgdb_activate_sw_breakpoints(void)
> +{
> +	unsigned long addr;
> +	int error = 0;
> +	int i;
> +
> +	for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
> +		if (kgdb_break[i].state != BP_SET)
> +			continue;
> +
> +		addr = kgdb_break[i].bpt_addr;
> +		error = kgdb_arch_set_breakpoint(addr,
> +				kgdb_break[i].saved_instr);
> +		if (error)
> +			return error;
> +
> +		if (CACHE_FLUSH_IS_SAFE) {
> +			if (current->mm && addr < TASK_SIZE) {
> +				flush_cache_range(current->mm->mmap_cache,
> +						addr, addr + BREAK_INSTR_SIZE);
> +			} else {
> +				flush_icache_range(addr, addr +
> +						BREAK_INSTR_SIZE);
> +			}
> +		}

identical cache flushing code is present in
kgdb_deactivate_sw_breakpoints() below

maybe it would make sense to have some common helper

> +		kgdb_break[i].state = BP_ACTIVE;
> +	}
> +	return 0;
> +}
> +
> +static int kgdb_set_sw_break(unsigned long addr)
> +{
> +	int error = kgdb_validate_break_address(addr);
> +	int breakno = -1;
> +	int i;
> +
> +	if (error < 0)
> +		return error;
> +
> +	for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
> +		if ((kgdb_break[i].state == BP_SET) &&
> +					(kgdb_break[i].bpt_addr == addr))
> +			return -EEXIST;
> +	}
> +	for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
> +		if (kgdb_break[i].state == BP_REMOVED &&
> +					kgdb_break[i].bpt_addr == addr) {
> +			breakno = i;
> +			break;
> +		}
> +	}

if kgdb_isremovedbreak() helper is moved before kgdb_set_sw_break()
and converted to return 'i' on success and '-1' on failure then it can
be used instead the above for () loop

> +
> +	if (breakno == -1) {
> +		for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
> +			if (kgdb_break[i].state == BP_UNDEFINED) {
> +				breakno = i;
> +				break;
> +			}
> +		}
> +	}
> +
> +	if (breakno == -1)
> +		return -E2BIG;
> +
> +	kgdb_break[breakno].state = BP_SET;
> +	kgdb_break[breakno].type = BP_BREAKPOINT;
> +	kgdb_break[breakno].bpt_addr = addr;
> +
> +	return 0;
> +}
> +
> +static int kgdb_deactivate_sw_breakpoints(void)
> +{
> +	unsigned long addr;
> +	int error = 0;
> +	int i;
> +
> +	for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
> +		if (kgdb_break[i].state != BP_ACTIVE)
> +			continue;
> +		addr = kgdb_break[i].bpt_addr;
> +		error = kgdb_arch_remove_breakpoint(addr,
> +					kgdb_break[i].saved_instr);
> +		if (error)
> +			return error;
> +
> +		if (CACHE_FLUSH_IS_SAFE && current->mm &&
> +				addr < TASK_SIZE) {
> +			flush_cache_range(current->mm->mmap_cache,
> +					addr, addr + BREAK_INSTR_SIZE);
> +		} else if (CACHE_FLUSH_IS_SAFE) {
> +			flush_icache_range(addr, addr + BREAK_INSTR_SIZE);
> +		}
> +		kgdb_break[i].state = BP_SET;
> +	}
> +	return 0;
> +}
> +
> +static int kgdb_remove_sw_break(unsigned long addr)
> +{
> +	int i;
> +
> +	for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
> +		if ((kgdb_break[i].state == BP_SET) &&
> +				(kgdb_break[i].bpt_addr == addr)) {
> +			kgdb_break[i].state = BP_REMOVED;

it would make a sense to have to have kgdb_isset() helper
to use here and in kgdb_set_sw_break()

> +			return 0;
> +		}
> +	}
> +	return -ENOENT;
> +}
> +
> +int kgdb_isremovedbreak(unsigned long addr)
> +{
> +	int i;
> +
> +	for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
> +		if ((kgdb_break[i].state == BP_REMOVED) &&
> +					(kgdb_break[i].bpt_addr == addr))
> +			return 1;
> +	}
> +	return 0;
> +}

Thanks,
Bart

  parent reply	other threads:[~2008-02-10 20:43 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-10  7:13 [3/6] kgdb: core Ingo Molnar
2008-02-10  7:31 ` Sam Ravnborg
2008-02-10  7:59   ` Ingo Molnar
2008-02-10  7:35 ` Christoph Hellwig
2008-02-10  7:43   ` Ingo Molnar
2008-02-10  7:57     ` Christoph Hellwig
2008-02-10  8:02       ` Ingo Molnar
2008-02-10  8:21         ` Ingo Molnar
2008-02-10  8:26           ` Christoph Hellwig
2008-02-10  9:08             ` Ingo Molnar
2008-02-10  9:17               ` Ingo Molnar
2008-02-10  9:20                 ` Ingo Molnar
2008-02-10  9:34                   ` Ingo Molnar
2008-02-10  9:31                 ` Christoph Hellwig
2008-02-10 17:17                   ` [patch] kgdb light, v6 Ingo Molnar
2008-02-10 19:43                     ` Bartlomiej Zolnierkiewicz
2008-02-10 21:31                       ` Ingo Molnar
2008-02-10 20:55                     ` Bartlomiej Zolnierkiewicz [this message]
2008-02-10 21:09                       ` Ingo Molnar
2008-02-10 21:45                         ` Jan Kiszka
2008-02-10 22:14                           ` Bartlomiej Zolnierkiewicz
2008-02-10 22:32                             ` Jan Kiszka
2008-02-10 22:40                               ` Ingo Molnar
2008-02-11  2:35                                 ` Yinghai Lu
2008-02-10 22:31                           ` Ingo Molnar
2008-02-10 22:24                         ` Bartlomiej Zolnierkiewicz
2008-02-10  8:24         ` [3/6] kgdb: core Christoph Hellwig
2008-02-10  8:57           ` Ingo Molnar
2008-02-10  9:11             ` Christoph Hellwig
2008-02-10  9:27               ` Ingo Molnar
2008-02-10  9:34                 ` Christoph Hellwig
2008-02-10 17:02                   ` Ingo Molnar
2008-02-10 12:46 ` Marcin Slusarz
2008-02-10 13:19   ` Jesper Juhl
2008-02-10 14:00     ` Marcin Slusarz
2008-02-10 13:36   ` Jan Kiszka
2008-02-10 16:43   ` Ingo Molnar
2008-02-10 19:20     ` Bartlomiej Zolnierkiewicz
2008-02-10 16:46   ` Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200802102155.46505.bzolnier@gmail.com \
    --to=bzolnier@gmail.com \
    --cc=akpm@zip.com.au \
    --cc=hch@infradead.org \
    --cc=jason.wessel@windriver.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.