Re: [PATCH] kdb: add rdmsr and wrmsr commands for i386

Mitch Bradley <[email protected]>
Newsgroups gmane.linux.laptop.olpc.devel,gmane.linux.kernel.debugging
Message-ID <[email protected]>

Bernardo Innocenti wrote:
> The syntax is:
>    rdmsr <addr>
>    wrmsr <addr> <l> <h>
>   

In the hardware documentation that I have seen, MSR values are 
conventionally shown as 64-bit numbers.  The <l> <h> ordering will make 
it necessary to do a mental flip.  The 32-bit pieces of MSR do not have 
individual addresses, so considerations of endianness are not directly 
relevant.

> Signed-off-by: Bernardo Innocenti <[email protected]>
>
>
> diff --git a/arch/i386/kdb/kdbasupport.c b/arch/i386/kdb/kdbasupport.c
> index 482b319..8ecef2e 100644
> --- a/arch/i386/kdb/kdbasupport.c
> +++ b/arch/i386/kdb/kdbasupport.c
> @@ -223,6 +223,47 @@ kdba_removedbreg(kdb_bp_t *bp)
>   	kdba_putdr7(dr7);
>   }
>
> +static int
> +kdba_rdmsr(int argc, const char **argv)
> +{
> +	unsigned long addr;
> +	uint64_t val;
> +	int diag;
> +
> +	if (argc != 1) {
> +		return KDB_ARGCOUNT;
> +	}
> +
> +	if ((diag = kdbgetularg(argv[1], &addr)))
> +		return diag;
> +
> +	kdb_printf("msr(0x%lx) = ", addr);
> +	rdmsrl(addr, val);
> +	kdb_printf("0x%llx\n", val);
> +
> +	return 0;
> +}
> +
> +static int
> +kdba_wrmsr(int argc, const char **argv)
> +{
> +	unsigned long addr;
> +	unsigned long l, h;
> +	int diag;
> +
> +	if (argc != 3)
> +		return KDB_ARGCOUNT;
> +
> +	if ((diag = kdbgetularg(argv[1], &addr))
> +			|| (diag = kdbgetularg(argv[2], &l))
> +			|| (diag = kdbgetularg(argv[3], &h)))
> +		return diag;
> +
> +	wrmsr(addr, l, h);
> +
> +	return 0;
> +}
> +
>
>   /*
>    * kdba_getregcontents
> @@ -474,12 +515,11 @@ kdba_setregcontents(const char *regname,
>    *	argument is NULL (struct pt_regs).   The alternate register
>    *	set types supported by this function:
>    *
> - *	d 		Debug registers
> + *	d		Debug registers
>    *	c		Control registers
>    *	u		User registers at most recent entry to kernel
>    *			for the process currently selected with "pid" command.
>    * Following not yet implemented:
> - *	m		Model Specific Registers (extra defines register #)
>    *	r		Memory Type Range Registers (extra defines register)
>    */
>
> @@ -546,8 +586,6 @@ kdba_dumpregs(struct pt_regs *regs,
>   			   cr[0], cr[1], cr[2], cr[3], cr[4]);
>   		return 0;
>   	}
> -	case 'm':
> -		break;
>   	case 'r':
>   		break;
>   	default:
> @@ -899,6 +937,9 @@ kdba_init(void)
>   {
>   	kdb_register("pt_regs", kdba_pt_regs, "address", "Format struct 
> pt_regs", 0);
>   	kdb_register("stackdepth", kdba_stackdepth, "[percentage]", "Print 
> processes using >= stack percentage", 0);
> +	//TODO: maybe check CPUID first
> +	kdb_register("rdmsr", kdba_rdmsr, "<maddr>", "Display Model Specific 
> Register", 0);
> +	kdb_register("wrmsr", kdba_wrmsr, "<maddr> <l> <h>", "Modify Model 
> Specific Register", 0);
>
>   	return;
>   }
> diff --git a/kdb/kdbmain.c b/kdb/kdbmain.c
> index 0b2cb91..88bf14f 100644
> --- a/kdb/kdbmain.c
> +++ b/kdb/kdbmain.c
> @@ -2596,8 +2596,7 @@ kdb_rd(int argc, const char **argv)
>    *	none.
>    * Remarks:
>    *	Currently doesn't allow modification of control or
> - *	debug registers, nor does it allow modification
> - *	of model-specific registers (MSR).
> + *	debug registers.
>    */
>
>   static int
>
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.