Commit b1728622 authored by Paul Durrant's avatar Paul Durrant Committed by Paolo Bonzini
Browse files

KVM: x86: PIT: Preserve state of speaker port data bit



Currently the state of the speaker port (0x61) data bit (bit 1) is not
saved in the exported state (kvm_pit_state2) and hence is lost when
re-constructing guest state.

This patch removes the 'speaker_data_port' field from kvm_kpit_state and
instead tracks the state using a new KVM_PIT_FLAGS_SPEAKER_DATA_ON flag
defined in the API.

Signed-off-by: default avatarPaul Durrant <pdurrant@amazon.com>
Message-Id: <20220531124421.1427-1-pdurrant@amazon.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 3dbec44d
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -3007,6 +3007,8 @@ Valid flags are::

  /* disable PIT in HPET legacy mode */
  #define KVM_PIT_FLAGS_HPET_LEGACY     0x00000001
  /* speaker port data bit enabled */
  #define KVM_PIT_FLAGS_SPEAKER_DATA_ON 0x00000002

This IOCTL replaces the obsolete KVM_GET_PIT.

+2 −1
Original line number Diff line number Diff line
@@ -307,6 +307,7 @@ struct kvm_pit_state {
};

#define KVM_PIT_FLAGS_HPET_LEGACY     0x00000001
#define KVM_PIT_FLAGS_SPEAKER_DATA_ON 0x00000002

struct kvm_pit_state2 {
	struct kvm_pit_channel_state channels[3];
+7 −3
Original line number Diff line number Diff line
@@ -591,7 +591,10 @@ static int speaker_ioport_write(struct kvm_vcpu *vcpu,
		return -EOPNOTSUPP;

	mutex_lock(&pit_state->lock);
	pit_state->speaker_data_on = (val >> 1) & 1;
	if (val & (1 << 1))
		pit_state->flags |= KVM_PIT_FLAGS_SPEAKER_DATA_ON;
	else
		pit_state->flags &= ~KVM_PIT_FLAGS_SPEAKER_DATA_ON;
	pit_set_gate(pit, 2, val & 1);
	mutex_unlock(&pit_state->lock);
	return 0;
@@ -612,8 +615,9 @@ static int speaker_ioport_read(struct kvm_vcpu *vcpu,
	refresh_clock = ((unsigned int)ktime_to_ns(ktime_get()) >> 14) & 1;

	mutex_lock(&pit_state->lock);
	ret = ((pit_state->speaker_data_on << 1) | pit_get_gate(pit, 2) |
		(pit_get_out(pit, 2) << 5) | (refresh_clock << 4));
	ret = (!!(pit_state->flags & KVM_PIT_FLAGS_SPEAKER_DATA_ON) << 1) |
		pit_get_gate(pit, 2) | (pit_get_out(pit, 2) << 5) |
		(refresh_clock << 4);
	if (len > sizeof(ret))
		len = sizeof(ret);
	memcpy(data, (char *)&ret, len);
+0 −1
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ struct kvm_kpit_state {
	bool is_periodic;
	s64 period; 				/* unit: ns */
	struct hrtimer timer;
	u32    speaker_data_on;

	struct mutex lock;
	atomic_t reinject;