-
Notifications
You must be signed in to change notification settings - Fork 1
/
answers-lab3.txt
56 lines (48 loc) · 2.78 KB
/
answers-lab3.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Problem 1:
The feature that we get with individual handler functions is being able to
retrieve the trap number and have a common handling function trap() for all
traps.
The processor does not pass any information about which interrupt number
triggered calling the handler. By having a different handler for each one,
we can hard-code the values and place them in a location so that we can
have a common handler function that switches on that value.
Problem 2:
Nothing special needed to be done other than having a handler for interrupts
13 and 14.
Calling int $14 is disallowed at CPL 3 since the DPL for gate 14 is 0.
This generates a general protection fault, which uses gate 13.
If the kernel allowed int $14 to work, then user programs could trigger
arbitrary page faults and potentially destabilize the system.
Problem 3:
The gate needs to be set up with a DPL of 3 so that it can be called from
user mode. The processor generates a GP fault when breakpoint is called
without this change because it sees a user-mode program (with CPL=3) trying
to trigger an interrupt with DPL=0. Changing the DPL to 3 fixes this problem.
Problem 4:
The point of these mechanisms is to prevent user-mode programs from triggering
privileged interrupts as a protection from both incorrect and malicious
programs. An incorrect or malicious program could trigger interrupts to
destabilize the system or send malicious data to the kernel. The TSS
also helps with this by ensuring that user stacks with potentially
incorrect or malicious data are not used for serving interrupts.
CHALLENGE:
I did the sysenter/sysexit challenge. There were three main modifications
that were required:
First, trap_init was modified to initialize the MSR so that sysenter knows
where to enter. It only does this, however, if the cpu has that feature
according to cpuid feature flags.
Second, syscall in lib/syscall.c was modified to check if we want to
use sysenter rather than int $0x30. It first checks to see if the cpu
has that feature before it attempts to use it. It then switches
on the trap number to see if it prefers sysenter over int $0x30. This
means that syscalls need to explicitly be set to use sysenter over the
normal syscall trap. If the syscall is in that list, it then calls
do_fast_call to do the call. do_fast_call uses inline assembly to
move the arguments into registers along with information about how to
get back and then calls sysenter. This allows all each syscall that
supports it to call sysenter.
Third, a new function in trapentry.S was created called sysenter_handler.
This is the defined entry point in the MSR from before. This function
simply pushes the arguments for syscall and calls that function. When
syscall returns, it sets up registers for the return and calls sysexit
to go back to user-space with the return value in eax.