Skip to content

Commit 3097b8d

Browse files
bibo-maoKexyBiscuit
authored andcommitted
FROMGIT: LoongArch: KVM: Use generic function loongarch_eiointc_read()
Generic read function loongarch_eiointc_read() is used for 1/2/4/8 bytes read access. It reads 8 bytes from emulated software state and shift right from address offset. Also the similar with kvm_complete_iocsr_read(), destination register of IOCSRRD.{B/H/W} is sign extension from byte/half word/word. Signed-off-by: Bibo Mao <[email protected]> Signed-off-by: Huacai Chen <[email protected]> (cherry picked from commit 3e394ea https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git loongarch-next) Signed-off-by: Kexy Biscuit <[email protected]>
1 parent f2ccc51 commit 3097b8d

File tree

1 file changed

+17
-136
lines changed

1 file changed

+17
-136
lines changed

arch/loongarch/kvm/intc/eiointc.c

Lines changed: 17 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -130,134 +130,8 @@ static inline void eiointc_enable_irq(struct kvm_vcpu *vcpu,
130130
}
131131
}
132132

133-
static int loongarch_eiointc_readb(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
134-
gpa_t addr, void *val)
135-
{
136-
int index, ret = 0;
137-
u8 data = 0;
138-
gpa_t offset;
139-
140-
offset = addr - EIOINTC_BASE;
141-
switch (offset) {
142-
case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
143-
index = offset - EIOINTC_NODETYPE_START;
144-
data = s->nodetype.reg_u8[index];
145-
break;
146-
case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
147-
index = offset - EIOINTC_IPMAP_START;
148-
data = s->ipmap.reg_u8[index];
149-
break;
150-
case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
151-
index = offset - EIOINTC_ENABLE_START;
152-
data = s->enable.reg_u8[index];
153-
break;
154-
case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
155-
index = offset - EIOINTC_BOUNCE_START;
156-
data = s->bounce.reg_u8[index];
157-
break;
158-
case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
159-
index = offset - EIOINTC_COREISR_START;
160-
data = s->coreisr.reg_u8[vcpu->vcpu_id][index];
161-
break;
162-
case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
163-
index = offset - EIOINTC_COREMAP_START;
164-
data = s->coremap.reg_u8[index];
165-
break;
166-
default:
167-
ret = -EINVAL;
168-
break;
169-
}
170-
*(u8 *)val = data;
171-
172-
return ret;
173-
}
174-
175-
static int loongarch_eiointc_readw(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
176-
gpa_t addr, void *val)
177-
{
178-
int index, ret = 0;
179-
u16 data = 0;
180-
gpa_t offset;
181-
182-
offset = addr - EIOINTC_BASE;
183-
switch (offset) {
184-
case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
185-
index = (offset - EIOINTC_NODETYPE_START) >> 1;
186-
data = s->nodetype.reg_u16[index];
187-
break;
188-
case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
189-
index = (offset - EIOINTC_IPMAP_START) >> 1;
190-
data = s->ipmap.reg_u16[index];
191-
break;
192-
case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
193-
index = (offset - EIOINTC_ENABLE_START) >> 1;
194-
data = s->enable.reg_u16[index];
195-
break;
196-
case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
197-
index = (offset - EIOINTC_BOUNCE_START) >> 1;
198-
data = s->bounce.reg_u16[index];
199-
break;
200-
case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
201-
index = (offset - EIOINTC_COREISR_START) >> 1;
202-
data = s->coreisr.reg_u16[vcpu->vcpu_id][index];
203-
break;
204-
case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
205-
index = (offset - EIOINTC_COREMAP_START) >> 1;
206-
data = s->coremap.reg_u16[index];
207-
break;
208-
default:
209-
ret = -EINVAL;
210-
break;
211-
}
212-
*(u16 *)val = data;
213-
214-
return ret;
215-
}
216-
217-
static int loongarch_eiointc_readl(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
218-
gpa_t addr, void *val)
219-
{
220-
int index, ret = 0;
221-
u32 data = 0;
222-
gpa_t offset;
223-
224-
offset = addr - EIOINTC_BASE;
225-
switch (offset) {
226-
case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
227-
index = (offset - EIOINTC_NODETYPE_START) >> 2;
228-
data = s->nodetype.reg_u32[index];
229-
break;
230-
case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
231-
index = (offset - EIOINTC_IPMAP_START) >> 2;
232-
data = s->ipmap.reg_u32[index];
233-
break;
234-
case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
235-
index = (offset - EIOINTC_ENABLE_START) >> 2;
236-
data = s->enable.reg_u32[index];
237-
break;
238-
case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
239-
index = (offset - EIOINTC_BOUNCE_START) >> 2;
240-
data = s->bounce.reg_u32[index];
241-
break;
242-
case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
243-
index = (offset - EIOINTC_COREISR_START) >> 2;
244-
data = s->coreisr.reg_u32[vcpu->vcpu_id][index];
245-
break;
246-
case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
247-
index = (offset - EIOINTC_COREMAP_START) >> 2;
248-
data = s->coremap.reg_u32[index];
249-
break;
250-
default:
251-
ret = -EINVAL;
252-
break;
253-
}
254-
*(u32 *)val = data;
255-
256-
return ret;
257-
}
258-
259-
static int loongarch_eiointc_readq(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
260-
gpa_t addr, void *val)
133+
static int loongarch_eiointc_read(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
134+
gpa_t addr, unsigned long *val)
261135
{
262136
int index, ret = 0;
263137
u64 data = 0;
@@ -293,7 +167,7 @@ static int loongarch_eiointc_readq(struct kvm_vcpu *vcpu, struct loongarch_eioin
293167
ret = -EINVAL;
294168
break;
295169
}
296-
*(u64 *)val = data;
170+
*val = data;
297171

298172
return ret;
299173
}
@@ -303,7 +177,7 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,
303177
gpa_t addr, int len, void *val)
304178
{
305179
int ret = -EINVAL;
306-
unsigned long flags;
180+
unsigned long flags, data, offset;
307181
struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
308182

309183
if (!eiointc) {
@@ -316,25 +190,32 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,
316190
return -EINVAL;
317191
}
318192

193+
offset = addr & 0x7;
194+
addr -= offset;
319195
vcpu->kvm->stat.eiointc_read_exits++;
320196
spin_lock_irqsave(&eiointc->lock, flags);
197+
ret = loongarch_eiointc_read(vcpu, eiointc, addr, &data);
198+
spin_unlock_irqrestore(&eiointc->lock, flags);
199+
if (ret)
200+
return ret;
201+
202+
data = data >> (offset * 8);
321203
switch (len) {
322204
case 1:
323-
ret = loongarch_eiointc_readb(vcpu, eiointc, addr, val);
205+
*(long *)val = (s8)data;
324206
break;
325207
case 2:
326-
ret = loongarch_eiointc_readw(vcpu, eiointc, addr, val);
208+
*(long *)val = (s16)data;
327209
break;
328210
case 4:
329-
ret = loongarch_eiointc_readl(vcpu, eiointc, addr, val);
211+
*(long *)val = (s32)data;
330212
break;
331213
default:
332-
ret = loongarch_eiointc_readq(vcpu, eiointc, addr, val);
214+
*(long *)val = (long)data;
333215
break;
334216
}
335-
spin_unlock_irqrestore(&eiointc->lock, flags);
336217

337-
return ret;
218+
return 0;
338219
}
339220

340221
static int loongarch_eiointc_writeb(struct kvm_vcpu *vcpu,

0 commit comments

Comments
 (0)