LINUX.ORG.RU

регистры fs и gs


0

0

Для чего в ядре Linux используются регистры fs и gs. Как правильно называются дескрипторы, на которые указывают селекторы загружаемые в эти регистры

#define GDT_ENTRY_PERCPU			(GDT_ENTRY_KERNEL_BASE + 15)
#ifdef CONFIG_SMP
#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
#else
#define __KERNEL_PERCPU 0
#endif
...
#define GDT_ENTRY_STACK_CANARY		(GDT_ENTRY_KERNEL_BASE + 16)
#ifdef CONFIG_CC_STACKPROTECTOR
#define __KERNEL_STACK_CANARY		(GDT_ENTRY_STACK_CANARY * 8)
#else
#define __KERNEL_STACK_CANARY		0
#endif

почему они используються только ядром, для юзерспейса нету аналогичных дескрипторов, также при выполнение инстпукцмм iret (в слечае понижение привилегий) регистры fs и gs обнуляются.

Почему при заполнении GDT дескриптор

[GDT_ENTRY_PERCPU]		= GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
аналогичен __KERNEL_DS а во время загрузки после отработки функции
static inline void setup_percpu_segment(int cpu)
{
#ifdef CONFIG_X86_32
	struct desc_struct gdt;

	pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
			0x2 | DESCTYPE_S, 0x8);
	gdt.s = 1;
	write_gdt_entry(get_cpu_gdt_table(cpu),
			GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
значение его base и limit модифицируються ? Почему ?

Инициализация дескриптора _KERNEL_STACK_CANARY, имеет еще более странные значения

#define GDT_STACK_CANARY_INIT						\
	[GDT_ENTRY_STACK_CANARY] = GDT_ENTRY_INIT(0x4090, 0, 0x18),
Суть которых еще большая загадка.

Почти не нашел не какой информации по этому вопросу. Надеюсь что хоть кто то сможет пролить свет на сею темную сторону

★

Linux использует сегментацию только когда это требует архитектура x86, больше она ему нафиг не нужна.

для юзерспейса нету аналогичных дескрипторов

man 2 modify_ldt

frey ★★
()

> Для чего в ядре Linux используются регистры fs и gs

с (относительно) недавнего времени fs или gs (в зависимости от X86_64)
используется для доступа к per_cpu данным.

насколько я знаю - больше ни для чего. ну, если не считать всякое
баловство типа apm_bios или stackprotector (x86_32).

еще раз, я говорю только про kernel. user-space может использовать
эти регистры тоже, поэтому kernel должен их сохранять/восстанавливать.

__KERNEL_STACK_CANARY

для юзерспейса нету аналогичных дескрипторов,



а зачем они для user-space ???

при выполнение инстпукцмм iret (в слечае понижение привилегий) регистры

fs и gs обнуляются.



хм. где вы такое увидели?

аналогичен __KERNEL_DS а во время загрузки после отработки функции

setup_percpu_segment(int cpu)


значение его base и limit модифицируються ?



потому, что каждому CPU нужен свой дескриптор, естественно. смотрите
внимательнее на setup_percpu_segment(), там меняется per_cpu(gdt_page).

#define GDT_STACK_CANARY_INIT

Суть которых еще большая загадка.



см жЫрный коммент в arch/x86/include/asm/stackprotector.h

idle ★★★★★
()
Ответ на: комментарий от idle

> при выполнение инстпукцмм iret (в слечае понижение привилегий) регистры

fs и gs обнуляются.

хм. где вы такое увидели?

Сначала на практике, в виде непонятной ошибки, потом в книжке при поиске причины, потом опять на практике после исправления ошибки :) (Бовети, Чезати)

> Для чего в ядре Linux используются регистры fs и gs

с (относительно) недавнего времени fs или gs (в зависимости от X86_64) используется для доступа к per_cpu данным.

насколько я знаю - больше ни для чего. ну, если не считать всякое

баловство типа apm_bios или stackprotector (x86_32).

забыл указать, что именно в ядре и именно в x86_32. Вот как раз это apm_bios или stackprotector :) Можно про них чуть поподробней ?

А что такое per_cpu данные ?

> #define GDT_STACK_CANARY_INIT

Суть которых еще большая загадка.

см жЫрный коммент в arch/x86/include/asm/stackprotector.h


Супер, спасибо.

Cupper ★
() автор топика
Вы не можете добавлять комментарии в эту тему: топик перемещен в архив.