mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-01 09:42:10 +00:00
DM: add system reset (with RAM content kept)
This function add high level reset_vdev function. Which is implemented to call deinit/init pairing to emulate the virtual device reset operation. This patch also add the system reset which keep the UOS RAM content functionality to DM. Signed-off-by: Yin Fengwei <fengwei.yin@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
parent
b33012aee8
commit
9878543356
@ -509,6 +509,73 @@ vm_deinit_vdevs(struct vmctx *ctx)
|
||||
ioapic_deinit();
|
||||
}
|
||||
|
||||
static void
|
||||
vm_reset_vdevs(struct vmctx *ctx)
|
||||
{
|
||||
/*
|
||||
* The current virtual devices doesn't define virtual
|
||||
* device reset function. So we call vdev deinit/init
|
||||
* pairing to emulate the device reset operation.
|
||||
*
|
||||
* pci/ioapic deinit/init is needed because of dependency
|
||||
* of pci irq allocation/free.
|
||||
*
|
||||
* acpi build is necessary because irq for each vdev
|
||||
* could be assigned with different number after reset.
|
||||
*/
|
||||
atkbdc_deinit(ctx);
|
||||
vrtc_deinit(ctx);
|
||||
|
||||
deinit_pci(ctx);
|
||||
pci_irq_deinit(ctx);
|
||||
ioapic_deinit();
|
||||
|
||||
atkbdc_init(ctx);
|
||||
vrtc_init(ctx);
|
||||
|
||||
ioapic_init(ctx);
|
||||
pci_irq_init(ctx);
|
||||
init_pci(ctx);
|
||||
|
||||
if (acpi) {
|
||||
acpi_build(ctx, guest_ncpus);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vm_system_reset(struct vmctx *ctx)
|
||||
{
|
||||
int vcpu_id = 0;
|
||||
|
||||
/*
|
||||
* If we get system reset request, we don't want to exit the
|
||||
* vcpu_loop/vm_loop/mevent_loop. So we do:
|
||||
* 1. pause VM
|
||||
* 2. notify request done to reset ioreq state in vhm
|
||||
* 3. reset virtual devices
|
||||
* 4. load software for UOS
|
||||
* 5. hypercall reset vm
|
||||
* 6. reset suspend mode to VM_SUSPEND_NONE
|
||||
*/
|
||||
|
||||
vm_pause(ctx);
|
||||
for (vcpu_id = 0; vcpu_id < 4; vcpu_id++) {
|
||||
struct vhm_request *vhm_req;
|
||||
|
||||
vhm_req = &vhm_req_buf[vcpu_id];
|
||||
if (vhm_req->valid &&
|
||||
(vhm_req->processed == REQ_STATE_PROCESSING) &&
|
||||
(vhm_req->client == ctx->ioreq_client))
|
||||
vm_notify_request_done(ctx, vcpu_id);
|
||||
}
|
||||
|
||||
vm_reset_vdevs(ctx);
|
||||
|
||||
acrn_sw_load(ctx);
|
||||
vm_reset(ctx);
|
||||
vm_set_suspend_mode(VM_SUSPEND_NONE);
|
||||
}
|
||||
|
||||
static void
|
||||
vm_loop(struct vmctx *ctx)
|
||||
{
|
||||
@ -521,19 +588,23 @@ vm_loop(struct vmctx *ctx)
|
||||
assert(error == 0);
|
||||
|
||||
while (1) {
|
||||
int vcpu;
|
||||
int vcpu_id;
|
||||
struct vhm_request *vhm_req;
|
||||
|
||||
error = vm_attach_ioreq_client(ctx);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
for (vcpu = 0; vcpu < 4; vcpu++) {
|
||||
vhm_req = &vhm_req_buf[vcpu];
|
||||
for (vcpu_id = 0; vcpu_id < 4; vcpu_id++) {
|
||||
vhm_req = &vhm_req_buf[vcpu_id];
|
||||
if (vhm_req->valid
|
||||
&& (vhm_req->processed == REQ_STATE_PROCESSING)
|
||||
&& (vhm_req->client == ctx->ioreq_client))
|
||||
handle_vmexit(ctx, vhm_req, vcpu);
|
||||
handle_vmexit(ctx, vhm_req, vcpu_id);
|
||||
}
|
||||
|
||||
if (VM_SUSPEND_SYSTEM_RESET == vm_get_suspend_mode()) {
|
||||
vm_system_reset(ctx);
|
||||
}
|
||||
}
|
||||
quit_vm_loop = 0;
|
||||
|
@ -827,6 +827,7 @@ pci_emul_deinit(struct vmctx *ctx, struct pci_vdev_ops *ops, int bus, int slot,
|
||||
free(fi->fi_param);
|
||||
|
||||
if (fi->fi_devi) {
|
||||
pci_lintr_release(fi->fi_devi);
|
||||
pci_emul_free_bars(fi->fi_devi);
|
||||
free(fi->fi_devi);
|
||||
}
|
||||
@ -1621,6 +1622,25 @@ pci_lintr_request(struct pci_vdev *dev)
|
||||
pci_set_cfgdata8(dev, PCIR_INTPIN, bestpin + 1);
|
||||
}
|
||||
|
||||
void
|
||||
pci_lintr_release(struct pci_vdev *dev)
|
||||
{
|
||||
struct businfo *bi;
|
||||
struct slotinfo *si;
|
||||
int pin;
|
||||
|
||||
bi = pci_businfo[dev->bus];
|
||||
assert(bi != NULL);
|
||||
|
||||
si = &bi->slotinfo[dev->slot];
|
||||
|
||||
for (pin = 1; pin < 4; pin++) {
|
||||
si->si_intpins[pin].ii_count = 0;
|
||||
si->si_intpins[pin].ii_pirq_pin = 0;
|
||||
si->si_intpins[pin].ii_ioapic_irq = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pci_lintr_route(struct pci_vdev *dev)
|
||||
{
|
||||
|
@ -257,6 +257,7 @@ void pci_generate_msix(struct pci_vdev *pi, int msgnum);
|
||||
void pci_lintr_assert(struct pci_vdev *pi);
|
||||
void pci_lintr_deassert(struct pci_vdev *pi);
|
||||
void pci_lintr_request(struct pci_vdev *pi);
|
||||
void pci_lintr_release(struct pci_vdev *pi);
|
||||
int pci_msi_enabled(struct pci_vdev *pi);
|
||||
int pci_msix_enabled(struct pci_vdev *pi);
|
||||
int pci_msix_table_bar(struct pci_vdev *pi);
|
||||
|
Loading…
Reference in New Issue
Block a user