diff options
author | Markus Metzger <markus.t.metzger@intel.com> | 2009-04-03 10:43:51 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-07 07:36:35 -0400 |
commit | 150f5164c1258e05b7dea16f29e592f354c48f34 (patch) | |
tree | 5b90728e0bc23182ae1a152d9cb8ff4e9e819afa /arch | |
parent | 608780a9048efa3e85fbc4d8649b26805cc588aa (diff) |
x86, ds: allow small debug store buffers
Check the buffer size more precisely to allow buffers for exactly
one element provided the base address is already properly aligned.
Add a debug store selftest.
Reported-by: Stephane Eranian <eranian@googlemail.com>
Signed-off-by: Markus Metzger <markus.t.metzger@intel.com>
Cc: roland@redhat.com
Cc: eranian@googlemail.com
Cc: oleg@redhat.com
Cc: juan.villacis@intel.com
Cc: ak@linux.jf.intel.com
LKML-Reference: <20090403144606.139137000@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/ds.c | 9 | ||||
-rw-r--r-- | arch/x86/kernel/ds_selftest.c | 6 |
2 files changed, 10 insertions, 5 deletions
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c index ebfb0fde8e6f..4e05157506aa 100644 --- a/arch/x86/kernel/ds.c +++ b/arch/x86/kernel/ds.c | |||
@@ -656,6 +656,7 @@ static int ds_request(struct ds_tracer *tracer, struct ds_trace *trace, | |||
656 | { | 656 | { |
657 | struct ds_context *context; | 657 | struct ds_context *context; |
658 | int error; | 658 | int error; |
659 | size_t req_size; | ||
659 | 660 | ||
660 | error = -EOPNOTSUPP; | 661 | error = -EOPNOTSUPP; |
661 | if (!ds_cfg.sizeof_rec[qual]) | 662 | if (!ds_cfg.sizeof_rec[qual]) |
@@ -665,9 +666,13 @@ static int ds_request(struct ds_tracer *tracer, struct ds_trace *trace, | |||
665 | if (!base) | 666 | if (!base) |
666 | goto out; | 667 | goto out; |
667 | 668 | ||
668 | /* We need space for alignment adjustments in ds_init_ds_trace(). */ | 669 | req_size = ds_cfg.sizeof_rec[qual]; |
670 | /* We might need space for alignment adjustments. */ | ||
671 | if (!IS_ALIGNED((unsigned long)base, DS_ALIGNMENT)) | ||
672 | req_size += DS_ALIGNMENT; | ||
673 | |||
669 | error = -EINVAL; | 674 | error = -EINVAL; |
670 | if (size < (DS_ALIGNMENT + ds_cfg.sizeof_rec[qual])) | 675 | if (size < req_size) |
671 | goto out; | 676 | goto out; |
672 | 677 | ||
673 | if (th != (size_t)-1) { | 678 | if (th != (size_t)-1) { |
diff --git a/arch/x86/kernel/ds_selftest.c b/arch/x86/kernel/ds_selftest.c index a40b2533c71e..5f104a0ace66 100644 --- a/arch/x86/kernel/ds_selftest.c +++ b/arch/x86/kernel/ds_selftest.c | |||
@@ -16,8 +16,8 @@ | |||
16 | #include <asm/ds.h> | 16 | #include <asm/ds.h> |
17 | 17 | ||
18 | 18 | ||
19 | #define BUFFER_SIZE 521 /* Intentionally chose an odd size. */ | 19 | #define BUFFER_SIZE 521 /* Intentionally chose an odd size. */ |
20 | 20 | #define SMALL_BUFFER_SIZE 24 /* A single bts entry. */ | |
21 | 21 | ||
22 | struct ds_selftest_bts_conf { | 22 | struct ds_selftest_bts_conf { |
23 | struct bts_tracer *tracer; | 23 | struct bts_tracer *tracer; |
@@ -381,7 +381,7 @@ int ds_selftest_bts(void) | |||
381 | conf.suspend = ds_suspend_bts_noirq; | 381 | conf.suspend = ds_suspend_bts_noirq; |
382 | conf.resume = ds_resume_bts_noirq; | 382 | conf.resume = ds_resume_bts_noirq; |
383 | conf.tracer = | 383 | conf.tracer = |
384 | ds_request_bts_task(current, buffer, BUFFER_SIZE, | 384 | ds_request_bts_task(current, buffer, SMALL_BUFFER_SIZE, |
385 | NULL, (size_t)-1, BTS_KERNEL); | 385 | NULL, (size_t)-1, BTS_KERNEL); |
386 | local_irq_save(irq); | 386 | local_irq_save(irq); |
387 | ds_selftest_bts_cpu(&conf); | 387 | ds_selftest_bts_cpu(&conf); |