lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20060826034610.12928.qmail@science.horizon.com>
Date:	25 Aug 2006 23:46:10 -0400
From:	linux@...izon.com
To:	johnstul@...ibm.com, linux@...izon.com
Cc:	linux-kernel@...r.kernel.org, theotso@...ibm.com,
	zippel@...ux-m68k.org
Subject: Re: Linux time code

If anyone's interesting in the Very Sneaky option, here's a little
test program to judge its feasibility.

You can do an even nicer thing with timer 2, the speaker timer, since
it keeps counting mod-65536 when not in use, but coping with console
beeps or the PC speaker driver would be a nightmare.

On 4 machines (laptop, two desktops, and amd64), timer 1 is always
programmed for mode 2 (status = 0x94) with a cout of 18 (0x12).  This
does not divide any of the standard timer rate divisors (including the
AMD Elan versions).  However, collecting hitograms, I do see occasional
glitches:

Timer 1 status = 94
  1: 34
  3: 133
  4: 34
  6: 132
  7: 33
  9: 133
 10: 33
 12: 134
 13: 33
 15: 134
 16: 33
 18: 133
181: 1

(AMD64, nForce4 chipset - why it has a "refresh timer" when it doesn't
have any RAM attached is a mystery)

Also, it appears to take very nearly 3 us to latch the
count and read the timer, resulting in histograms like:

Timer 1 status = 94
  1: 167
  4: 167
  7: 166
 10: 166
 13: 167
 16: 167

Anyway, if anyone else would like to try, the following program should
be very conservative and not kill your machine.  Still, it disables
interrupts and does raw hardware accesses.  In fact, since nobody else
should be touching timer 1, the interrupt disabling is probably not
necessary, but I'd still be cuatious running it on an SMP system.

/*
 * This program figures out what timer 1 (the memory refresh timer) is
 * doing on yor computer.
 */
#include <stdio.h>
#include <sys/io.h>	/* For iopl(), inb(), outb() */
#include <asm/system.h>	/* For local_irq_disable(), local_irq_enable() */
#include <stdint.h>
#include <assert.h>

/* Timer registers at 0x40..0x43 */

static uint8_t
get_status(unsigned timer)
{
	uint8_t status;

	assert(timer < 3);

	local_irq_disable();
	outb(0xe0 + (2<<timer), 0x43);
	status = inb(0x40 + timer);
	local_irq_enable();

	return status;
}

/*
 * We collect a histogram of values to find out the highest counter
 * value and look for oddities like skipped values.
 */
static void
get_histogram(unsigned timer, unsigned counts[256], unsigned n)
{
	uint8_t const command = 0xd0 + (2<<timer);
	/* Alt: command = timer << 6 */
	uint16_t const port = 0x40 + timer;

	assert(timer < 3);
	assert(n);

	local_irq_disable();
	do {
		outb(command, 0x43);
		counts[inb(port)]++;
	} while (--n);
	local_irq_enable();
}

int
main(void)
{
	unsigned i;
	unsigned histogram[256];
	uint8_t status;

	if (iopl(3) < 0) {
		perror("iopl(3)");
		fputs("Are you running as root?\n", stderr);
		return 1;
	}

	status = get_status(1);

	printf("Timer 1 status = %02x\n", status);

	if (status & 0x40) {
		puts("Null count it set.  This is strange and interesting,\n"
		     "but means I don't know what's going on.  Aborting.");
		return 0;
	}
	if ((status & 0x30) != 0x10) {
		puts("Read mode is not lsbyte-only.  This is strange and interesting,\n"
		     "but means I don't know what's going on.  Aborting.");
		     return 0;
	}
	if ((status & 0xe) != 4) {
		printf("Timer mode is %u, not 2, which is unexpected.  Still,\n"
		       "data can be collected.  Please report!",
		       (status >> 1) & 7);
	}
	if (status & 1) {
		puts("Timer is in BCD mode.  Most peculiar.  Please report!");
		/* But we can collect a histogram */
	}

	for (i = 0; i < 256; i++)
		histogram[i] = 0;

	/* Break up collection into bursts to avoid long interrupt latency */
	for (i = 0; i < 10; i++)
		get_histogram(1, histogram, 100);

	for (i = 0; i < 256; i++)
		if (histogram[i])
			printf("%3u: %u\n", i, histogram[i]);

	puts("Thank you.");
	return 0;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ