So the next thing I want to talk about is the CPU virtualization. Now here again, what is happening is there is a physical resource here and the hypervisors managing it. But what we want to give is an illusion to each one of these operating systems that they own the CPU resources. They are scheduling the processes on top of physical CPU. In this case, I'm showing a single CPU could be multiple CPUs managed with the hypervisor to keep the discussion simple, let's think of this as having a single CPU that all of these guys are sharing. So this hypervisor is giving dibs on the CPU to different operating systems for different amounts of times so that they can schedule the processes that are running on each one of these operating systems under physical CPU that's managed by the hypervisor. So there are two parts to CPU virtualization. One is this illusion that I talked about, ownership of the CPU for each VM. Here you can have a proportional share approach, meaning that I'm going to say it's like a Round-robin scheduler that says that I am going to have a chunk of time that I'm going to give to this operating system. A chunk of time, I'm going to give to this operating system. During that chunk of time, this operating system is free to schedule the different processes that are running within it. Once that time is over, hypervisor gives it to a different operating system and so on, that is proportional to the SLAs that you've negotiated. So if this guy has negotiated a higher share, then you might give it a higher share. Fair share, on the other hand, says that I'm going to treat everybody equally. We've talked about the resource management policies when we discussed in one of the earlier lectures. So I don't have to harp on this some more, but the basic idea is how to virtualize the CPU so that you can give the illusion of ownership of the CPU for each virtual machine. The second part, which is common to both full and paravirtualization, is delivering events to a parent guest operating system. So when a particular process of a particular guest operating system is running on the processor, during that time there's nothing between the process and the bare metal. So it is running on the processor executing the program. No problem with that. But what could happen is you're going to have programmed discontinuities. While the program is running, this process can have discontinuities. The first thing that every processor is doing is address translation, of course, in every memory access. But that hopefully is happening at memory speeds so long as the virtual pages have already been populated in the DRAM. But there could be a system call that this process makes. When a system call is made, then the system call is to be passed up to the guest operating system because that is the one that can deal with that. That's one program discontinuity that can happen. So the hypervisor will then have to tell the guest operating system, here is a system call made by this process, deal with it. So that is one program discontinuity. Another thing that can happen is a page fault. If the addresses are translated already and the page table is populated, life is good. But if you have a page fault, once again, the hypervisor is incapable of handling it directly, so it has to pass it up to the guest operating system. Then a program can do something dumb. Divide by zero or run out of access memory, out of its range and so on. Those exceptions have to be also be caught by the hypervisor and passed up to the guest operating system. Lastly, there could be external interrupts, device interrupts, that can come in. A network packet comes in or an IO that was scheduled gets completed. So in that case, those external interrupt could even be for not just the process that is currently running on the guest operating system, but some of the VM that made an IO request, and it may be the external interrupt really belongs to this guy, is on behalf of this. All of this has to be managed by the hypervisor. That is, when such events happen, that is programmed discontinuity happens, the hypervisor is the first one that catches that and then it has to pass it up to the appropriate guest operating system. So these are all part of what the hypervisor has to do, whether it is a full virtualization, a paravirtualization. The events are going to be delivered as software interrupts to the appropriate guest operating system so that the guest operating system can deal with it. In the case of paravirtualization, there is something more that happens. That is, there are APIs provided by the hypervisor for the guest to do communication. The events are going to be delivered as software interrupts in whether it is full or paravirtualization. But in the case of paravirtualization, then the additional facility that's available as APIs from the hypervisor for the guest operating system to use. One thing that I should reemphasize is that in a fully virtualized operating system, Windows control come to the hypervisor whenever the guest operating system does something that is privileged. So for instance, you think about normal processes, they are running with user privileges. But whenever you are doing anything in the kernel, you are running it with kernel privileges. But if you think about a virtual machine on top of a hypervisor, it's just like a process, a user process. Therefore, everything that is doing is in users case, so far is the hypervisor is concerned. But the operating system doesn't know that. It thinks that, oh, I want to change, I'm going to change my mode to kernel mode. I cannot do that. It'll result in a trap. When it traps into the hypervisor, hypervisor will emulate whatever the guest operating system wants to do. So that is the way by which guest operating systems interact with the hypervisor in a fully virtualized world. But if it is a paravirtualized, then the guest operating system knows that it is not in complete control of the hardware. Therefore, if it wants to do something privileged it has the APIs through which it can access the hypervisor and ask it to do something on its behalf that it cannot do on its own.